Snowflake Numeric value '' is not recognized - snowflake-cloud-data-platform

Please help me with error 'Numeric value '' is not recognized'.
In Snowflake i am having a variable day_minus which holds a number, using this i want to return date value of current_date minus the value given in the variable.
If there is Null or empty passed in the variable i want to get current date minus 1.
For this i have written a code like below. But it throws me an error Numeric value '' is not recognized
But it throws an
set day_minus=7;
SELECT DATEADD(DAY, concat('-',nvl(nullif(try_to_number($day_minus) ,''),1)),current_date() );
Can you please correct me where i am doing mistake

you can use case statement
SELECT DATEADD(DAY, concat('-',nvl(case when $Units ='' then 1 else $Units end ,1)),current_date() );

If you use concat then the result is always going to be a string. If you want to set the "default" value to -1 then just put -1 in your code.
The try_to_* functions take a string as their input so you'd need to make your variable a string to make this work e.g.
set day_minus='7';
You don't need nullif at all. So the final version would be something like:
set day_minus='7';
DATEADD(DAY, nvl(try_to_number($day_minus),-1),current_date() );

Related

How to replace regular expression?

I do replacing
SET #data = REPLACE(#data, 'Riched20 10.0.19041}', '');
It is ok, but recently I have detected that it can be
Riched20 10.0.18362 etc
How can I replace in common case like 'Riched20 ...}'?
Can I use a regular-expression?
It should be implementation in T-SQL
If the problem is as simple as this question makes it out to be then you could, instead, find the position of the string 'Riched20' in your value, and then the position of the first } that appears after it and use STUFF to remove the text in that range.
This assumes that the value will always have a } after 'Riched20', and that if there is a } then 'Riched20' also appears. If this isn't the case you will get the value NULL.
DECLARE #data varchar(100) = 'sdjkafhbgtajl asdgasdf, Riched20 10.0.19041} dlkghbsdfl';
SET #data = STUFF(#data, CHARINDEX('Riched20',#data),CHARINDEX('}',#data,CHARINDEX('Riched20',#data)) - CHARINDEX('Riched20',#data) +1,'');
SELECT #data;
If you need "true" pattern replacement, then you are out of luck; T-SQL does not support this as the comments mention.

Snowflake with regular expression

Trying to run the below SQL in Snowflake:
SELECT fm_id ,
CASE
WHEN regexp_instr(ASSD,'...',1) > 0
THEN regexp_SUBSTR(ASSD,1,regexp_instr(ASSD,'...',1)-1)
ELSE ASSD
END ASSD
from
(SELECT a.fm_id,
listagg(a.STUID, '; ') within GROUP (
ORDER BY a.Fm_id, a.STUID ) ASSD
from stu_d a
where fm_id = 1222
group by a.fm_id
)
Getting error:
"Invalid parameter value: 0. Reason: Position must be positive"
seems it is failing at -1 or 0 value in above case statement.
What am I doing wrong?
Without seeing your table it's hard to say, but regexp_instr() will return 1 when the pattern is at the beginning of the string. Then, you subtract 1, and 0 is an invalid position argument to regexp_substr(). doc
Perhaps you intended to use SUBSTR not REGEX_SUBSTR()

invalid input syntax for type timestamp

