Using SQL Server, I have two tables that I want to merge. Table2 has a tbID column that has NULL values. I would like for NULL values to be automatically updated, beginning with the next value of the tbID column, from Table1 when the tables are merged.
I am entering something like this..
SELECT
A.tbID,
A.etID,
A.cNumber,
A.cName
FROM
Table1 AS A
UNION ALL
SELECT
B.tbID,
B.etID,
B.cNumber,
B.cName
FROM
Table2 AS B
My results has a NULL value (instead of an automatically inserted number), in the records from Table2.
If by "merge" you want all the records to end up in table1 - just leave the id column out of the insert:
INSERT INTO table1 (etID, cNumber, cName)
SELECT etID, cNumber, cName
FROM table2
If you just want to select and see incremented ids for the data coming from table2, here is one way:
SELECT A.tbID,
A.etID,
A.cNumber,
A.cName
FROM Table1 AS A
UNION ALL
SELECT (SELECT MAX(tbID) FROM Table1) +
ROW_NUMBER() OVER (ORDER BY B.etID),
B.etID,
B.cNumber,
B.cName
FROM Table2 AS B
If you just want a result set, you can use:
SELECT A.tbID, A.etID, A.cNumber, A.cName
FROM Table1 A
UNION ALL
SELECT (a.maxID + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) as tbID,
B.etID, B.cNumber, B.cName
FROM Table2 B CROSS JOIN
(SELECT MAX(A.tbID) as maxID FROM Table1 as A) a;
If you are inserting these rows into a new table, then the id can be assigned automatically -- but the values might differ for A.
Related
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
I have a table where in customer number column contains duplicate values and I would like to select all rows where there are duplicate entries for customer number, but only select those rows where WO Type column only contains these specific values ('IMU','Electric') so in the table image attached to this question: I should only get rows for ID 1 and 2.
I do not want those duplicates counted where the pair of duplicate rows also contain GAS, but only want those duplicate rows which exclusively contain only IMU and Electric values in WO Type Column
Your help is much appreciated.
You can use group by and having:
select customerNumber
from t
where woType in ('EMU', 'Electric')
group by customerNumber
having count(*) = 2;
Note: This assumes no duplicates. To handle this, you can use:
having min(woType) <> max(woType)
or:
having count(distinct woType) = 2 -- number of elements in IN list
SELECT *
FROM tbl t1
WHERE EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'IMU'
) AND EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'Electric'
) AND NOT EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype NOT IN ('IMU', 'Electric')
)
Here's a fiddle.
Try this:
select * from Table1 Main
Inner JOIN (
select Customer_Number
From Table1
group by Customer_Number
Having COunt(Customer_Number)>1) SUB ON Main.Customer_Number=SUB.Customer_Number
WHERE Main.Wo_Type IN ('IMU','Electric')
This Query will return the duplicate set or rows in the table.
I've two tables say table 1 and table 2,
table 1 has column names as sno and useddate
table 2 has column names as sno and recentlyuseddate
I want to compare these two columns useddate and recentlyusedate and get the most recently used date.
These tables may have many entries but I need only ONE ENTRY (mostrecent) date after comparing these tables.
SELECT MAX(useddate) AS mostrecent
FROM
(SELECT useddate FROM Table1
UNION ALL
SELECT recentlyuseddate AS useddate FROM Table2) TheUnion
You can use unions for this
SELECT MAX(col)
FROM (SELECT col FROM TABLE_1
UNION ALL
SELECT col FROM TABLE_2)
If you have an index on the two dates in the two tables, I would go for:
select top 1 sno, useddate, which
from ((select top 1 sno, useddate, 'table1' as which from table1 order by useddate desc) union all
(select top 1 sno, recentlyuseddate , 'table2' as which from table2 order by recentlyuseddate desc)
)
order by useddate desc;
This version also tells you which table the date came from.
i would like to run a sql statement that will delete ONLY the second value for example
delete from table1 where condition1
i want this statement to delete ONLY the second value
how can i accomplish this?
i would like to clarify. i have a field called field1 which is an autonumber and and it is a primary key and it increments. i would like to delete the record containing the greater number
You could also employ the ROW_NUMBER() function of SQL server to number each row, and use this number to isolate just the second item for deletion, according to your own custom ordering in the inner query ( over (ORDER BY <myKey> asc) ). This provides a great deal of flexibility.
DELETE a FROM table1
FROM table1 a
JOIN (
select ROW_NUMBER() over (ORDER BY <myKey> asc) as AutoNumber, <myKey> from table1
) b on a.<myKey> = b.<myKey>
WHERE condition1
AND b.AutoNumber = 2
Do you want to delete only the last duplicate, or all but the first?
For all but the first: (Edited to use CTE per #Martin's suggestion.)
with target as (select * from table1 where condition1)
delete from target goner
where exists (select * from target keeper
where keeper.field1 < goner.field1)
In other words, if there is another matching record with a lower field1, delete this record.
EDIT:
To delete only the last:
with target as (select * from table1 where condition1)
delete from target goner
where exists (select * from target keeper
where keeper.field1 < goner.field1)
and not exists (select * from target missing
where missing.field1 > goner.field1)
In other words, if there is another matching record with a lower field1, AND there is no matching record with a higher field1, then we have the highest duplicate, so nuke it.
It's been a while (so my syntax my not quite be right), and this may not be the best solution, but the "academic" answer would be something like:
delete from table1 where condition1
and field1 = (select max(field1) from table1 where condition1)
Try this:
DELETE MyTable
FROM MyTable
LEFT OUTER JOIN (
SELECT MIN(id) as id, Col1, Col2, Col3
FROM MyTable
GROUP BY Col1, Col2, Col3
) as KeepRows ON
MyTable.id= KeepRows.id
WHERE
KeepRows.RowId IS NULL
UPDATE
While this might not be as "pretty" as #Jeffrey's it works. From what I can tell, #Jeffrey's does not. See sql below (Delete replaced with SELECT * for demonstration):
WITH TEMP as
(
SELECT 1 as id,'A' as a,'Z' as b
UNION
SELECT 2,'A','Z'
UNION
SELECT 3,'B','Z'
UNION
SELECT 4,'B','Z'
)
SELECT *
FROM TEMP
LEFT OUTER JOIN (
SELECT MIN(id) as id, a, b
FROM TEMP
GROUP BY a, b
) as KeepRows ON
temp.id= KeepRows.id
WHERE
KeepRows.id IS NULL
How can I make a sql query like the following:
(SELECT `name` FROM table1)
UNION
(SELECT `name` FROM table2)
return each other. Ie. name1 from table1, name1 from table2, name2 from table1, name2 from table2 and so on?
Edit:
Table1
name
Hello
world
Table2
name
guten
tag
The output wanted:
Hello
guten
world
tag
and this should also be possible if adding more unions, so that it takes from the first union, then the second, third, forth and so on.
You could number rows with variables, using 2,4,6,... for the first part of the union and 3,5,7,... for the second:
select #rownum1 := #rownum1+2 as rownum, name
from (select #rownum1:=0) r, table1
union all
select #rownum2 := #rownum2+2 as rownum, name
from (select #rownum2:=1) r, table2
order by rownum;
The select in the from clause (select #rownum2:=1) r is only used to initialize the variable.
Does this work?
set #i = 0;
set #j = 1;
select #i:=#i+2 as rownumber,
name
from table1
union
select #j:=#j+2 as rownumber,
name
from table2
order by rownumber
I read your question as wanting to alternate one row from table1, one from table2 and so on in your results set.
Edit in light of your edit:
Change the "2"s to the number of tables, and add as many variables as you have tables, with consecutive start values in the "set" statements. This will extend in the way you want.
In a similar vein to David M, you can do:
(SELECT #rownum:=#rownum+1 as rownum,`name` FROM table1, (SELECT #rownum:=0) r)
UNION
(SELECT #rownum:=#rownum+1 as rownum,`name` FROM table2, (SELECT #rownum:=0) r)
order by rownum