Sql 检索emp表中任何重复数据行的报告,以及该行数据重复的次数
我的EMP表如下:Sql 检索emp表中任何重复数据行的报告,以及该行数据重复的次数,sql,sql-server,Sql,Sql Server,我的EMP表如下: CREATE TABLE EMP ( [ID] INT NOT NULL PRIMARY KEY, [MGR_ID] INT, [DEPT_ID] INT, [NAME] VARCHAR(30), [SAL] INT, [DOJ] DATE ); 我需要检索emp表中任何重复数据行的报告,以及该行数据重复的次数 我部分解决了这个问题: 此查询返回每个重复行的单个实例 SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
CREATE TABLE EMP
(
[ID] INT NOT NULL PRIMARY KEY,
[MGR_ID] INT,
[DEPT_ID] INT,
[NAME] VARCHAR(30),
[SAL] INT,
[DOJ] DATE
);
我需要检索emp表中任何重复数据行的报告,以及该行数据重复的次数
我部分解决了这个问题:
此查询返回每个重复行的单个实例
SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
from EMP
group by [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
having count(*) > 1
输出将是:
MGR_ID DEPT_ID NAME SAL DOJ
NULL 2 Hash 100 2012-01-01
1 2 Robo 100 2012-01-01
2 1 Privy 50 2012-05-01
我仍然需要根据这些行在EMP表中的重复次数对输出进行分组
我试过这个:
WITH CTE
AS
(
SELECT * from EMP A
join ( SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
from EMP
group by [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
having count(*) > 1 ) B
on a.[MGR_ID] = b.[MGR_ID]
OR a.[MGR_ID] != b.[MGR_ID]
AND a.[DEPT_ID] = b.[DEPT_ID]
AND a.[NAME] = b.[NAME]
AND a.[SAL] = b.[SAL]
AND a.[DOJ] = b.[DOJ]
)
SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ], DENSE_RANK() OVER
(PARTITION BY [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ] ORDER BY DUPICATES) AS [DUPLICATES]
FROM CTE
但我有一个错误:
Msg 8156,第16级,状态1,第1行为“CTE”多次指定了列“MGR_ID” 请帮忙 已找到部分解决方案,除了在3条记录的输出中返回MRG_ID列,其中该列为=NULL
with cte as
(
SELECT A.[DEPT_ID],A.[NAME],A.[SAL],A.[DOJ] from EMP A
join ( SELECT [DEPT_ID],[NAME],[SAL],[DOJ]
from EMP
group by [DEPT_ID],[NAME],[SAL],[DOJ]
having count(*) > 1 ) B
ON a.[DEPT_ID] = b.[DEPT_ID]
AND a.[NAME] = b.[NAME]
AND a.[SAL] = b.[SAL]
AND a.[DOJ] = b.[DOJ]
)
SELECT [DEPT_ID],[NAME],[SAL],[DOJ], DENSE_RANK() OVER
(PARTITION BY [NAME] ORDER BY [NAME] DESC) AS [DUPLICATES], RANK() OVER
(PARTITION BY [NAME] ORDER BY [NAME] DESC) AS [SimpleRank]
FROM CTE
DEPT_ID NAME SAL DOJ DUPLICATES SimpleRank
2 Hash 100 2012-01-01 1 1
2 Hash 100 2012-01-01 1 1
2 Hash 100 2012-01-01 1 1
1 Privy 50 2012-05-01 1 1
1 Privy 50 2012-05-01 1 1
1 Privy 50 2012-05-01 1 1
2 Robo 100 2012-01-01 1 1
2 Robo 100 2012-01-01 1 1
2 Robo 100 2012-01-01 1 1
很多
最终的解决方案似乎简单得多:
Select [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ], count(name) From EMP group by [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ] having Count(Name) >1
它生成这个结果集
MGR_ID DEPT_ID NAME SAL DOJ Count_Of_ Duplicated_Rows
NULL 2 Hash 100 2012-01-01 3
1 2 Robo 100 2012-01-01 3
2 1 Privy 50 2012-05-01 3
注意:仅当按重复的列分组时,此操作才有效
下面的示例基于前面更复杂的查询,但它验证了行中的所有字段,而上面的简单查询检查您分组查询所依据的特定列的条件
WITH CTE
AS
(
SELECT A.[MGR_ID], A.[DEPT_ID], A.[NAME], A.[SAL], A.[DOJ]
FROM EMP A
JOIN (SELECT [MGR_ID], [DEPT_ID], [NAME], [SAL], [DOJ]
FROM EMP
GROUP BY [MGR_ID], [DEPT_ID], [NAME], [SAL], [DOJ]
HAVING count(*) > 1) B
ON a.[MGR_ID] = b.[MGR_ID]
AND a.[DEPT_ID] = b.[DEPT_ID]
AND a.[NAME] = b.[NAME]
AND a.[SAL] = b.[SAL]
AND a.[DOJ] = b.[DOJ]
)
SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ],
count(*) As Count_Of_Duplicated_Rows
FROM EMP
GROUP BY [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
--HAVING Count(*) >1
您的问题是没有在CTE中显式命名所选列。由于
EMP
和子查询都有一个名为MGR\u ID
的列,因此在连接上执行select*
操作会两次返回该列MGR\u ID
。根据法律,这是不允许的:
只有在查询定义中提供了所有结果列的不同名称时,列名列表才是可选的
请注意,对于联接两侧存在的每对列,您将遇到相同的错误。要解决此问题,您可以在列列表中使用重复列的别名显式命名CTE返回的列,如下所示:
WITH CTE (mgr_id,dept_id,name,sal,doj,mgr_id2,...) //mgr_id2 is an alias for b.mgr_id
AS
...
你可以参考这个演示。删除列列表,您将看到与现在相同的错误
或者,您可以在CTE本身中指定要选择的列,我建议您这样做,因为您实际上不需要在查询中重复任何列:
;with cte as
(
SELECT A.[MGR_ID],A.[DEPT_ID],A.[NAME],A.[SAL],A.[DOJ] from EMP A
join ( SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
from EMP
group by [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
having count(*) > 1 ) B
...
试试这个
WITH CTE
AS
(
SELECT a.* from EMP A
join ( SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
from EMP
group by [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]
having count(*) > 1 ) B
on a.[MGR_ID] = b.[MGR_ID]
--OR a.[MGR_ID] != b.[MGR_ID]
AND a.[DEPT_ID] = b.[DEPT_ID]
AND a.[NAME] = b.[NAME]
AND a.[SAL] = b.[SAL]
AND a.[DOJ] = b.[DOJ]
),cte2 as(
SELECT [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ], DENSE_RANK() OVER
(PARTITION BY [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ] ORDER BY [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ]) AS [DUPLICATES]
FROM CTE )
select [MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ] from cte2 where DUPLICATES=1
如果你停止大喊大叫,你会得到更好的帮助。用大写字母打字被认为是粗鲁的。请编辑您的问题。只是一个建议,请编辑您的标题,以免不尊重您。
a.[MGR\u ID]=b.[MGR\u ID]或a.[MGR\u ID]!=b、 [MGR_ID]
-这等于不检查任何一种情况@enigma6205表中是否有重复的列名,或者是否有类似重复的虚拟列名?没有一列是这样的,那么您是如何使用它的,并且多次为“CTE”指定了列“MGR_ID”,通过使用特定的列名而不是在外部查询中使用*(所有列)来纠正错误。Ajaynaidu Pappala,我已经尝试将(*)更改为此列列表:[MGR_ID],[DEPT_ID],[NAME],[SAL],[DOJ],但还是出现了相同的错误。嗨,Shree,我想我遵循了你的建议,但仍然收到错误消息207,16级,状态1,第228行无效列名“Dupictes”。我正在运行的查询是,您是否有同名的列?此外,你需要清楚你正在尝试做什么。请参阅我的原始帖子,以获得所需的解决方案。我已经尝试过了。它产生的副本范围不全;它不会返回第三个重复行,该行在MRG_ID列中具有空值。请看我上面的解释。