【问题标题】:Conditional Count on a field字段的条件计数
【发布时间】:2010-11-20 06:11:44
【问题描述】:

如果我有这样一张桌子:

jobId, jobName, Priority

其中优先级可以是 1 到 5 之间的整数。

因为我需要这个查询来生成报告图表,所以我需要显示 jobid、jobname 和 5 个字段,称为 Priority1、Priority2、Priority3、Priority4。优先级 5。

Priority1 应该计算优先级字段值为 1 的行数。

Priority2 应该计算优先级字段值为 2 的行数。

Priority3 应该计算优先级字段值为 3 的行数。

我将如何以快速高效的方式做到这一点?

【问题讨论】:

  • 一个工作 ID 是否有多个记录?所以 jobid 1 可能在表中出现 10 次,都具有不同的优先级?另外,您使用的是哪个数据库? sql服务器? mysql?

标签: sql count conditional-statements


【解决方案1】:
SELECT  Priority, COALESCE(cnt, 0)
FROM    (
        SELECT  1 AS Priority
        UNION ALL
        SELECT  2 AS Priority
        UNION ALL
        SELECT  3 AS Priority
        UNION ALL
        SELECT  4 AS Priority
        UNION ALL
        SELECT  5 AS Priority
        ) p
LEFT JOIN
        (
        SELECT  Priority, COUNT(*) AS cnt
        FROM    jobs
        GROUP BY
                Priority
        ) j
ON      j.Priority = p.Priority

【讨论】:

    【解决方案2】:

    我需要显示 jobid、jobname 和 5 个字段,称为 Priority1、Priority2、Priority3、Priority4。优先级 5。

    您的查询设计有问题。您也在每一行中显示一个特定的作业,因此您可能会遇到这样一种情况,即任何一行都有四个带有“0”的优先级列和一个带有“1”的优先级列(该作业的优先级)否则您最终会重复计算每一行的所有优先级。

    你真的想在这里展示什么?

    【讨论】:

      【解决方案3】:

      使用 ANSI SQL-92 CASE 语句,您可以执行以下操作(派生表加大小写):

       SELECT jobId, jobName, SUM(Priority1)
       AS Priority1, SUM(Priority2) AS
       Priority2, SUM(Priority3) AS
       Priority3, SUM(Priority4) AS
       Priority4,  SUM(Priority5) AS
       Priority5 FROM (
           SELECT jobId, jobName,
           CASE WHEN Priority = 1 THEN 1 ELSE 0 END AS Priority1,
           CASE WHEN Priority = 2 THEN 1 ELSE 0 END AS Priority2,
           CASE WHEN Priority = 3 THEN 1 ELSE 0 END AS Priority3,
           CASE WHEN Priority = 4 THEN 1 ELSE 0 END AS Priority4,
           CASE WHEN Priority = 5 THEN 1 ELSE 0 END AS Priority5
           FROM TableName
      
      
      )
      

      【讨论】:

        【解决方案4】:

        我想你可能会喜欢

        select 
            jobID, JobName,
            sum(case when Priority = 1 then 1 else 0 end) as priority1,
            sum(case when Priority = 2 then 1 else 0 end) as priority2,
            sum(case when Priority = 3 then 1 else 0 end) as priority3,
            sum(case when Priority = 4 then 1 else 0 end) as priority4,
            sum(case when Priority = 5 then 1 else 0 end) as priority5
        from
            Jobs
        group by 
            jobID, JobName
        

        但是我不确定您是否需要结果中的 jobID 和 JobName,如果需要删除它们并删除 group by,

        【讨论】:

          【解决方案5】:

          您可以将表与自身连接起来:

          select
             t.jobId, t.jobName,
             count(p1.jobId) as Priority1,
             count(p2.jobId) as Priority2,
             count(p3.jobId) as Priority3,
             count(p4.jobId) as Priority4,
             count(p5.jobId) as Priority5
          from
             theTable t
             left join theTable p1 on p1.jobId = t.jobId and p1.jobName = t.jobName and p1.Priority = 1
             left join theTable p2 on p2.jobId = t.jobId and p2.jobName = t.jobName and p2.Priority = 2
             left join theTable p3 on p3.jobId = t.jobId and p3.jobName = t.jobName and p3.Priority = 3
             left join theTable p4 on p4.jobId = t.jobId and p4.jobName = t.jobName and p4.Priority = 4
             left join theTable p5 on p5.jobId = t.jobId and p5.jobName = t.jobName and p5.Priority = 5
          group by
             t.jobId, t.jobName
          

          或者你可以在 sum 中使用 case:

          select
             jobId, jobName,
             sum(case Priority when 1 then 1 else 0 end) as Priority1,
             sum(case Priority when 2 then 1 else 0 end) as Priority2,
             sum(case Priority when 3 then 1 else 0 end) as Priority3,
             sum(case Priority when 4 then 1 else 0 end) as Priority4,
             sum(case Priority when 5 then 1 else 0 end) as Priority5
          from
             theTable
          group by
             jobId, jobName
          

          【讨论】:

            【解决方案6】:

            使用 COUNT 代替 SUM 消除了对 ELSE 语句的要求:

            SELECT jobId, jobName,
                COUNT(CASE WHEN Priority=1 THEN 1 END) AS Priority1,
                COUNT(CASE WHEN Priority=2 THEN 1 END) AS Priority2,
                COUNT(CASE WHEN Priority=3 THEN 1 END) AS Priority3,
                COUNT(CASE WHEN Priority=4 THEN 1 END) AS Priority4,
                COUNT(CASE WHEN Priority=5 THEN 1 END) AS Priority5
            FROM TableName
            GROUP BY jobId, jobName
            

            【讨论】:

            • 这将起作用,但会产生:警告:空值已被聚合或其他 SET 操作消除。
            【解决方案7】:

            IIF 不是标准 SQL 构造,但如果您的数据库支持它,您可以实现更优雅的语句,产生相同的结果:

            SELECT JobId, JobName,
            
            COUNT(IIF (Priority=1, 1, NULL)) AS Priority1,
            COUNT(IIF (Priority=2, 1, NULL)) AS Priority2,
            COUNT(IIF (Priority=3, 1, NULL)) AS Priority3,
            COUNT(IIF (Priority=4, 1, NULL)) AS Priority4,
            COUNT(IIF (Priority=5, 1, NULL)) AS Priority5
            
            FROM TableName
            GROUP BY JobId, JobName
            

            【讨论】:

              【解决方案8】:

              试试这个:

              SELECT Count(Student_ID) as 'StudentCount' 
              FROM CourseSemOne
              where Student_ID=3 
              Having Count(Student_ID) < 6 and Count(Student_ID) > 0;
              

              【讨论】:

              • 由于这是一个完全错误的答案,请帮我们大家一个忙并删除它
              猜你喜欢
              • 1970-01-01
              • 2016-10-13
              • 2011-01-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多