返回相对于另一列值的已计数列

时间:2014-01-23 21:28:50

标签: sql sql-server reporting-services

我有一个包含多列的表格;其中两个我选择:“Operation_desc”和“new_rtg_no”

还有其他列作为参数,并且是硬编码的,因为它们永远不会改变。

我正在尝试收集关联的数字并计算每个数字的数量,并将其与SSRS报告中使用的查询相关联。

表格中的数据示例

Operation   Rating
INS OPER    3.00
LAW         3.00
HUMAN RES   5.00
HUMAN RES   3.00
INFO SERVS  3.00
HUMAN RES   3.00
HUMAN RES   3.00
HUMAN RES   4.00
HUMAN RES   3.00
HUMAN RES   4.00

我得到的是我实际上正在寻找的东西,但是我得到的是整个数据库的个人评级的整数。我知道我可以使用CASE来做我想做的事情,但是这将需要一大堆子查询,这些查询会大大减慢一切。

而不是这个:

            Bonus Eligible          Exempt              Non-Exempt
OPERATION   R1  R2  R3  R4  R5  Ttl R1  R2  R3  R4  R5  Ttl R1 ... etc
INS OPER    0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3
LAW         0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3
HUMAN RES   0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3
Info Servs  0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3
COLMBS LF   0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3
CONTROLLER  0   0   0   0   0   0   0   1   9   3   0   17  0   0   13  5   1   16  0   0   3   1   0   3

我想要这个:

                Bonus Eligible          Exempt              Non-Exempt
OPERATION   R1  R2  R3  R4  R5  Ttl R1  R2  R3  R4  R5  Ttl R1 ... etc
INS OPER    3   2   4   1   1   11  0   1   13  3   0   17  0   0   13  5   1   19  0   0   3   1   0   4
LAW         0   0   0   0   0   0   0   2   7   3   1   13  0   0   10  2   1   13  0   0   3   4   0   7
..... ETC

我目前的查询是:

SELECT DISTINCT OPERATION_DESC, (SELECT     COUNT(NEW_RTG_NO) AS Expr1
              FROM         EMPL
              WHERE     (NEW_RTG_NO = 1 AND GRADE_CD = '50')) AS R1B,
           (SELECT     COUNT(NEW_RTG_NO) AS Expr1
            FROM          EMPL AS EMPL_4
            WHERE      (NEW_RTG_NO = 2 AND GRADE_CD = '50' )) AS R2B,
           (SELECT     COUNT(NEW_RTG_NO) AS Expr1
            FROM          EMPL AS EMPL_3
            WHERE      (new_RTG_NO = 3 AND GRADE_CD = '50')) AS R3B,
           (SELECT     COUNT(new_RTG_NO) AS Expr1
            FROM          EMPL AS EMPL_2
            WHERE      (NEW_RTG_NO = 4 AND GRADE_CD = '50')) AS R4B,
           (SELECT     COUNT(NEW_RTG_NO) AS Expr1
            FROM          EMPL AS EMPL_1
            WHERE      (NEW_RTG_NO = 5 AND GRADE_CD = '50')) AS R5B
    , (select count(NEW_RTG_NO) as expr1 from empl where (grade_cd = '50')) AS TotalBonus
    , (SELECT COUNT(NEW_RTG_NO) AS Expr1
               FROM         EMPL
               WHERE     (NEW_RTG_NO = 1 AND FLSA_STAT_CD = 'E')) AS R1E,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_4
               WHERE      (NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'E' )) AS R2E,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_3
               WHERE      (new_RTG_NO = 3 AND FLSA_STAT_CD = 'E')) AS R3E,
              (SELECT     COUNT(new_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_2
               WHERE      (NEW_RTG_NO = 4 AND FLSA_STAT_CD = 'E')) AS R4E,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_1
               WHERE      (NEW_RTG_NO = 5 AND FLSA_STAT_CD = 'E')) AS R5E
    , (select count(NEW_RTG_NO) as expr1 from empl where (FLSA_STAT_CD = 'E')) AS TotalExempt
    , (SELECT COUNT(NEW_RTG_NO) AS Expr1
               FROM         EMPL
               WHERE     (NEW_RTG_NO = 1 AND FLSA_STAT_CD = 'N')) AS R1N,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_4
               WHERE      (NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'N' )) AS R2N,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
                FROM          EMPL AS EMPL_3
                WHERE      (new_RTG_NO = 3 AND FLSA_STAT_CD = 'N')) AS R3N,
              (SELECT     COUNT(new_RTG_NO) AS Expr1
                FROM          EMPL AS EMPL_2
                WHERE      (NEW_RTG_NO = 4 AND FLSA_STAT_CD = 'N')) AS R4N,
              (SELECT     COUNT(NEW_RTG_NO) AS Expr1
               FROM          EMPL AS EMPL_1
               WHERE      (NEW_RTG_NO = 5 AND FLSA_STAT_CD = 'N')) AS R5N
    , (select count(NEW_RTG_NO) as expr1 from empl where (FLSA_STAT_CD = 'N')) AS TotalNonExempt
    , (SELECT COUNT(NEW_RTG_NO) AS Expr1
                FROM         EMPL
                WHERE     (NEW_RTG_NO = 1 AND FULL_OR_PART_TM_IND = 'P')) AS R1P,
               (SELECT     COUNT(NEW_RTG_NO) AS Expr1
                  FROM          EMPL AS EMPL_4
                  WHERE      (NEW_RTG_NO = 2 AND FULL_OR_PART_TM_IND = 'P' )) AS R2P,
               (SELECT     COUNT(NEW_RTG_NO) AS Expr1
                 FROM          EMPL AS EMPL_3
                 WHERE      (new_RTG_NO = 3 AND FULL_OR_PART_TM_IND = 'P')) AS R3P,
               (SELECT     COUNT(new_RTG_NO) AS Expr1
                 FROM          EMPL AS EMPL_2
                 WHERE      (NEW_RTG_NO = 4 AND FULL_OR_PART_TM_IND = 'P')) AS R4P,
               (SELECT     COUNT(NEW_RTG_NO) AS Expr1
                 FROM          EMPL AS EMPL_1
                 WHERE      (NEW_RTG_NO = 5 AND FULL_OR_PART_TM_IND = 'P')) AS R5P
    , (select count(NEW_RTG_NO) as expr1 
                from empl 
                where (FULL_OR_PART_TM_IND = 'P')) AS TotalPT
 FROM         EMPL AS E
 group by E.OPERATION_DESC ORDER BY E.OPERATION_DESC

现在我的问题是:无论如何都要做我正在尝试做的事情,而不必使用CASE声明,并为每个案例复制并粘贴40次。我也很乐意在SSRS中使用简单的查询来实现这一点,如果这样做会更容易。

最终查询:

