SQL multiple merge statements with same data source (WITH as) - sql

I would like to have multiple merge statements (one after another) in same query
but i can't use same date source. Example:
WITH DATA as(
SELECT * FROM tables_or_joins
)
MERGE table_name as Target
USING
(SELECT * FROM DATA JOIN another table
)
....
do something more; --and finish this statement here
-- start another merge here
MERGE table_name_2 as Target
USING(
SELECT * FROM DATA and join with another table
)
do something else
But output is Invalid object name 'DATA'. In second merge. Is any other way how to use data in both merge? Hope this is clear enough.

CTE is only good for one statement
Cannot even do two simple selects on DATA
You can have multiple CTE but still only one actual statement

You can use mutiple CTE statements
WITH DATA as( SELECT * FROM tables_or_joins
), DATA2 AS( (SELECT * FROM DATA JOIN another table )
SELECT * from DATA d join DATA2 d2 on d.id=d2.id
OR
Select * from DATA union Select * from DATA2

Related

2 Queries to do the same thing not working

I have 2 queries. The first is what I want to accomplish, however, it was taking much too long. Here's how the query looked like:
SELECT *
FROM old_table
WHERE id NOT IN (SELECT id FROM new_table)
UNION ALL
SELECT *
FROM new_table
Basically, I want everything that's in the old table, but not in the new table. I then union everything from the old and new. Again, this query was taking much too long on a bigger dataset. So, I optimized it like so:
WITH union_tbl AS (
(SELECT * FROM old_table)
UNION ALL
(SELECT * FROM new_table)
), row_tbl AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY ordering) AS row
FROM union_tbl
)
SELECT *
FROM row_tbl
WHERE row = 1
In the old_table and new_table (in a separate query) I add a new column to each called ordering. The new_table gets 1 for all its rows. For the old table, it gets 2 for all its rows. In the end, I select where the row number is 1. So that means if there's 2 rows one for new_table and one for old_table then it should get the new_table row instead.
This is how I'm envisioning it, however, I'm not getting the same results as my previous query. I'd expect it to have the same exact results with the same rows. What am I getting wrong? Is my query logic incorrect?
Can you try the below code?
SELECT a.*
FROM old_table a left join new_table b on a.id=b.id
WHERE b.id IS NULL
UNION ALL
SELECT *
FROM new_table
This is a very optimized way

Get rows in sequence from multiple table in SQL Server

I want to get all rows in sequence from 2 tables in SQL Server.
Output should be 1st row from 1st table, then 1st row from 2nd table,
2nd row from 1st table, 2nd row from 2nd table....etc
What #eshirvana suggested will not get you the desired. Instead, it'll be table1.row1, table2.row1, table2.row2, table1.row2
You can use UNION to join data from two tables when the column names and types match. I'm making an assumption on how to order the data based on your desired outcome.
SELECT RowID, Row, z
FROM table1
UNION
SELECT *
FROM table2
ORDER BY z, RowID
Here's the working code:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=068c0fd2056cc48718345e85b74b7bba
probably something like that :
select * from
(
select rowID,Row,z from table1
union all
select rowID,Row,z from table2
) alltables
order by z
You can try with below approach:
SELECT * FROM
(
SELECT RowId,Row,Z,1 AS TableOrder From Table1
UNION ALL
SELECT RowId,Row,z,2 AS TableOrder From Table2
)
ORDER BY Z,TableOrder

How to add union data in table?