While running the below code i get an error saying invalid input syntax for type timestamp from admission_datetime.
UPDATE ccsm.stg_demographics_baseline
SET xx_los_days =
(CASE WHEN admission_datetime IS NULL OR
date_trunc('day',admission_datetime) = ''
THEN NULL
WHEN discharge_datetime IS NULL OR
date_trunc('day',discharge_datetime) = ''
THEN date_diff('day', admission_datetime, CURRENT_DATE)
ELSE
date_diff('day', admission_datetime, discharge_datetime)
END);
enter code here
See date_trunc documentation:
The return value is of type timestamp or interval with all fields that are less significant than the selected one set to zero (or one, for day and month).
So you can not compare it with an empty string:
date_trunc('day', admission_datetime) = ''
The invalid input syntax for type timestamp error message concerns the empty string (''), not the admission_datetime column.
Furthermore, there is no date_diff function in PostgreSQL. Just subtract one timestamp from another and you will get an interval result:
SELECT timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'
You'll get
interval '1 day 15:00:00'
If you need the difference in days, try this:
SELECT DATE_PART('day', timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00')
The result is 1.
See here for examples of DATEDIFF-like expressions in PostgreSQL.

Report Builder 3.0 optional parameter

is there a chance to use optional parameters in report builder?
for example: i have a query with 3 parameters
#Pa1 date
#Pa2 date
#Pa3 varchar(3)
if i run View report without inform one of then i got the message:
Select a value for the parameter #Pa3 (for example)
is it possible?
I tried to use a empty field but i got no data
select a.legajo,c.nombres,e.Descripcion,CONVERT (char(10), a.fecha, 103) as Fecha,a.hora as ENTRADA,
b.hora as SALIDA,
DATEDIFF(HOUR,a.hora,b.hora) as Horas_trabajadas,
c.hor_x_jor Horas_jornada,
DATEDIFF(HOUR,a.hora,b.hora) -hor_x_jor as Diferencia
from fichadas_in a, fichadas_out b, empleados c,sucursales d,Clasificacion e
where a.Legajo=b.Legajo
and a.fecha=b.fecha
and a.fecha between #fecha1 and #fecha2
and d.codigo=#sucursal
and a.legajo=c.legajo
and c.CCO=d.Codigo
and e.Codigo=c.Clasif
Order by a.fecha,legajo
Allow Null Values or Blank values for your parameter.
As already mentioned you need to select ALLOW BLANK VALUES, and ALLOW NULL VALUE.. But you also have to ensure your SQL knows what to do with those VALUES in your WHERE clause.
AND (
((#Pa3 IS NOT NULL AND #Pa3 != '') AND d.codigo = #Pa3)
OR
((#Pa3 IS NULL OR #Pa3 = '') AND d.codigo LIKE '%'))
)
There are other ways to do this, but make sure you account for those values/lack of values.
For the date range, I would recommend declaring another variable that calculates what the date value is before running the SELECT statement.. Create a variable that is calculates what the value is if the value is blank, null, or entered.
The variable may go in to #Pa1 but then calculates into #fecha1, then in the WHERE clause you us #fecha1.

Filter SQL datatable according to different parameters, without a WHERE clause

I'm building an application that needs to allow the user to filter a data table according to different filters. So, the user will have three different filter posibilites but he might use only one, or two or the three of them at the same tame.
So, let's say I have the following columns on the table:
ID (int) PK
Sede (int)
Programa (int)
Estado (int)
All of those columns will store numbers, integers. The "ID" column is the primary key, "Sede" stores 1 or 2, "Programa" is any number between 1 and 15, and "Estado" will store numbers between 1 and 13.
The user may filter the data stored in the table using any of those filters (Sede, Programa or Estado). But the might, as well, use two filters, or the three of them at the same time.
The idea is that this application works like the data filters on Excel. I created a simulated table on excel to show what I want to achieve:
This first image shows the whole table, without applying any filter.
Here, the user selected a filter for "Sede" and "Programa" but leaved the "Estado" filter empty. So the query returns the values that are equal to the filter, but leaves the "Estado" filter open, and brings all the records, filering only by "Sede" (1) and "Programa" (6).
In this image, the user only selected the "Estado" filter (5), so it brings all the records that match this criteria, it doesn't matter if "Sede" or "Programa" are empty.
If I use a SELECT clasuse with a WHERE on it, it will work, but only if the three filters have a value:
DECLARE #sede int
DECLARE #programa int
DECLARE #estado int
SET #sede = '1'
SET #programa = '5'
SET #estado = '12'
SELECT * FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = #sede)
AND
([dbo].[Inscripciones].[Programa] = #programa)
AND
([dbo].[Inscripciones].[Estado] = #estado)
I also tryed changing the "AND" for a "OR", but I can't get the desired result.
Any help will be highly appreciated!! Thanks!
common problem: try using coalesce on the variable and for the 2nd value use the field name you're comparing to. Be careful though; Ensure it's NULL and not empty string being passed!
What this does is take the first non-null value of the variable passed in or the value you're comparing to.. Thus if the value passed in is null the comparison will always return true.
WHERE
[dbo].[Inscripciones].[Sede] = coalesce(#sede, [dbo].[Inscripciones].[Sede])
AND
[dbo].[Inscripciones].[Programa] = coalesce(#programa, [dbo].[Inscripciones].[Programa])
AND
[dbo].[Inscripciones].[Estado] = coalesce(#estado, [dbo].[Inscripciones].[Estado])
If sede is null and programa and estado are populated the compare would look like...
?=? (or 1=1)
?=programa variable passed in
?=Estado variable passed in
Boa Sorte!
Thank you all for your anwers. After reading the article posted in the comments by #SeanLange I was finally able to achieve what was needed. Using a CASE clause in the WHERE statement solves the deal. Here's the code:
SELECT
*
FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = (CASE WHEN #sede = '' THEN [dbo].[Inscripciones].[Sede] ELSE #sede END))
AND
([dbo].[Inscripciones].[Programa] = (CASE WHEN #programa = '' THEN [dbo].[Inscripciones].[Programa] ELSE #programa END))
AND
([dbo].[Inscripciones].[Estado] = (CASE WHEN #estado = '' THEN [dbo].[Inscripciones].[Estado] ELSE #estado END))
AND
([dbo].[Inscripciones].[TipoIngreso] = (CASE WHEN #tipoingreso = '' THEN [dbo].[Inscripciones].[TipoIngreso] ELSE #tipoingreso END))
Thanks again!!

Resources