Need to include the offset value as expr in LAG functions - amazon-redshift

I am migrating Redshift SQL to snowflake SQL.
Need suggestion on how to include the offset value as expression in snowflake's LAG(). regarding offset, Redshift supports expression in LAG() where as snowflake does not.
Eg:
expected sql in SF:
LAG(exp, **exp**) over (partition by col1 order by col2)

Expression for second input parameter of the LAG function is currently not supported. You will receive an error as given below, if you use the pass an expression.
Error: SQL compilation error: argument 2 to function LAG needs to be constant, found 'EXPR' -- Where EXPR is an expression
An improvement request for supporting expressions in the second argument of LAG() function is in the pipeline.
Workaround
You can rewrite the LAG function by adding the ROW_NUMBER() to the table and doing a Self-Join.

Related

PostgreSQL : ERROR: set-returning functions are not allowed in WHERE

I'm new to PostgreSQL, and I have the following code
select unnest(xpath(
'//ns2:ProcedureCategory/text()',messagebody::xml,
array[array['ns2','urn:wco:datamodel:WCO:DEC-DMS:2']]
))::text
from sw_customs_message scm
where unnest(xpath(
'//ns2:ProcedureCategory/text()',messagebody::xml,
array[array['ns2','urn:wco:datamodel:WCO:DEC-DMS:2']]
))::text = 'H7'
and I get the error message
SQL Error [0A000]: ERROR: set-returning functions are not allowed in WHERE
Position: 172
Set returning functions should be used in the FROM clause. Then you can also reference the result columns in the WHERE clause:
select u.val::text
from sw_customs_message scm
cross join unnest(xpath('//ns2:ProcedureCategory/text()',
scm.messagebody::xml,
array[array['ns2','urn:wco:datamodel:WCO:DEC-DMS:2']])) as u(val)
where u.val::text = 'H7'
Note that typically xmltable() is easier and more flexible to use if you want to turn an XML value into rows and columns. And if you are storing XML in a column, the column should be defined as xml not something else.

Azure data factory: pass where clause as a string to dynamic query with quotes

I have a Lookup that retrieves a few records from a MS SQL table containing schema, table name and a whole where clause. These values are passed to a copy data (within a ForEach) In the copy data i use a Dynamic query statement like:
#concat('select a.*, current_date as crt_tms from ',item().shm_nam,'.',item().tab_nam,
item().where_clause )
This construction works fine without the where_clause or with a where clause with an integer. But it goes wrong with strings like:
'a where a.CODSYSBRN ='XXX' ;'
it's about the quote (')
How can i pass it through?
I know that the where clause as a fixed string in the dynamic query works when i use double quotes (to escape the single quote):
'a where a.CODSYSBRN =''XXX'' ;'
Point is i need the where clause to be completely dynamic because it differ per table
whatever i try i get this kind of error:
Syntax error or access violation;257 sql syntax error: incorrect syntax near "where a"
ps i also tested this, but with the same result:
select a.*, current_date as crt_tms from #{item().shm_nam}.#{item().tab_nam} a #{item().where_clause}
As you have mentioned you are getting whole where clause from the lookup table, the query must have included the column values in where clause for string and integer types separately.
Example lookup table:
In your copy activity, you can use Concat() function as you were already doing it, to combine static values & parameters.
#concat('select * from ',item().schma_name,'.',item().table_name,' ',item().where_clause)
For debugging purposes, I have added the expression in set variable activity, to see the value of the expression.
Iteration1:
Iteration2:

Redshift: Cannot use aggregate function inside UDF's?

I have written the below code:
create or replace function max_price()
returns real
volatile
as
$$
select
max(main_amount)
from
table
$$
language sql;
I am receiving this error message:
ERROR: The select expression can not have aggregate or window function.
CONTEXT: Create SQL function "max_price" body
How can I work around this?
No, Redshift UDFs are scalar - each "row" of input values returns one output.
https://docs.aws.amazon.com/redshift/latest/dg/udf-creating-a-scalar-sql-udf.html
You may be able to use a Stored Procedure to obtain the result you are looking for.
https://docs.aws.amazon.com/redshift/latest/dg/stored-procedure-create.html
A scalar User-Defined Function in Amazon Redshift cannot issue a SELECT command that retrieves data from a table. It is intended as a means of calculating a number, rather than querying the database.
From Creating a scalar SQL UDF - Amazon Redshift:
The SELECT clause can't include any of the following types of clauses: FROM, INTO, WHERE, GROUP BY, ORDER BY, LIMIT
If you need to consult another table as part of the function, use a Stored procedure.

Using xmlserialize in db2 with a timestamp

I was looking for a way to combine multiple returned rows into a single row on a db2 database (I have an application that can query a database, but will only work if a single row is returned). I found this solution which worked pretty well and was a lot easier than using recursive SQL. However, I ran into a problem when I tried to include a column that was set as TIMESTAMP instead of VARCHAR.
So how can I make this work if a column is a TIMESTAMP type?
Error:
SQL0440N No authorized routine named "XMLTEXT" of type "FUNCTION" having
compatible arguments was found. SQLSTATE=42884
SQL0440N No authorized routine named "XMLTEXT" of type "FUNCTION " having compatible arguments was found.
".
Example:
select xmlserialize(
xmlagg(
xmlconcat(
xmltext(column_name),
xmltext(':'),
xmltext(content),
xmltext(','),
xmltext(DATETIMESTAMP),
xmltext(',')
)
) as varchar(10000)
)
from
yourtable
Instead of the suggested CAST you could wrap the TOCHAR` function around the timestamp value:
select xmlserialize(
xmlagg(
xmlconcat(
xmltext(column_name),
xmltext(':'),
xmltext(content),
xmltext(','),
xmltext(TO_CHAR(DATETIMESTAMP)),
xmltext(',')
)
) as varchar(10000)
)
from
yourtable
If you are on a recent version of DB2 and have LISTAGG available I would recommend to use that function. It is much faster than converting the SQL input to XML types and then converting it back. It requires some CPU cycles due to all the official rules involved.

how to use subquery with aggregate function in hive

SELECT peridle, CPU
FROM (SELECT MAX(peridle) FROM try2);
While executing this query in hive I am getting following error
Parse Error: line 1:47 cannot recognize input near 'select' 'MAX' '(' in expression specification
Please suggest a solution how to use aggregate functions in hive subquery
At least two things need to be fixed here:
You are not returning fields named peridle or CPU from the sub-query, yet you are trying to select them.
Hive requires you to alias all sub-queries, even if you don't reference the alias. You can quickly do this by changing the ); at the end to ) x; (or however you want to call it).