Thanks in advance !!
I want to get below data in separate table with column how can we achieved this.
From my reading of your question, you would like the results of that SELECT statement put into a new table?
Firstly, I'm assuming your original SQL works as a SELECT statement - e.g., all those tables have the same structure. Note that you can simplify the unions, but I haven't done so here, to keep the key part of the answer (saving the data) as the main focus.
To save the data into another table, you can either create a table first and make that into an insert, or just use 'SELECT INTO' within the main SELECT.
If you are happy with the columns being automatically created, the 'SELECT INTO' version will create columns (e.g., you do not need to specify the columns in a CREATE TABLE statement). However, when you run the SELECT INTO, it does create the table. Therefore if you want to insert further values, you need to specify the column list (or have matching column lists).
SELECT INTO version
select *
INTO #Temp -- Added This row
from
( select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
) A
except
select * from
( select * from #ONEYRCON
union all
select * from #OTHERYRCON
) B
INSERT INTO version
CREATE TABLE #Temp (<your fields here to match the SELECT statement>)
INSERT INTO #Temp
select * from
( select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
) A
except
select * from
( select * from #ONEYRCON
union all
select * from #OTHERYRCON
) B
Set operators are evaluated from top to bottom so there only needs to be 1 subquery. Something like this
select ab.* into #Temp
from (select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
except
select * from #ONEYRCON
except
select * from #OTHERYRCON) ab;

SQL Server: Find Values that don't exist in a table

I have a list or set of values that I would like to know which ones do not currently exist in a table. I know I can find out which ones do exist with:
SELECT * FROM Table WHERE column1 IN (x,x,x,x,x)
The set is the values I am checking against. Is there a way to find out which values in that set do not exist in column1? Basically, I'm looking for the inverse of the sql statement above.
This is for a report, so all I need is the values that don't exist to be returned back.
I have and could do this with a left join and putting the values in another table, but the values I check are always different and was hoping to find a solution that didn't involve clearing a table and inserting data first. Trying to find a better solution for me if one exists.
You can also use EXCEPT as well as the OUTER JOIN e.g.
SELECT * FROM
(
SELECT -1 AS N
UNION
SELECT 2 AS N
) demo
EXCEPT
SELECT number
FROM spt_values
WITH q(x) AS
(
SELECT x1
UNION ALL
SELECT x2
UNION ALL
SELECT x3
)
SELECT x
FROM q
WHERE x NOT IN
(
SELECT column1
FROM [table]
)
Put the values you want to check for in a table A
LEFT OUTER JOIN the table A against your Table WHERE Table.column1 IS NULL
SELECT column1
FROM A
LEFT OUTER JOIN
Table
ON A.column1 = Table.column1
WHERE Table.column1 IS NULL
This will only show the rows that exist in A but not in Table.
As you want some of the values from the set in the result, and you can't take them from the table (as you want the ones that doesn't exist there), you have to put the set in some kind of table or result so that you can use that as source.
You can for example make a temporary result, that you can join against the table to filter out the ones that does exist in the table:
select set.x
from (
select 1 as x union all
select 2 union all
select 3 union all
select 4 union all
select 5
) as set
left join Table as t on t.column1 = set.x
where t.columnn1 is null
One way you can do it is:
SELECT * FROM Table WHERE column1 NOT IN(...);
Use the NOT operator:
SELECT * FROM Table WHERE column1 NOT IN (x,x,x,x,x)

In MySql how do I get row duplication for the case where I pass duplicate IDs in a list?

For this MySQL SELECT statement:
SELECT * FROM MY_TABLE WHERE ID IN(x,y,y,z):
I want 4 rows back - ie I WANT row duplication for the case where I pass duplicate IDs in the list.
Is this possible?
using the IN() construct, that's not possible.
the only way i can think to do this is with a UNION:
SELECT * FROM my_table WHERE id = x
UNION ALL
SELECT * FROM my_table WHERE id = y
UNION ALL
SELECT * FROM my_table WHERE id = y
UNION ALL
SELECT * FROM my_table WHERE id = z
but in all honesty, i would just do the IN() like you have it and make your app code duplicate the rows as needed.
Put your IDs, including dups in a temp table and join your results on that table. The join will take care of filtering, but will keep duplicates if it's in the temp table twice
SELECT * FROM MY_TABLE WHERE ID IN(x,y,z)
union all
SELECT * FROM MY_TABLE WHERE ID IN(y)
To me, IN specify a set of values to search in (and duplication is a concept that conflict with the set one).
You should use other mean to reach your scope.