SELECT DISTINCT OPERATION_DESC, 
SUM(Case when NEW_RTG_NO = 1 and GRADE_CD = '50' then 1 else 0 end) AS R1B,
SUM(case when NEW_RTG_NO = 2 AND GRADE_CD = '50' then 1 else 0 end) AS R2B,
SUM(case when NEW_RTG_NO = 3 AND GRADE_CD = '50' then 1 else 0 end) AS R3B,
SUM(case when NEW_RTG_NO = 4 AND GRADE_CD = '50' then 1 else 0 end) AS R4B,
SUM(case when NEW_RTG_NO = 5 AND GRADE_CD = '50' then 1 else 0 end) AS R5B,
SUM(case when GRADE_CD = '50' then 1 else 0 end ) AS TotalBonus,
SUM(case when NEW_RTG_NO = 1 AND FLSA_STAT_CD = 'E' then 1 else 0 end) AS R1E,
SUM(case when NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'E' then 1 else 0 end) AS R2E,
SUM(case when NEW_RTG_NO = 3 AND FLSA_STAT_CD = 'E' then 1 else 0 end) AS R3E,
SUM(case when NEW_RTG_NO = 4 AND FLSA_STAT_CD = 'E' then 1 else 0 end) AS R4E,
SUM(case when NEW_RTG_NO = 5 AND FLSA_STAT_CD = 'E' then 1 else 0 end) AS R5E,
SUM(case when FLSA_STAT_CD = 'E' then 1 else 0 end ) AS TotalExempt,
SUM(case when NEW_RTG_NO = 1 AND FLSA_STAT_CD = 'N' then 1 else 0 end ) AS R1N,
SUM(case when NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'N' then 1 else 0 end ) AS R2N,
SUM(case when NEW_RTG_NO = 3 AND FLSA_STAT_CD = 'N' then 1 else 0 end ) AS R3N,
SUM(case when NEW_RTG_NO = 4 AND FLSA_STAT_CD = 'N' then 1 else 0 end ) AS R4N,
SUM(case when NEW_RTG_NO = 5 AND FLSA_STAT_CD = 'N' then 1 else 0 end ) AS R5N,
SUM(case when FLSA_STAT_CD = 'N' then 1 else 0 end ) AS TotalNonExempt,
SUM(case when NEW_RTG_NO = 1 AND FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS R1P,
SUM(case when NEW_RTG_NO = 2 AND FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS R2P,
SUM(case when NEW_RTG_NO = 3 AND FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS R3P,
SUM(case when NEW_RTG_NO = 4 AND FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS R4P,
SUM(case when NEW_RTG_NO = 5 AND FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS R5P,
SUM(case when FULL_OR_PART_TM_IND = 'P' then 1 else 0 end ) AS TotalPT
FROM EMPL
GROUP BY OPERATION_DESC 
ORDER BY OPERATION_DESC

1 个答案:

答案 0 :(得分:0)

您的group by无效,因为每个选项都是一个独立的不相关子查询。例如,

(SELECT     COUNT(NEW_RTG_NO) AS Expr1
           FROM          EMPL AS EMPL_4
           WHERE      (NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'E' )) AS R2E

将从整个数据库中获取计数,因为其中没有group by。以下是您需要针对当前结构执行的操作:

(SELECT     COUNT(NEW_RTG_NO) AS Expr1
           FROM          EMPL AS EMPL_4
           WHERE      (NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'E' )
           GROUP BY OPERATION_DESC) AS R2E

我在这里看到的问题是你根本不需要完成所有这些不相关的子查询。我将在下面演示。请注意,我使用SUM IF而不是COUNT。这就是说,如果满足条件,则在总和中加1,否则加零。

SELECT DISTINCT OPERATION_DESC, 
    SUM(IF(NEW_RTG_NO = 1 AND GRADE_CD = '50', 1, 0)) AS R1B,
    SUM(IF(NEW_RTG_NO = 2 AND GRADE_CD = '50', 1, 0)) AS R2B,
    SUM(IF(NEW_RTG_NO = 3 AND GRADE_CD = '50', 1, 0)) AS R3B,
    SUM(IF(NEW_RTG_NO = 4 AND GRADE_CD = '50', 1, 0)) AS R4B,
    SUM(IF(NEW_RTG_NO = 5 AND GRADE_CD = '50', 1, 0)) AS R5B,
    SUM(IF(GRADE_CD = '50', 1, 0)) AS TotalBonus,
    **** and so forth ****
FROM empl E
GROUP BY E.OPERATION_DESC 
ORDER BY E.OPERATION_DESC

编辑:

你的原帖是用MYSQL标记的,所以上面是MYSQL。我不在SQL中工作,所以我对它的了解来自几年前的课程。如果我没记错的话,你应该可以为每个SUM IF做一些这样的事情:

    SUM(CASE WHEN NEW_RTG_NO = 1 AND GRADE_CD = '50'
           THEN 1 
           ELSE 0 
        END) AS R1B,

编辑2:

请参阅this answer了解在SQL中执行此操作的其他方法。

编辑3:

您可能还想考虑另一种方法。

 SELECT COUNT(r1e.NEW_RTG_NO) AS R1E, COUNT(r2e.NEW_RTG_NO) AS R2E, .... et cetera ....
 FROM empl E
 LEFT JOIN empl r1e ON r1e.NEW_RTG_NO = E.NEW_RTG_NO AND r1e.NEW_RTG_NO = 1 AND FLSA_STAT_CD = 'E'
 LEFT JOIN empl r2e ON r2e.NEW_RTG_NO = E.NEW_RTG_NO AND r2e.NEW_RTG_NO = 2 AND FLSA_STAT_CD = 'E'
 .... et cetera ....

我不知道SQL中哪种方法更快。