Select 行,其中两列之间存在一对一匹配 table SQL
Select rows where there is a one-to-one match between two columns in same table SQL
我有一个 SQL table 有两种类型的 ID 列。例如
ID_1 Name Date ID_2
487 Joe 09/06/2004 332
731 Mike 06/01/2004 116
487 Joe 09/06/2004 354
777 Rich 01/01/2002 455
745 Mike 06/01/2004 116
有时 ID_1 有多行,ID_2 的值不同。反之亦然,有时 ID_2 有多行,ID_1.
的值不同
我想保留 ID_1 和 ID_2 之间存在一对一匹配的所有行。理想情况下,我还会用剩余的行制作另一个 table,这样我以后可以轻松查看它们。所以上面的例子,只有一行(第 4 行)在 ID_1 和 ID_2 之间有一对一的匹配:
ID_1 Name Date ID_2
777 Rich 01/01/2002 455
所有其他行都有其中一个 ID 重复的行。所以它基本上删除了任何一个 ID 列完全重复的行。
我尝试过使用 DISTINCT,但它保留了其中一个重复行,而我希望将它们全部删除。
p.s。这不是关于加入 tables 的问题 - 该示例是单个 table.
您可以使用窗口化 COUNT
:
CREATE TABLE only_one_to_one
AS
SELECT ID_1, Name, Date, ID_2
FROM (SELECT *,COUNT(*) OVER(PARTITION BY ID_1) AS ID1_cnt,
COUNT(*) OVER(PARTITION BY ID_2) AS ID2_cnt
FROM tab) sub
WHERE ID1_cnt = 1 AND ID2_cnt = 1;
只有一对一
SELECT *
FROM Table A
WHERE (SELECT Count(1)
FROM Table B
WHERE A.ID_1 = B.ID_1) = 1
AND (SELECT Count(1)
FROM Table B
WHERE A.ID_2 = B.ID_2) = 1
不止一个
SELECT *
FROM Table A
WHERE (SELECT Count(1)
FROM Table B
WHERE A.ID_1 = B.ID_1) > 1
OR (SELECT Count(1)
FROM Table B
WHERE A.ID_2 = B.ID_2) > 1
create table #one_to_one
(id_1 int, name varchar(20), dt date, id_2 int)
insert into #one_to_one values( 487, 'Joe', '09/06/2004' , 332)
insert into #one_to_one values( 731, 'Mike', '06/01/2004' , 116)
insert into #one_to_one values(487, 'Joe', '09/06/2004' , 354)
insert into #one_to_one values( 777, 'Rich', '01/01/2002', 455)
insert into #one_to_one values( 745, 'Mike', '06/01/2004', 116)
select id_1, name, dt, id_2
from (select *, count(*) over(partition by id_1) as id_1_count,
count(*) over(partition by id_2) as id_2_count
from #one_to_one) res
where id_1_count = 1 and id_2_count = 1;
此代码将帮助您
create table #temp (ID_1 int,name varchar(255),[Date] date,ID_2 int)
insert into #temp values (487 , 'Joe','09/06/2004', 332)
insert into #temp values (731 , 'Mike' , '06/01/2004' , 116 )
insert into #temp values (487 , ' Joe' , '09/06/2004' , 354 )
insert into #temp values (777 , 'Rich' , '01/01/2002' , 455 )
insert into #temp values (745 , 'Mike' , '06/01/2004' , 116 )
Select * from (
Select ROW_NUMBER() OVER(ORDER BY id_1 DESC) AS Row#,ID_1,Name,Date,ID_2
FROM #temp
) as T
Where Row# = 4
Drop table #temp
我有一个 SQL table 有两种类型的 ID 列。例如
ID_1 Name Date ID_2
487 Joe 09/06/2004 332
731 Mike 06/01/2004 116
487 Joe 09/06/2004 354
777 Rich 01/01/2002 455
745 Mike 06/01/2004 116
有时 ID_1 有多行,ID_2 的值不同。反之亦然,有时 ID_2 有多行,ID_1.
的值不同我想保留 ID_1 和 ID_2 之间存在一对一匹配的所有行。理想情况下,我还会用剩余的行制作另一个 table,这样我以后可以轻松查看它们。所以上面的例子,只有一行(第 4 行)在 ID_1 和 ID_2 之间有一对一的匹配:
ID_1 Name Date ID_2
777 Rich 01/01/2002 455
所有其他行都有其中一个 ID 重复的行。所以它基本上删除了任何一个 ID 列完全重复的行。
我尝试过使用 DISTINCT,但它保留了其中一个重复行,而我希望将它们全部删除。
p.s。这不是关于加入 tables 的问题 - 该示例是单个 table.
您可以使用窗口化 COUNT
:
CREATE TABLE only_one_to_one
AS
SELECT ID_1, Name, Date, ID_2
FROM (SELECT *,COUNT(*) OVER(PARTITION BY ID_1) AS ID1_cnt,
COUNT(*) OVER(PARTITION BY ID_2) AS ID2_cnt
FROM tab) sub
WHERE ID1_cnt = 1 AND ID2_cnt = 1;
只有一对一
SELECT *
FROM Table A
WHERE (SELECT Count(1)
FROM Table B
WHERE A.ID_1 = B.ID_1) = 1
AND (SELECT Count(1)
FROM Table B
WHERE A.ID_2 = B.ID_2) = 1
不止一个
SELECT *
FROM Table A
WHERE (SELECT Count(1)
FROM Table B
WHERE A.ID_1 = B.ID_1) > 1
OR (SELECT Count(1)
FROM Table B
WHERE A.ID_2 = B.ID_2) > 1
create table #one_to_one
(id_1 int, name varchar(20), dt date, id_2 int)
insert into #one_to_one values( 487, 'Joe', '09/06/2004' , 332)
insert into #one_to_one values( 731, 'Mike', '06/01/2004' , 116)
insert into #one_to_one values(487, 'Joe', '09/06/2004' , 354)
insert into #one_to_one values( 777, 'Rich', '01/01/2002', 455)
insert into #one_to_one values( 745, 'Mike', '06/01/2004', 116)
select id_1, name, dt, id_2
from (select *, count(*) over(partition by id_1) as id_1_count,
count(*) over(partition by id_2) as id_2_count
from #one_to_one) res
where id_1_count = 1 and id_2_count = 1;
此代码将帮助您
create table #temp (ID_1 int,name varchar(255),[Date] date,ID_2 int)
insert into #temp values (487 , 'Joe','09/06/2004', 332)
insert into #temp values (731 , 'Mike' , '06/01/2004' , 116 )
insert into #temp values (487 , ' Joe' , '09/06/2004' , 354 )
insert into #temp values (777 , 'Rich' , '01/01/2002' , 455 )
insert into #temp values (745 , 'Mike' , '06/01/2004' , 116 )
Select * from (
Select ROW_NUMBER() OVER(ORDER BY id_1 DESC) AS Row#,ID_1,Name,Date,ID_2
FROM #temp
) as T
Where Row# = 4
Drop table #temp