【问题标题】:SQL count distinct values appearing in different columnsSQL 计算出现在不同列中的不同值
【发布时间】:2023-03-08 08:05:02
【问题描述】:

我想计算不同的值并在 SQL 中报告它们的出现。问题是我需要计算不同列上的出现次数,然后为每列报告每个值的出现次数。所以,假设我有一个名为 Result 的表中的这样的数据:

Id OwnerId PilotId CoachId
A 1 2 3
B 2 2 3
C 3 1 3

那么我的结果应该是:

Id Owner Pilot Coach
1 1 1 0
2 1 2 0
3 1 0 3

我尝试使用 COUNT 函数和联合来单独获取每个结果,它可以工作。但我想在同一行 per Id 上得到结果。谁能帮我解决这个问题?

【问题讨论】:

  • 我没有得到 0 的值。
  • 如果 ID 从未出现在输入数据的特定列中。例如,1 和 2 从未出现在“CoachId”列中,因此为 0。
  • 但是一个值总是至少出现一次,@rucquoy 如果它在表中。在您的结果集中,PilotID 1 出现一次,但您的计数为 0
  • 第二列中的Id是从哪里来的,第一个表中的列(带有Id后缀的列)与结果表中的列之间的关系是什么?
  • 那是我的错,问题的结构不是很好。假设我的输入数据是一个具有 ID 和 3 个外键(OwnerId、PilotId、CoachId)的表。然后我希望对于这些外键的每个不同值,它们在每列中的出现次数。 (因此,对于每个 FK 值,我应该有 3 个计数:它作为 OwnerId 出现的次数、作为aPilotId 出现的次数和作为 CoachId 出现的次数)

标签: sql sql-server count pivot unpivot


【解决方案1】:

我认为您想将列转为行,然后计算每个值的出现次数。你可以这样做:

select v.id,
    sum(case when v.col = 'owner' then 1 else 0 end) owner,
    sum(case when v.col = 'pilot' then 1 else 0 end) pilot,
    sum(case when v.col = 'coach' then 1 else 0 end) coach
from mytable t
cross apply (values (t.ownerid, 'owner'), (t.pilotid, 'pilot'), (t.coachid, 'coach')) as v(id, col)
group by v.id

Demo on DB Fiddle

编号 |所有者 |飞行员 |教练 -: | ----: | ----: | ----: 1 | 1 | 1 | 0 2 | 1 | 2 | 0 3 | 1 | 0 | 3

【讨论】:

  • 是的,这似乎是 OP 想要的。
  • 噢噢噢噢噢,那太好了。在包含 700k+ 行的表上运行不到一秒钟。我什至不知道什么是交叉申请,我想我还有很多东西要学。谢谢你的回答先生!
【解决方案2】:

使用基本的SQL 命令也是如此。保证在每个 DBMS 上工作:

SELECT 
  ids.id, 
  SUM(CASE WHEN ro.ownerid = ids.id THEN 1 ELSE 0 END) AS Owner,
  SUM(CASE WHEN po.pilotid = ids.id THEN 1 ELSE 0 END) AS Pilot,
  SUM(CASE WHEN co.coachid = ids.id THEN 1 ELSE 0 END) AS Coach
FROM (
  SELECT ownerID AS id FROM result UNION
  SELECT pilotID FROM result UNION
  SELECT coachID FROM result  
) ids
  LEFT JOIN result ro ON ids.id = ro.ownerid
  LEFT JOIN result po ON ids.id = po.pilotid
  LEFT JOIN result co ON ids.id = co.coachid
GROUP BY ids.id

这里是SQLFiddler

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多