I have two table which I would like to union. I need to keep only the duplicates from one of the two tables. I tried to find it, but could not find it anywhere. Hope somebody can help.
For example:
Table_1:
ID
Product
Amount
1
A
10
2
B
10
3
C
10
Table_2:
ID
Product
Amount
3
C
9
4
A
100
5
B
100
Desired result:
ID
Product
Amount
1
A
10
2
B
10
3
C
9
4
A
100
5
B
100
So always use the duplicates from table_2. In this example ID 3 is duplicate, so use the duplicate of table_2 with amount 9.
How to realize this with T-SQL? I used the code below:
Select * from Table_1 where Table_1.id != Table_2.id
Union All
Select * from Table_2
But then I receive the error:
'The multi-part identifier "Table_2.ID" could not be bound.'
Use not exists:
Select t1.*
from Table_1 t1
where not exists (select 1 from table_2 t2 where t2.id = t1.id)
Union All
Select t2.*
from Table_2 t2;
Try this:
SELECT T1.*
FROM #Table1 T1
WHERE T1.ID NOT IN (SELECT ID FROM #Table2)
UNION
SELECT T2.*
FROM #Table2 T2
I assume what you want is an EXISTS:
SELECT T1.ID,
T1.Product,
T1.Amount
FROM dbo.Table1 T1
WHERE NOT EXISTS (SELECT 1
FROM dbo.Table2 T2
WHERE T1.ID = T2.ID)
UNION ALL
SELECT T2.ID,
T2.Product,
T2.Amount
FROM dbo.Table2 T2;
A FULL OUTER JOIN, however, might also work if ID is unique in both tables:
SELECT ISNULL(T2.ID,T1.ID) AS ID,
ISNULL(T2.Product,T1.Product) AS Product,
ISNULL(T2.Amount,T1.Amount) AS Amount
FROM dbo.Table1 T1
FULL OUTER JOIN dbo.Table2 T2 ON T1.ID = T2.ID;
Union will give you the result. Union will always return unique values always. If you use union all you will get all with duplicates. Your answer would be to use union all.
SELECT
B.ID
,B.Product
,B.Amount
FROM
(
SELECT
A.ID
,A.Product
,A.Amount
,ROW_NUMBER() over (Partition BY ID, Product order by Amount ASC) AS [row_num]
FROM
(
SELECT
tb_1.*
FROM tb_1
UNION ALL
SELECT
tb_2.*
FROM tb_2
) AS A
) AS B
WHERE B.[row_num] = 1
Related
I have two almost identical tables except one column.
table1
id name amount
1 nm1 15
2 nm2 20
table1
id name amt
1 nm1 15
2 nm2 20
Now I have other joins but I want to avoid have it all twice but rather have more simple sql code.
At the moment I have to do all twice:
select t1.id, t1.name, t1.amount from table1 t1
left outer join.......
union all
select t2.id, t2.name, t2.amt as amount from table2 t2
left outer join.......
I would like to have something like:
select t1.id, t1.name, t1.amount from (select * from table1 union all select * from table2) t1
but this one column "amount" prevents it.
Is there a way how to handle it?
Do the union all before the join:
select t.id, t.name, t.amount, . . .
from (select t1.* from table1 t1 union all
select t2.* from table2 t2
) t left outer join.......
I have this scenario question which needs to be solved using joins only. can't use except,intersect or union.
sample code:
--demo setup
create table t1 (id int)
insert into t1 values (1),(2),(3)
create table t2 (id int)
insert into t2 values (4),(5),(6)
--join
select t1.id,t2.id
from t1 full outer join
t2 on t1.id=t2.id
--after join i am getting
id id
----------- -----------
1 NULL
2 NULL
3 NULL
NULL 4
NULL 5
NULL 6
--But i need is
id
-----------
1
2
3
4
5
6
Can someone help me with this ? i know this can be easily done using union but this challenge needs to be solved using joins only.
any help is appreciated ....
--solved the challenge after adding case to the code.
select case when t1.id is null then t2.id else t1.id end as id
from t1 full outer join
t2 on t1.id=t2.id
you can use this code:
SELECT case when t1.id IS NULL THEN t2.id ELSE t1.id END AS id
FROM t1 FULL OUTER JOIN t2
ON t1.id=t2.id
As you said the Use From Union
select * from t1
union
select * from t2
Although UNION ALL is the better option, you can use this following script-
SELECT
CASE WHEN C.ID1 IS NULL THEN C.ID2 ELSE C.ID1 END V
FROM
(
SELECT * FROM
(
SELECT 'T1' TabName1,id ID1 FROM #t1
)A
FULL JOIN (
SELECT 'T2' TabName2,id ID2 FROM #t2
)B
ON A.TabName1 = B.TabName2
)C
ORDER BY 1
I have a table:
My select:
select regexp_split_to_table(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
order by s
Or also I can get a string '22173345566179111134546175622323811' with this:
select string_agg(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
I need to get a table with number|count data, I mean for any number to get a count of repetitions in the select, for example:
1 | 9
2 | 5
3 | 5
and so on..
PostgreSQL DBMS
Does this do what you want?
select id, count(*)
from (select t1."Id" from table1 t1
union all
select t2."Id" from table2 t2
) t3
group by id
order by id;
If I understand you right, you want a list of all digits, that exist in a set of IDs from two tables and the count of each digit, how often it appears in all these IDs. If so, you just need to GROUP BY a digit and use count().
SELECT s.d,
count(*) count
FROM (SELECT t1."Id"
FROM table1 t1
UNION ALL
SELECT t2."Id"
FROM table2 t2) t3
CROSS JOIN LATERAL regexp_split_to_table(t3."Id"::character varying, '') s(d)
GROUP BY s.d
ORDER BY s.d;
easiest way
select regexp_split_to_table(t3."Id"::character varying,'') s, count(*) count
from (select t1."Id" from table1 t1 union all select t2."Id"from table2 t2) t3
group by s
Suppose, we have query like this:
SELECT
1
FROM DUAL WHERE
(SELECT id FROM table_1 t1 WHERE /*conditions*/)
IN
(SELECT id FROM table_1 t2 WHERE /*conditions*/)
I want to check if first query
SELECT id FROM table_1 t1 WHERE /*conditions*/
returns the same ids like the second query.
Of course this query (IN statement) doesn't work.
Try:
SELECT id FROM table_1 t1 WHERE /*conditions1*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions2*/)
union
SELECT id FROM table_1 t1 WHERE /*conditions2*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions1*/)
If both queries gives you the same id's the result should be empty.
This will return nothing if sets are equal:
SELECT id FROM table_1 t1 WHERE /*conditions*/
EXCEPT
SELECT id FROM table_1 t2 WHERE /*conditions*/
You can use EXCEPT.
EXCEPT returns distinct rows from the left input query that aren’t
output by the right input query.
EXCEPT sample in your case:
SELECT id
FROM table_1 AS t1
WHERE /*conditions*/
EXCEPT
SELECT id
FROM table_1 AS t2
WHERE /*conditions*/
Just as an alternative method that used Full Join in tsql:
SELECT CASE WHEN isnull(Count(*), 0) > 1 then 1 else 0 end as result
FROM (SELECT t1.id as t1_id, t2.id as t2_id FROM
(SELECT id FROM table1 WHERE /*conditions*/) As t1
Full Outer Join
(SELECT id FROM table2 WHERE /*conditions*/) As t2
On t1.id = t2.id
) As ft
WHERE ft.t1_id is null or ft.t2_id is null
And I think this can marked as a stupid way.
I've two related tables:
Table1
Id
-----
1
2
3
Table2
Id Feature
--------------
1 Car
1 Moto
1 Camper
2 Moto
2 Scooter
3 Apple
I want to select Ids which have, for example, both 'Car' AND 'Moto'.
So in the example i want to get only Id = 1.
Use the INTERSECT operator:
select id from table2 where feature = 'Car'
intersect
select id from table2 where feature = 'Moto'
This:
WITH features AS
(
SELECT feature
FROM (
VALUES
('Car'),
('Moto')
) q (feature)
)
SELECT *
FROM table1 t1
WHERE NOT EXISTS
(
SELECT feature
FROM features
EXCEPT
SELECT feature
FROM table2 t2
WHERE t2.id = t1.id
)
or this:
SELECT *
FROM table t1
WHERE (
SELECT COUNT(*)
FROM table2 t2
WHERE t2.id = t1.id
AND t2.feature IN ('Car', 'Moto')
) = 2
Which query is more efficient depends on how many records you have in both tables and how many matches there are.
This select does two LEFT OUTER JOINs to table2 (one based on 'Car' and the other based on 'Moto') and makes sure that each JOIN returned a result. The DISTINCT ensures that you get each ID only once.
SELECT DISTINCT t1.id
FROM table2 t2
LEFT OUTER JOIN table2 t2_2 ON t2.id = t2_2.id AND t2_2.feature = 'Moto'
WHERE t2.feature = 'Car'
AND t2_2.id IS NOT NULL
Edit: Removed join to table1 since it really isn't needed.