How to Pass in Parameters of CTE in View or Procedure - sql

I have multiple CTEs and I want to pass in two parameters: one being the date and the other being the CTE table name.
This is in oracle db.
The CTEs are like this
WITH big_table1 AS
(
select * from mini_table1
),
big_table2 AS
(
select * from mini_table2
)
The date will be calculated by the select statements in the CTE. I want to do something like select * from &&big_table where &&date = date or any other way (in a view/store procedure) that would help me pass in dynamically the CTE name and a specific date (like '10-23-2021').
I have tried this and it works: select * from &&big_table where &&date = date. But it needs to be in a store proc or view or something that is established I guess. Not really sure why but those are the requirements I need to satisfy.
Appreciate any help.

Related

Accessing an 'f0_' field

I have created a common table expression with a list of dates within a range using the following SQL code in BigQuery:
WITH calendar AS(
SELECT * FROM UNNEST(GENERATE_DATE_ARRAY('2020-01-01', CURRENT_DATE(), INTERVAL 1 DAY))
)
If I were to run that as a query without the 'WITH' clause, the query would return a single column called 'f0_' (you should be able to reproduce this result yourself).
Now, the problem I'm having is that when I attempt to access that column in a separate SELECT statement, the name 'f0_' is not recognised. ("Unrecognized name: f0_")
WITH calendar AS(
SELECT * FROM UNNEST(GENERATE_DATE_ARRAY('2020-01-01', CURRENT_DATE(), INTERVAL 1 DAY))
)
SELECT f0_
FROM calendar
Of course, that query in itself is pointless, as I could just run the first SELECT statement without the WITH clause and not need the second SELECT statement. I get that. The end result I'm after is a little more complex though, and the logic above should be sufficient to explain the problem I'm having. Basically, if the SELECT statement inside that common table expression returns a column called 'f0_' when I run it as a standalone query, why does my second SELECT statement return an error when it's referencing a common table expression that seems like it should return a column called 'f0_'.
I assume it's something along the lines of 'f0_' not being a real name - it's just something that gets assigned in the absence of any specified name, or maybe the naming works differently when you run it as a common table expression rather than a simple SELECT statement. Is there a way I can alias the unnested date array within my common table expression so that I can access it in the second part of my query? Or some other solution?
Just use an alias:
WITH calendar AS(
SELECT *
FROM UNNEST(GENERATE_DATE_ARRAY('2020-01-01', CURRENT_DATE(), INTERVAL 1 DAY)) as dt
)
SELECT dt
FROM calendar

Ordering by expression from Select

I need to make a query like this:
SELECT (t.a-t.b) AS 'difference'
FROM t
ORDER BY abs(t.a-t.b)
Is there a way not to duplicate code (t.a-t.b) ? Thank you for your answers
You can wrap the SQL statement and then perform the ORDER BY if you're performing an absolute value on it.
SELECT * FROM
(
SELECT (t.a-t.b) AS "difference"
FROM t
) a
ORDER BY abs(a.difference)
UPDATE: I used SQL Server the 1st time, but depending on your environment (Oracle, MySQL), you may need to include double quotes around the column alias, so:
SELECT * FROM
(
SELECT (t.a-t.b) AS "difference"
FROM t
) a
ORDER BY abs("a.difference")

Referencing same random value in a SELECT statement

