我有一张表Categories
:
|Category|Person|
|--------|------|
|A |P1 |
|A |P2 |
|A |P3 |
|B |P1 |
|C |P2 |
|C |P3 |
|D |P4 |
我想计算有A
的人有B
的人数以及有A
的人C
的人数。所以交叉:
|Category A|Category B|Count|
|----------|----------|-----|
|A |B |1 |
|A |C |2 |
|A |D |0 |
|B |A |1 |
|B |C |0 |
|B |D |0 |
|C |A |2 |
|C |B |0 |
|C |D |0 |
|D |A |0 |
|D |B |0 |
|D |C |0 |
但是,踢球者需要在一个需要将其作为单个查询运行的糟糕系统上执行。到目前为止,我有:
SELECT
X.[Category A]
,COUNT(*) AS [Count]
,X.[Category B]
FROM (
SELECT
A.Category AS [Category A]
,B.Category AS [Category B]
FROM (
SELECT
Category
,Person
FROM Categories
) AS A
CROSS JOIN (
SELECT
Category
,Person
FROM Categories
) B WHERE A.Category = B.Category
) X GROUP BY X.[Category A], X.[Category B]
答案 0 :(得分:0)
检查这个。
使用CTE
with CTE as
(
select
Person,Category
from Categories
)
select distinct c2.Category , c1.Category
,count(case when c1.person=c2.person then 1 end ) as Count
from CTE C1, CTE c2
where c1.Category <> c2.Category
group by c1.Category,c2.Category
没有CTE
select distinct c2.Category , c1.Category
,count(case when c1.person=c2.person then 1 end ) as Count
from Categories C1, Categories c2
where c1.Category <> c2.Category
group by c1.Category,c2.Category
输出:
答案 1 :(得分:0)
您可以使用CTE构建如下查询:
WITH CTE_CategoryCombinations AS
(
SELECT A.Category AS [Category A], B.Category AS [Category B]
FROM Categories AS A
INNER JOIN Categories AS B
ON A.Person = B.Person AND A.Category != B.Category )
SELECT [Category A], [Category B], COUNT(1)
FROM CTE_CategoryCombinations
GROUP BY [Category A], [Category B]
ORDER BY [Category A], [Category B];
这使用CTE,它是公用表表达式。我们创建CTE_CategoryCombinations的CTE将仅在其后的SELECT和GROUP BY cluase的持续时间内持续。它将不再可用,并且引用它将产生错误。
使用它的优点:
1)CTE提供了比使用Sub查询更快执行的好处,因为每次我们获取应用子查询的行时都会运行子查询。 CTE应该是解决这个问题的更快方法,这也应该得到理想的结果。
2)我们不使用交叉连接,交叉连接是一项昂贵的任务。另一方面,内部联接是获得我们期望的结果的更有效方式,因为它设置了我们比较类别的条件,因为我们只想比较相同人群的类别。
编辑2:
如果您不必坚持使用单个语句,则可以使用临时表。像这样:
INSERT INTO #Categories
FROM
(
SELECT A.Category AS [Category A], B.Category AS [Category B], A.Person
FROM Categories AS A
INNER JOIN Categories AS B
ON A.Person = B.Person AND A.Category != B.Category ) AS Temp;
SELECT [Category A], [Category B], COUNT(DISTINCT Person)
FROM #Categories
GROUP BY [Category A], [Category B]
ORDER BY [Category A], [Category B];
答案 2 :(得分:0)
尝试以下脚本,
DECLARE @TABLE TABLE (
Category VARCHAR(10)
,Person VARCHAR(10)
)
INSERT INTO @TABLE
VALUES ('A','P1'),('A','P2'),('A','P3')
,('B','P1'),('C','P2'),('C','P3')
,('D','P4')
SELECT T1.Category AS CategoryA
,T2.Category AS CategoryB
,COUNT(CASE WHEN T1.Person=T2.Person THEN 1 END ) AS AB_Count
FROM @TABLE T1
INNER JOIN @TABLE T2 ON T1.Category <> T2.Category
GROUP BY T1.Category,T2.Category
ORDER BY 1