使用 CTE 比较多行数据
Using CTE for comparing data in multiple rows
在这个数据集中,我需要标记出应用程序 ID P-10900,因为它被 2 个 TeamMember 触及。
我们可以以创建为单独列的标志的形式将其标记出来。
我知道可以使用递归 CTE 轻松完成,但不确定如何编写语法。
TeamMember Status ApplicationID
NULL NW P-10900
John IR P-10900
John CO P-10900
Dick IR P-10900
Dick PA P-10900
NULL NW P-06700
John IR P-06700
John PA P-06700
NULL NW P-14600
Andre IR P-14600
这是对此处提出的问题的扩展
Find which rows have different values for a given column in SQL
我正在使用 MS SQL Server 2012
我期待这样的输出:
TeamMember Status ApplicationID Flag
NULL NW P-10900 Dup
John IR P-10900 Dup
John CO P-10900 Dup
Dick IR P-10900 Dup
Dick PA P-10900 Dup
NULL NW P-06700 Alike
John IR P-06700 Alike
John PA P-06700 Alike
NULL NW P-14600 Alike
Andre IR P-14600 Alike
这是架构:
CREATE TABLE App
([TeamMember] varchar(5), [aStatus] varchar(2), [ApplicationID] varchar(7))
;
INSERT INTO App
([TeamMember], [aStatus], [ApplicationID])
VALUES
(NULL, 'NW', 'P-10900'),
('John', 'IR', 'P-10900'),
('John', 'CO', 'P-10900'),
('Dick', 'IR', 'P-10900'),
('Dick', 'PA', 'P-10900'),
(NULL, 'NW', 'P-06700'),
('John', 'IR', 'P-06700'),
('John', 'PA', 'P-06700'),
(NULL, 'NW', 'P-14600'),
('Andre', 'IR', 'P-14600')
;
这是我尝试过的方法,当然是行不通的:
WITH cte (applicationid, status, teammember)
AS (SELECT applicationid,
status,
teammember
FROM app
GROUP BY applicationid,
status,
teammember)
SELECT applicationid,
teammember,
status,
CASE
WHEN (SELECT DISTINCT CASE
WHEN Count(applicationid) > 1 THEN 'Alike'
ELSE 'Dup'
END
FROM cte B
WHERE B.teammember = A.teammember
GROUP BY B.teammember) = 'Alike' THEN 'Alike'
ELSE 'Dup'
END AS Flag
FROM cte A
ORDER BY applicationid
你只是把事情复杂化了。您在这里根本不需要 CTE:
SELECT a.*, dups.Flag
FROM app a INNER JOIN (
SELECT ApplicationID, CASE
WHEN MIN(TeamMember) = MAX(TeamMember) THEN 'Alike'
ELSE 'Dup'
END Flag
FROM app t
GROUP BY ApplicationID) dups
ON a.ApplicationID = dups.ApplicationID
在这个数据集中,我需要标记出应用程序 ID P-10900,因为它被 2 个 TeamMember 触及。 我们可以以创建为单独列的标志的形式将其标记出来。
我知道可以使用递归 CTE 轻松完成,但不确定如何编写语法。
TeamMember Status ApplicationID
NULL NW P-10900
John IR P-10900
John CO P-10900
Dick IR P-10900
Dick PA P-10900
NULL NW P-06700
John IR P-06700
John PA P-06700
NULL NW P-14600
Andre IR P-14600
这是对此处提出的问题的扩展
Find which rows have different values for a given column in SQL
我正在使用 MS SQL Server 2012
我期待这样的输出:
TeamMember Status ApplicationID Flag
NULL NW P-10900 Dup
John IR P-10900 Dup
John CO P-10900 Dup
Dick IR P-10900 Dup
Dick PA P-10900 Dup
NULL NW P-06700 Alike
John IR P-06700 Alike
John PA P-06700 Alike
NULL NW P-14600 Alike
Andre IR P-14600 Alike
这是架构:
CREATE TABLE App
([TeamMember] varchar(5), [aStatus] varchar(2), [ApplicationID] varchar(7))
;
INSERT INTO App
([TeamMember], [aStatus], [ApplicationID])
VALUES
(NULL, 'NW', 'P-10900'),
('John', 'IR', 'P-10900'),
('John', 'CO', 'P-10900'),
('Dick', 'IR', 'P-10900'),
('Dick', 'PA', 'P-10900'),
(NULL, 'NW', 'P-06700'),
('John', 'IR', 'P-06700'),
('John', 'PA', 'P-06700'),
(NULL, 'NW', 'P-14600'),
('Andre', 'IR', 'P-14600')
;
这是我尝试过的方法,当然是行不通的:
WITH cte (applicationid, status, teammember)
AS (SELECT applicationid,
status,
teammember
FROM app
GROUP BY applicationid,
status,
teammember)
SELECT applicationid,
teammember,
status,
CASE
WHEN (SELECT DISTINCT CASE
WHEN Count(applicationid) > 1 THEN 'Alike'
ELSE 'Dup'
END
FROM cte B
WHERE B.teammember = A.teammember
GROUP BY B.teammember) = 'Alike' THEN 'Alike'
ELSE 'Dup'
END AS Flag
FROM cte A
ORDER BY applicationid
你只是把事情复杂化了。您在这里根本不需要 CTE:
SELECT a.*, dups.Flag
FROM app a INNER JOIN (
SELECT ApplicationID, CASE
WHEN MIN(TeamMember) = MAX(TeamMember) THEN 'Alike'
ELSE 'Dup'
END Flag
FROM app t
GROUP BY ApplicationID) dups
ON a.ApplicationID = dups.ApplicationID