Formatting values dynamically based on length - snowflake-cloud-data-platform

I have input data as below
I want to add leading 0s to the PRODUCT_NUMBER to make it total 10 digit , desired output should be like below
Is there a way to do this in snowflake?

Yes, it's possible to use TO_CHAR function to format the numbers:
select TO_CHAR( num, '0000000000' ) AS res from values
(145678),
(3456),
(12) tmp(num);
+------------+
| RES |
+------------+
| 0000145678 |
| 0000003456 |
| 0000000012 |
+------------+
https://docs.snowflake.com/en/sql-reference/functions/to_char.html

Another alternative is lpad which dynamically pads specified character until the string reaches the length N. If the length of string was > N to begin with, it will return first N characters and truncate the rest.
select lpad(col, 10, '0')
Documentation

Related

Removing trailing zeroes after decimal Snowflake

I have been trying to remove trailing zeroes from a numeric column after the decimal. For example:
0.978219150000 -> 0.97821915
0.650502591918 -> 0.650502591918
0.975479450000 -> 0.97547945
The data type is NUMBER(38,12). Is there any way to remove the trailing zeroes as I mentioned above?
You can try to cast to float:
create or replace table test (a NUMBER(38,12));
insert into test values (0.97821915), (0.650502591918), (0.975479450000);
select a from test;
+----------------+
| A |
|----------------|
| 0.978219150000 |
| 0.650502591918 |
| 0.975479450000 |
+----------------+
select a::float from test;
+--------------+
| A::FLOAT |
|--------------|
| 0.97821915 |
| 0.6505025919 |
| 0.97547945 |
+--------------+
However, depending what you want to achieve, using floating number might not be a good idea due to potential rounding issues.
UPDATE:
I tried the regexp version, not sure if I missed any test case or not:
create or replace table test (a NUMBER(38,12));
insert into test values
(0.97),
(0.650502591918),
(0.975479450000),
(10000),
(1450000),
(12.2000),
(14.0200);
select regexp_replace(
a::varchar,
'^([0-9]+)$|' ||
'^([0-9]+)\.0*$|' ||
'^([0-9]+\.[0-9]{1,}[1-9])0*$|' ||
'^([0-9]+\.[1-9])0*$', '\\1\\2\\3\\4'
) as a from test;
+----------------+
| A |
|----------------|
| 0.97 |
| 0.650502591918 |
| 0.97547945 |
| 10000 |
| 1450000 |
| 12.2 |
| 14.02 |
+----------------+
Where:
^([0-9]+)$ -> will cover the integer like 10000
^([0-9]+)\.0*$ -> will cover integer like 10.000000
^([0-9]+\.[0-9]{1,}[1-9])0*$ -> will cover 14.0200000
^([0-9]+\.[1-9])0*$. -> will cover 12.20000 or 0.97540000
If this is just a formatting/display issue, you can use the to_varchar() function with a fixed decimal format string:
select 123.45::number(38,12); -- 123.450000000000
select to_varchar(123.45::number(38,12), '99G999G999G999G999G999G999G999G999D999999999999'); -- 123.45
Since the format string is a bit long, it may make sense to put it in a UDF to make it more compact in SQL:
create or replace function DISPLAY_38_12(N number(38,12))
returns varchar
language sql
as
$$
to_varchar(123.45::number(38,12), '99G999G999G999G999G999G999G999G999D999999999999')
$$;
select DISPLAY_38_12(123.45::number(38,12));

TDengine database escaping characters

