SQL - 如何从一个表中获取重复记录并连接到另一张表
Posted
技术标签:
【中文标题】SQL - 如何从一个表中获取重复记录并连接到另一张表【英文标题】:SQL - How to get duplicate records from one table with join on another table 【发布时间】:2018-04-13 02:19:06 【问题描述】:我想从 Table1 中获取记录,其中它有多个相同访问号的记录,但同时该访问号也应该存在于 Table2 中。
例子
表1
Access Number
- 1000
- 1000
- 1000
- 2000
- 3000
- 4000
- 5000
- 5000
表2
AccessNumber Value
- 1000 -Value1000
- 1000 -Value9999
- 2000 -Value2000
- 3000 -Value3000
查询的结果应该是1000 - Value1000
这是我目前得到的,请提出建议
SELECT a.AccessNumber, b.Valuefrom Table1 a
JOIN Table2 b on b.AccessNumber = a.AccessNumber
Group by a.AccessNumber, b.VAlue
HAVING COUNT(1) > 1;
我面临的问题是查询返回 Table2 中的重复项。
1000 - Value1000
1000 - Value9999
【问题讨论】:
您使用的是什么版本的 SQL?Table2
中的 CaseReference
字段是什么?
@TimBiegeleisen SQL Server 12
@DanieleCappuccio 已编辑
我没有得到任何重复:sqlfiddle.com/#!18/4eade/1
【参考方案1】:
没有太多关于为什么1000 - Value1000
应该是结果而不是1000 - Value9999
的信息,我们可以从顶部获取第一条记录:
select top 1 * from (
-- your original query
SELECT a.AccessNumber, b.Value from Table1 a
JOIN Table2 b on b.AccessNumber = a.AccessNumber
Group by a.AccessNumber, b.Value
HAVING COUNT(1) > 1
-- your original query
) as x;
如果我们只是在寻找具有重复记录的 AccessNumber
,您可以从选定的列中删除 b.Value
,并在 Group By
子句中将其删除。
SELECT a.AccessNumber from Table1 a
JOIN Table2 b on b.AccessNumber = a.AccessNumber
Group by a.AccessNumber
HAVING COUNT(1) > 1;
http://www.sqlfiddle.com/#!18/3f114/3
【讨论】:
【参考方案2】:我们或许可以使用 SQL Server 的 EXCEPT
运算符来完成这项工作。但是一个明智的方法是按访问号聚合两个表,然后将第一个连接到第二个,只保留出现在两个表中的访问号 和 出现的数量更多在第一个比第二个。
SELECT t1.AccessNumber
FROM
(
SELECT AccessNumber, COUNT(*) AS cnt_1
FROM Table1
GROUP BY AccessNumber
) t1
LEFT JOIN
(
SELECT AccessNumber, COUNT(*) AS cnt_2
FROM Table2
GROUP BY AccessNumber
) t2
ON t1.AccessNumber = t2.AccessNumber
WHERE
t1.cnt_1 - COALESCE(t2.cnt_2, 0) > 0 AND t2.cnt_2 IS NOT NULL;
Demo
【讨论】:
我实际上是在一个更大的表上运行它,但这会返回比预期更多的记录 @Maverick 不,it works。查看演示。 如何获取Value列? 这个问题没有多大意义。您要为每个访问号码选择哪个值?你现在需要从聚合的角度来讨论,因为上面的报告是两个表的聚合。【参考方案3】:--希望这个查询对你有帮助
; with cte_accessnumber(Accessnumber, [value])
as
(
select
t1.Accessnumber, count(*)NoOfRecords
from table1 t1
where exists (
select top 1 1 from table2 t2 where t2.Accessnumber = t1.Accessnumber)
group by t1.Accessnumber
having count(*)>1
)
select t1.Accessnumber, t2.[value]
from cte_accessnumber t1
inner join table2 t2 on t2.Accessnumber = t1.Accessnumber and t2.[value] like '%' + convert(varchar(20),t1.Accessnumber) +'%'
【讨论】:
【参考方案4】:您可以尝试对 AccessNumber 行 > 1 的条件使用嵌套并交叉应用仅显示 1 条记录的条件
DECLARE @tblA AS TABLE
(
AccessNumber INT
)
DECLARE @tblB AS TABLE
(
AccessNumber INT,
colB NVARCHAR(50)
)
INSERT INTO @tblA SELECT 1000
INSERT INTO @tblA SELECT 1000
INSERT INTO @tblA SELECT 1000
INSERT INTO @tblA SELECT 1000
INSERT INTO @tblA SELECT 2000
INSERT INTO @tblA SELECT 3000
INSERT INTO @tblA SELECT 4000
INSERT INTO @tblB SELECT 1000,'hello'
INSERT INTO @tblB SELECT 1000,'hello2'
INSERT INTO @tblB SELECT 2000,'world'
-- Query --
SELECT tblB.* FROM (
SELECT AccessNumber,COUNT(1) AS cnt FROM @tblA GROUP BY AccessNumber ) ftblA
CROSS APPLY (SELECT TOP(1) * FROM @tblB itblB WHERE ftblA.AccessNumber = itblB.AccessNumber) tblB
WHERE ftblA.cnt >1
-- Only 1000 should be displayed only --
【讨论】:
【参考方案5】:使用subquery
和correlation
方法
select access_no,
(select top 1 Value from table2 where access_no = t.access_no) as value
from Table1 t
where exists (
select 1 from table2 where access_no = t.access_no)
group by access_no
having count(*) > 1
但是,您需要在 subquery
中指定 order by
子句才能从 table2
获取值
【讨论】:
以上是关于SQL - 如何从一个表中获取重复记录并连接到另一张表的主要内容,如果未能解决你的问题,请参考以下文章