Snowflake udf logic - snowflake-cloud-data-platform

I have created some SQL UDF there return a table which work as it should.
Now I would like to add some logic so based on the input parameters of the udf, different queries should be used e.g:
if input_parameter = A then
SELECT * FROM table where blabla
if input_parameter = B then
SELECT * FROM table_someting where blabla
Is that possible (with sql or python in snowflake)? and then still able to call it like:
select * from table(myfunction("A"))

The UDTF logic could be written as mutually exclusive UNION ALL:
SELECT *
FROM tab1
WHERE blabla
AND INPUT_PARAMETER = 'A'
UNION ALL
SELECT *
FROM table_something
WHERE blabla
AND INPUT_PARAMETER = 'B'

Related

Better way to do this (set and call parameters)

I'm trying to have this result :
Those two lines are from the same query, but I must duplicate the result (first called "CLI" and second "CPA").
Currently I do it with an UNION :
WITH Temp AS (SELECT Code, Name, ...)
SELECT 'CLI' as RecordType, Code, Name, CONCAT('CLI', Name) as TechnicalName, ... FROM Temp
UNION ALL
SELECT 'CPA' as RecordType, Code, Name, CONCAT('CPA', Name) as TechnicalName, ... FROM Temp
Is there any other solution most efficient ?
Because there are about 30 columns, so the code is very big now.
I thought of something like this :
DECLARE #P_RecordType as char(3);
WITH Temp AS (SELECT Code, Name, ...)
SET #P_RecordType = 'CLI'
SELECT * FROM Temp
UNION ALL
SET #P_RecordType = 'CPA'
SELECT * FROM Temp
But it doesn't work.
PS: I'm querying on SSMS from "Microsoft SQL Azure (RTM) - 12.0.2000.8".
You can try to use CROSS APPLY with value to make it simple.
Query 1:
SELECT v.c as RecordType, Code, Name, CONCAT(v.c, Name) as TechnicalName
FROM Temp
CROSS APPLY(VALUES ('CPA'),('CLI')) v (c)
Results:

Get records which are not ended with specific word

I have field with values for instance:
323.12.444.1
55.1231
4543.432.431
6.1
456.3234.54353.1124.1
321.3.425
2.3.1
5345.43.1
432.5646.2
So for records ended by .1 has to be gathered. What should be the query?
This should be faster than LIKE
SELECT * FROM table WHERE RIGHT(fieldname,2)='.1'
The LIKE with a % at the beginning is something one should avoid if possible...
select * from table where fieldname like '%.1'
I would suggest to use this:
SELECT *
FROM YourTable
WHERE REVERSE(SUBSTRING(REVERSE(col1),1,CHARINDEX('.',REVERSE(col1))-1)) = '1'
You can find any string you need without changing parameters inside query:
;WITH YourTable AS (
SELECT *
FROM (VALUES
('323.12.444.1'),
('55.1231'),
('4543.432.431'),
('6.1'),
('456.3234.54353.1124.1'),
('321.3.425'),
('2.3.1'),
('5345.43.1'),
('432.5646.2')
) as t(col1)
)
SELECT *
FROM YourTable
WHERE REVERSE(SUBSTRING(REVERSE(col1),1,CHARINDEX('.',REVERSE(col1))-1)) = '431'
Output:
4543.432.431

Join array of numbers with table in function

I need some support with array type, because it is a new thing for me, so
I have a function:
create or replace type num_array as table of number;
create or replace function functionname(arr_in num_array)
return num_array is
tab num_array;
begin
select id_acc bulk collect into tab from (
SELECT a.id_acc
FROM (SELECT id_acc, parent_acc FROM account) a
connect by nocycle prior a.id_acc=a.parent_acc
start with id_acc in
(
select distinct ID_ACC
from (SELECT id_acc, parent_acc FROM account
) a
where parent_acc = id_acc
connect by nocycle prior a.parent_acc = a.id_acc or parent_acc is null
start with id_acc in (select parent_acc from table_name t,account a where t.id=a.id_acc)));
return tab;
end;
As an input I want to have an array of numbers (id). I want to connect that number (from input) with account table. It is in line:
start with id_acc in (select parent_acc from table_name t,account a where t.id=a.id_acc)));
I would like to join somehow table account with numbers from input,
I was trying to use table(tab()),account a but I got an error.
As output I would like to have result of select query so (return tab).
I'm not sure I understood what you want to achieve. Just to help you with the syntax, look at this:
start with id_acc in (select * from table(arr_in));
Below i have provided a small snippet which basically illustrates your issue with joining Nested Table type with Table.
CREATE OR REPLACE FUNCTION test_ntt_join
RETURN NUMBER_NTT
AS
lv_tab_num NUMBER_NTT;
lv_tab2 NUMBER_NTT;
BEGIN
SELECT LEVEL BULK COLLECT INTO lv_tab_num FROM DUAL CONNECT BY LEVEL < 10;
SELECT COLUMN_VALUE
BULK COLLECT INTO
lv_tab2
FROM TABLE(lv_tab_num) t,
EMP
WHERE emp.empno= t.column_value;
RETURN lv_tab2;
END;
------------------------------------------OUTPUT------------------------------------
select * from table(test_ntt_join);
COLUMN_VALUE
1
1
3
------------------------------------------OUTPUT------------------------------------

Using select * and count(*) together in a query in SQL Server 2012

I have a table with 12 columns.
I need a query for computing COUNT(*) and selecting all the columns.
I mean I want to have these two queries just in one query:
select *
from mytable
where OneOfTheColumns = something;
select COUNT(*)
from mytable
where OneOfTheColumns = something;
Conditions and tables are the same.
Can I do this?
Thanks a million.
You can use a window function for that
select *,
count(*) over () as total_count
from mytable
where OneOfTheFields = something;

SQL Server Select Where value LIKE(temporary table value)

I have a function in SQL server 2008 that takes a string: 'A,B,C,D' and splits it and creates a table of the values.
Values
------
A
B
C
D
I now want to search a table (Users) Where a column value is LIKE one of the rows (surname) in the above table.
This is what I would like to do:
SELECT * FROM Users WHERE vLastName LIKE 'A%'
SELECT * FROM Users WHERE vLastName LIKE 'B%'
SELECT * FROM Users WHERE vLastName LIKE 'C%'
SELECT * FROM Users WHERE vLastName LIKE 'D%'
If the above is not possible, how else would you do it? Some kind of loop?
I'm using SQL Server 2008
SELECT * FROM Users,NewTable WHERE vLastName LIKE Values + '%'
SELECT * from Users u
JOIN StringSplitterResult r on r.Values = SUBSTRING( u.vLastName, 1,1)

Resources