I was trying to add some special characters in TDengine's binary string but I'm uncertain about the rule how TDengine processing escape characters, for example inserting the '\t'(tab) and '\v'(vertical tab) behave differently in terms of output. Can anyone help explaining the escaping rule or what common escaping characters supported in popular DBs?
insert into tb values (now ,2 ,'\t');
insert into tb values (now ,2 ,'\\t');
insert into tb values (now ,2 ,'\\\t');
-----------------------------------------
select * from tb;
ts | id | chars |
=========================================================================
2021-08-19 19:48:05.494 | 1 | |
2021-08-19 19:48:19.449 | 2 | t |
2021-08-19 19:48:26.870 | 2 | |
Query OK, 4 row(s) in set (0.005654s)
insert into tb values (now ,2 ,'\v');
insert into tb values (now ,2 ,'\\v');
insert into tb values (now ,2 ,'\\\v');
-----------------------------------------
taos> select * from tb;
ts | id | chars |
=========================================================================
2021-08-19 19:52:36.287 | 2 | v |
2021-08-19 19:52:44.791 | 2 | v |
2021-08-19 19:52:48.934 | 2 | v |
In TDengine, there is a Special Character Escape Sequences.
For details: https://www.taosdata.com/docs/cn/v2.0/taos-sql
Escape character usage rules:
The escape characters that in a identifier (database name, table name, column name):
1. Normal identifier: The wrong identifier is prompted directly, because the identifier must be numbers, letters and underscores, and cannot start with a number.
2. Backquote`` identifier: Keep it as it is.
The escape characters that in a data:
1. The escape character defined above will be escaped (% and _ see the description below). If there is no matching escape character, the escape character will be ignored.
2. The \% and \_ sequences are used to search for literal instances of % and _ in pattern-matching contexts where they would otherwise be interpreted as wildcard characters.If you use \% or \_ outside of pattern-matching contexts, they evaluate to the strings \% and \_, not to % and _.

Need Google Sheets Array Formula To Return Just The Cell(s) > 1

I'm looking to list duplicate values from another tab on my sheet. I have the formula below and it's almost complete. I need help with the formula only returning duplicate cells and how many occurrences.
Right now it will list out every cell in the column followed the number of occurrences in the next column to the right. I want it to show me just the cells where the number is greater than 1.
Any help would be appreciated!
=IFNA(ArrayFormula(
{
unique(filter(Completed!E2:E,Completed!E2:E<>"")),
COUNTIF(filter(Completed!E2:E,Completed!E2:E<>""),unique(filter(Completed!E2:E,Completed!E2:E<>"")))
}),"")
Here's an example of what it shows currently:
| 12345 | 1 |
| 01234 | 1 |
| 56789 | 2 |
Here's what I'd like it to return instead:
| 56789 | 2 |
try:
=IFNA(QUERY(INDEX(
{UNIQUE(FILTER(Completed!E2:E, Completed!E2:E<>"")),
COUNTIF(FILTER(Completed!E2:E, Completed!E2:E<>""),
UNIQUE(FILTER(Completed!E2:E, Completed!E2:E<>"")))}),
"where Col2>1"))
or just:
=QUERY(QUERY(Completed!E2:E,
"select E,count(E) group by E"), "where Col2 > 1", 0)

Use an array formula to calculate datedif on criteria

Lets say I have a record of logged flights in a range, example below
[A] | [B] | [C][D][...] | [G]
1 Date | Mode | More Data.... | Days Since
2 1 May | Day | .... | Formula here
3 4 May | Night | .... | Formula here
4 6 May | Day | .... | Formula here
5 8 May | Night | .... | Formula here
I can use a formula to get the datedif between each row in column G, similar to
=DATEDIF(A2,A3,"d")
and copy it all the way down the column, but I'm guessing I need an array formula to go back and find the first row above the current row that matches in column B and get the datedif or days between those two dates. I'm assuming an array formula, but what would the best way to go about that be? I need the result to be the days between row 5 and 3 (night) and 4 and 2 (day) and then copied down about 300 rows...
I was looking at another array formula for sorting rows and eliminated blanks, but not sure how to adapt it to this scenario.
To get the difference in days you only have to subtract one date from the other.
LOOKUP function can be used to find the previous match, so try this formula in G2 copied down
=IFERROR(A2-LOOKUP(2,1/(B$1:B1=B2),A$1:A1),"")
format result cell as number with no decimal places

MS Access Query - count number of values in a comma separated column

I want to count the number of occurrences of values in a comma separated field in a MS Access Table. Any suggestions please :
For example
Table
ID | Value
1 | 1,2,3
2 | 1,5,8,9,5
3 | 1,5,8,3
Desired Output
ID | # of value
1 | 3
2 | 5
3 | 4
As #June7 correctly said, you need a custom function which can be called in your query.
Place this in a Standard Module:
Public Function CountValues(ByVal commaValues As Variant) As Long
If Not IsNull(commaValues) Then CountValues = UBound(Split(commaValues, ",")) + 1
End Function
You can now call it in your query:
SELECT ID, CountValues(FieldName) AS [# of value]
FROM YourTableName;
Output:
ID | [# of value]
1 | 3
2 | 5
3 | 4
4 | 0
NULL values default to zero.
you can also do this with built in functions, without the overhead of calling a custom function:
select value, Len([value])-Len(Replace([value],",","")) as [# of value]

Resources