最近我需要根据以下事实生成报告:
TableA具有以下2列UserID和DocumentType
我已经提供了一份强制性的'文档类型:Type1,Type2,Type3和I需要返回每个没有这三种类型的UserID以及它们缺少的类型。
例如,如果TableA包含以下行
12 Type1
12 Type2
12 Type4
13 Type1
13 Type2
13 Type3
14 Type1
15 Type6
15 Type7
15 Type8
然后理想情况下输出将是:
12 Type3
14 Type2, Type3
15 Type1, Type2, Type3
理想情况下,生成结果的查询应该能够处理多达数千万条记录。
我们最近使用SQL Server 2012实现了一个类似问题的解决方案(比这更复杂一点)。在多个表中获取完整报告需要3分半钟,总共有大约400万条记录。我们想知道是否有更好的想法可以更快地做到这一点。
请随意分享您的想法,以解决此问题。
谢谢! :)
答案 0 :(得分:1)
这是FOR XML路径连接方法:
equals()
我相信检查大型数据集的条件聚合查询可能会有更好的性能。
条件聚合
CREATE TABLE TableA (ID INT, TypeCol CHAR(5));
INSERT INTO TableA (ID,TypeCol) VALUES (12,'Type1')
,(12,'Type2')
,(12,'Type4')
,(13,'Type1')
,(13,'Type2')
,(13,'Type3')
,(14,'Type1')
,(15,'Type6')
,(15,'Type7')
,(15,'Type8')
;WITH cteRequiredTypes AS (
SELECT 'type1' as TypeCol
UNION ALL
SELECT 'type2'
UNION ALL
SELECT 'type3'
)
, cteTableAIds AS (
SELECT DISTINCT Id
FROM
TableA
)
, cteMissingTypes AS (
SELECT
i.ID
,r.TypeCol
FROm
cteRequiredTypes r
CROSS JOIN cteTableAIds i
LEFT JOIN TableA a
ON r.TypeCol = a.TypeCol
AND i.ID = a.ID
WHERE
a.ID IS NULL
)
SELECT
DISTINCT a.ID
,STUFF(
(SELECT ',' + TypeCol
FROM
cteMissingTypes t
WHERE t.ID = a.ID
FOR XML PATH(''))
,1,1,'')
FROM
cteMissingTypes a
答案 1 :(得分:0)
简单方法
SELECT DISTINCT UserID
FROM your_table
EXCEPT
(
SELECT UserID
FROM your_table
WHERE DocumentType = ('Type1')
UNION
SELECT UserID
FROM your_table
WHERE DocumentType = ('Type2')
UNION
SELECT UserID
FROM your_table
WHERE DocumentType = ('Type3')
)
在规则中不能比这更精确 - 所以你的编译器会查看索引等并进行优化。
除非有部分问题,否则你没有告诉我们。
答案 2 :(得分:0)
我认为你需要这样的东西
select x2.*
(select *
from (select distinct UserID from [table])x
cross join
(select 'type1' DocumentType union
select 'type2' union
select 'type3' ) y
) x2
left join [table] y2
on y2.UserID = x2.UserID
and y2.DocumentType = x2.DocumentType
where y2.DocumentType is null
order by x2.UserID
答案 3 :(得分:0)
<强> DEMO 强>
WITH
base ([DocumentType]) as (
SELECT 'Type1' UNION ALL
SELECT 'Type2' UNION ALL
SELECT 'Type3'
),
users as (
SELECT DISTINCT [userID]
FROM Table1 t
),
pairs as (
SELECT *
FROM users, base
)
SELECT p.userID, p.[DocumentType], t.[DocumentType]
FROM pairs p
LEFT JOIN Table1 t
ON p.[DocumentType] = t.[DocumentType]
AND p.[userID] = t.[userID]
WHERE t.[DocumentType] IS NULL
输出