Set criteria to be used in multiple SQL select queries - sql

Need to set criteria for running multiple queries, but only want to change once. For example, want to set year, period, document so that...
select * from tbl1 where tbl1.yr = year and ...
select * from tbl2 where tbl2.yr = year, and ...

Create a view:
CREATE VIEW yourview AS
SELECT * from tbl1
UNION ALL
SELECT * from tbl2
Then query it:
SELECT * FROM yourview
WHERE tbl1.yr = year AND ...
You may also want to know from which table each row comes. This can be achieved by adding an extra column to the view:
CREATE VIEW yourview AS
SELECT 'tbl1' AS src, * from tbl1
UNION ALL
SELECT 'tbl2' AS src, * from tbl2

If they're truly different queries, not related, you may have to resort to Dynamic SQL, e.g.
DECLARE #sCondition VARCHAR(50)
SET #sCondition = 'yr = 2012'
DECLARE #sQuery1 VARCHAR(1000)
SET #sQuery1 = 'select * from tbl1 where ' + #sCondition
-- DECLARE other queries in similar faction OR combine multiple queries into single variable
EXEC (#sQuery1)

With CTE; Note: you should have same number of columns and matching datatypes from both tables as you are doing a blind union of select *
;with cte (myYear)
as (
select #year as myYear
)
select * from table1 t1 where t1.year in (select myYear from cte)
union all
select * from table2 t2 where t2.year in (select myYear from cte)

Related

Save a Select/Except Union into a Temp Table

This code does precisely what I want: finds the difference between two tables, including nulls, and returns them. Thanks to: sql query to return differences between two tables
(
SELECT * FROM table1
EXCEPT
SELECT * FROM table2
)
UNION ALL
(
SELECT * FROM table2
EXCEPT
SELECT * FROM table1
)
I am having trouble getting this to turn into a temporary table (or even a regular table) to store its results for later use. Is there a way that I can tack on INSERT INTO here or generate a temp table from this beautiful query?
Select from your existing query as a sub-query INTO the temp table of your choice.
SELECT *
INTO #temp1
FROM (
(
SELECT * FROM #table1
EXCEPT
SELECT * FROM #table2
)
UNION ALL
(
SELECT * FROM #table2
EXCEPT
SELECT * FROM #table1
)
) X

Select Id+1 from subquery on same table

I need to select all id + 1 and id - 1 row information from MYTABLE with condition that id exist in existing query on same table .
I tried:
SELECT *
FROM MYTABLE
WHERE
id - 1 IN (SELECT * FROM MYTABLE WHERE EXISTINGQUERY) AND
id + 1 IN (SELECT * FROM MYTABLE WHERE EXISTINGQUERY)
But it doesn't work.
Any suggestions?
It seems to me you may write your query by using join like below
SELECT t1.* FROM MYTABLE t1
join (SELECT * FROM MYTABLE WHERE EXISTINGQUERY) t2
on (t1.id-1=t2.id or t1.id+1=t2.id)
The following SELECT statement may be used that includes the substitution variable :id
SELECT s.*
FROM MYTABLE s
WHERE id in (:id - 1,:id + 1)
AND EXISTS ( SELECT 1 FROM MYTABLE s WHERE id =:id AND EXISTINGQUERY);
where colon(:) notation may be replaced with # or & depending on the database.

Run UNION SELECT only if the fist select is not empty

I have the following stored procedure that returns rows for an endless scroll page. How can I check that newTable is empty? If it's empty then I don't want the UNION SELECT to be executed. Note that newTable is a very complex query so I don't want to execute more than once.
#offset INT,
#fetch INT
WITH newTable AS
(
SELECT * FROM table1
ORDER BY id OFFSET #offset ROWS FETCH NEXT #fetch ROWS ONLY
)
Don't run the following if newTable has reached the last row and is empty
SELECT * FROM newTable
UNION
SELECT * FROM table3
UNION
SELECT * FROM table4
ORDER BY id
You can probably do something like this:
DECLARE #offset INT,
#fetch INT;
WITH newTable AS
(
SELECT * FROM table1
ORDER BY id OFFSET #offset ROWS FETCH NEXT #fetch ROWS ONLY
)
SELECT *
FROM newTable
UNION
SELECT *
FROM table3
WHERE EXISTS (SELECT 1 FROM newTable)
UNION
SELECT *
FROM table4
WHERE EXISTS (SELECT 1 FROM newTable)
ORDER BY id
I'm pretty sure it will not execute the cte again. If it does, you can use a temporary table instead of a cte:
SELECT <ColumnsList> INTO #TemporaryTable
FROM....
and then your UNION query.
SELECT *
FROM #TemporaryTable
UNION
SELECT *
FROM table3
WHERE EXISTS (SELECT 1 FROM #TemporaryTable)
UNION
SELECT *
FROM table4
WHERE EXISTS (SELECT 1 FROM #TemporaryTable)
ORDER BY id

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt

SQL conditional union

Question: I have an SQL function which returns a list of files
now I should join an additional list to that list with an union, but only if the user is admin.
Is that possible? Something like:
CREATE FUNCTION tfu_CMS_Process(#bIsAdmin bit )
-- Add the parameters for the function here
RETURNS TABLE
AS
RETURN
(
SELECT * FROM TABLE1
if bIsAdmin
UNION ALL
SELECT * FROM TABLE2
end if
)
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2
WHERE #isAdmin = 1