I have 2 functions I am calling form a SSRS dataset query:
fRndNumber() returns a random value
fCheckSum() returns a calculated value based in the value returned from fRndNumber.
The following statement does not work because the second call of fRndNumber() is generating a different value than the first call. I require the fCheckSum function to use the same value generated by fRndNumber()
Select
fRndNumber() as SerialNumber,
fCheckSum(fRndNumber) as CheckSum
Ideally I would like the statement to read as follows, but of course I cannot reference the 'SerialNumber' in this manner.
Select
fRndNumber() as SerialNumber,
fCheckSum(SerialNumber) as CheckSum
Any suggestions?
Doug P
Depending on your version of SQL, you could use a CTE...
;WITH RandomCte AS
(
SELECT fRndNumber() AS SerialNumber,
* -- add your other columns here...
FROM someTableName -- replace with your table name
)
SELECT fCheckSum(SerialNumber) AS [CheckSum],
*
FROM RandomCte;
See here for more info on CTEs
Using a CTE is considered best practices these days. But if your server doesn't support them, you could also use an inline view:
SELECT
A.SerialNumber,
fCheckSum(A.SerialNumber) AS CheckSum
FROM (
SELECT fRndNumber() as SerialNumber
) as A;

SQL select from data in query where this data is not already in the database?

I want to check my database for records that I already have recorded before making a web service call.
Here is what I imagine the query to look like, I just can't seem to figure out the syntax.
SELECT *
FROM (1,2,3,4) as temp_table
WHERE temp_table.id
LEFT JOIN table ON id IS NULL
Is there a way to do this? What is a query like this called?
I want to pass in a list of id's to mysql and i want it to spit out the id's that are not already in the database?
Use:
SELECT x.id
FROM (SELECT #param_1 AS id
FROM DUAL
UNION ALL
SELECT #param_2
FROM DUAL
UNION ALL
SELECT #param_3
FROM DUAL
UNION ALL
SELECT #param_4
FROM DUAL) x
LEFT JOIN TABLE t ON t.id = x.id
WHERE x.id IS NULL
If you need to support a varying number of parameters, you can either use:
a temporary table to populate & join to
MySQL's Prepared Statements to dynamically construct the UNION ALL statement
To confirm I've understood correctly, you want to pass in a list of numbers and see which of those numbers isn't present in the existing table? In effect:
SELECT Item
FROM IDList I
LEFT JOIN TABLE T ON I.Item=T.ID
WHERE T.ID IS NULL
You look like you're OK with building this query on the fly, in which case you can do this with a numbers / tally table by changing the above into
SELECT Number
FROM (SELECT Number FROM Numbers WHERE Number IN (1,2,3,4)) I
LEFT JOIN TABLE T ON I.Number=T.ID
WHERE T.ID IS NULL
This is relatively prone to SQL Injection attacks though because of the way the query is being built. It'd be better if you could pass in '1,2,3,4' as a string and split it into sections to generate your numbers list to join against in a safer way - for an example of how to do that, see http://www.sqlteam.com/article/parsing-csv-values-into-multiple-rows
All of this presumes you've got a numbers / tally table in your database, but they're sufficiently useful in general that I'd strongly recommend you do.
SELECT * FROM table where id NOT IN (1,2,3,4)
I would probably just do:
SELECT id
FROM table
WHERE id IN (1,2,3,4);
And then process the list of results, removing any returned by the query from your list of "records to submit".
How about a nested query? This may work. If not, it may get you in the right direction.
SELECT * FROM table WHERE id NOT IN (
SELECT id FROM table WHERE 1
);

how can i add select query result into dataset later again select query run

i want to add select query result into dataset, so i can write new query to run on it to get net dataset but how?
Original query:
MyDATASET=(
select x, y,z from table1
union all
select k,l,m from table2
)
i wan to this select * from this.MyDATASET
Well, you could perhaps create a CTE, UDF or view? But it really isn't clear what you are trying to do...
CREATE VIEW MyView AS
select x, y,z from table1
union all
select k,l,m from table2
GO
SELECT * FROM MyView
SELECT * FROM MyView WHERE x = 0
etc
Assuming you want to cache data for re-use later...
Use a temp table or table variable if it's contained within one bit of code.
If you want to refer the same data in several processes or calls, then use a temp table. Use a local one for many calls but don't close the connecion, use a global one for many different processes/connections.
If it's just one big select where you want to re-use the same data, then use a CTE.
A view also works but the data may change between executions.