【问题标题】:Semi-complicated result set in sql querysql查询中的半复杂结果集
【发布时间】:2012-03-28 02:28:18
【问题描述】:

我有一个像这样的user

FIRSTNAME  |  LASTNAME  |  ID  |
--------------------------------
James      |  Hay       |  1   |
Other      |  Person    |  2   |

我也有一个像这样的attendance

EVENTID  |  USERID  |  ATTENDANCE  |  STATUS  |
-----------------------------------------------
1           1          True           3
2           1          False          1
3           1          False          3
1           2          False          1
2           2          True           3
3           2          True           3

基本上,当邀请用户参加活动时,attendance 表中会添加一行,其中包含活动 ID、用户 ID、假出席和状态 0。

状态只是他们反应的一个指标

0 = No Response
1 = Said No
2 = Said Yes
3 = Said yes and seats confirmed

我想通过查询这两个表得到的最终结果非常复杂,我无法弄清楚我需要做什么。

我想得到这样的结果

NAME          |  % of saying YES to an RSVP  | % of attending after saying yes
-------------------------------------------------------------------------------
James Hay     |             66               |                50
Other Person  |             66               |                100

我相信您可以弄清楚我是如何得到这些数字的,但要解释一下,James Hay 对 2/3 的活动的邀请是 3(是)状态。所以说是的百分比是 66。在他说是的 2 个中,他只参加了 1/2,所以说是后参加的百分比是 50%

任何在正确轨道上的推动都会非常感谢,因为我无法理解这一点。

编辑:

另外一件非常重要的事情是,我希望结果包括数据库中的每个用户,即使他们在 attendance 表中有 0 行。

【问题讨论】:

    标签: sql sql-server-2008 group-by


    【解决方案1】:
    select
    u.firstname, u.lastname
    -- said yes, as percentage
    ,floor(100.0
        * count(case when a.status in (2,3) then 1 end)
        / count(u.id)) yes
    -- attended after saying yes, as percentage
    ,floor(100.0
        * count(case when a.status in (2,3) and attendance='true' then 1 end)
        / nullif(count(case when a.status in (2,3) then 1 end),0)) attendance
    --,count(u.id) rsvp -- total invites
    from users u
    left join attendance a on a.userid = u.id
    group by u.firstname, u.lastname
    

    注意:对于用户从未收到邀请的特殊情况,统计显示为 0% 和 NULL。

    术语解释:

    • count(case when a.status in (2,3) then 1 end)
      • 表示他们说是的次数,使用了两次
    • count(u.id)
      • 收到了多少邀请(出席记录)。特殊情况是当他们没有收到任何东西时,在这种情况下 LEFT JOIN 使其成为1(不重要)
    • count(case when a.status in (2,3) and attendance='true' then 1 end)
      • 在答应之后,他们参加了多少次

    【讨论】:

    • 感谢这个工作,您还向我解释了它,这很好而且很有帮助。只是要检查其中哪个更快。干杯
    • 我以为您想要样本中的整数。如果您想要小数,只需删除它们出现的“地板”字样。
    【解决方案2】:
    SELECT A.NAME,B.PERCENTAGE_YES_RSVP,B.PERCENTAGE_AFTER_YES
    FROM 
    ( 
      SELECT U.ID AS ID,U.FIRSTNAME+''+U.LASTNAME AS NAME
      FROM USERS U
    ) A,
    (
      SELECT A.USERID,A.PERCENTAGE_YES_RSVP,B.PERCENTAGE_AFTER_YES
    FROM   
      (
        SELECT B.USERID,ROUND((CAST(B.COUNT_YES_RSVP AS FLOAT)/B.TOTAL_COUNT)*100,0) AS PERCENTAGE_YES_RSVP    
        FROM  
        (SELECT A.USERID,
           SUM(CASE WHEN A.STATUS=3 THEN 1 END)AS COUNT_YES_RSVP,
           COUNT(*) AS TOTAL_COUNT
           FROM ATTENDANCE A  
           GROUP BY A.USERID
         ) B
      ) A,  
    (
      SELECT C.USERID,(CAST(C.COUNT_AFTER_YES_RSVP AS FLOAT)/C.TOTAL_COUNT)*100 AS PERCENTAGE_AFTER_YES   
      FROM  
      (SELECT A.USERID,
           SUM(CASE WHEN A.STATUS=3 AND A.ATTENDANCE='TRUE' THEN 1 END)AS COUNT_AFTER_YES_RSVP,
           SUM(CASE WHEN A.STATUS=3 THEN 1 END) AS TOTAL_COUNT
       FROM ATTENDANCE A  
       GROUP BY A.USERID
       ) C
    )B   
    WHERE A.USERID=B.USERID
    ) B
    WHERE A.ID = B.USERID;
    

    【讨论】:

    • 我在 SUM(CASE WHEN A.[STATUS]=3 THEN 1) 行的 ')' 附近得到一个不正确的语法错误
    • 是的,这个也给了我更准确的答案(即小数位)。唯一的问题是我的数据库中有 869 个用户,我只得到 340 行。你知道为什么会这样吗?
    • 太棒了...过去 30 分钟坐在上面... :)
    • 是的,我也想邀请所有从未被邀请的人,但我说服了我的老板,这对我们的目的没有用处。谢谢!
    【解决方案3】:

    编辑:

    糟糕,忘记加入用户了 :)

    select firstname, lastname,
      convert(decimal (5, 2), 1. * count(case when status in (2, 3) then 1 end) / count(*) * 100) SaidYes,
      convert(decimal (5, 2), 1. * count(case when status in (2, 3) and attendance = 'True' then 1 end) / count(case when status in (2, 3) then 1 end) * 100) ActuallyAttended
    from attendance a
    join users u on a.userid = u.id
    group by firstname, lastname
    

    【讨论】:

      猜你喜欢
      • 2014-08-03
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多