压缩SQL查询的结果

时间:2018-12-18 15:43:10

标签: sql sql-server

我有一个查询,可查询指定日期范围内的出勤率数据。我想以某种方式“拼合”数据,以便为每个学生提供一行内容,并统计每个课程的出勤率。我目前的结果看起来像这样

Student Name    PermID      Date        Per1    Per2    Per3    Per4
Student1        11786       2018-12-04   U       U       U       U  
Student2        603697      2018-12-07           U       U                  
Student2        603697      2018-12-10           U       M                  
Student2        603697      2018-12-11           U               L                  
Student2        603697      2018-12-14   U       U       L
Student3        1733        2018-11-27                           L
Student3        1733        2018-12-03                           L

但是我希望结果看起来像这样:

Student Name    PermID      Per1    Per2    Per3    Per4
Student1        11786        1       1       1       1  
Student2        603697       1       4       3       1          
Student3        1733         0       0       0       2

我不在乎结果中的日期,因为我的SQL代码仅回溯30天。这是我的查询示例:

SELECT 
  CONCAT(STU.LN, ', ', STU.FN) AS [Student Name], 
  STU.ID AS [PermID], 
  CONVERT(date,ATT.DT) AS [Date], 
  ATT.A1 AS Per1, 
  ATT.A2 AS Per2, 
  ATT.A3 AS Per3, 
  ATT.A4 AS Per4, 

FROM STU
   LEFT JOIN ATT 
    ON (STU.SN = ATT.SN AND STU.DEL = 0)

WHERE 
  (
  ATT.A1 in ('L', 'M', 'A', 'T', 'U') OR 
  ATT.A2 in ('L', 'M', 'A', 'T', 'U') OR 
  ATT.A3 in ('L', 'M', 'A', 'T', 'U') OR 
  ATT.A4 in ('L', 'M', 'A', 'T', 'U') OR 
  ) AND
  ATT.DT >= GETDATE()-30 AND
  ATT.DT != '2018-10-10' AND
  STU.SP <> 'E'

ORDER BY STU.LN, STU.FN, STU.ID, ATT.DY

是否可以重写此查询以汇总学生每个时期的出勤代码计数,以便将我的数据集展平到每个学生只有1行?

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

我认为这仅需要汇总。假设“空白”值为NULL

with t as (
      <your query here with no order by>
     )
select student_name, permid,
       count(per1) as per1,
       count(per2) as per2,
       count(per3) as per3,
       count(per4) as per4
from t
group by student_name, permid

答案 1 :(得分:2)

您可以将GROUP BYstudentnamepermID一起使用,然后为每个COUNT使用per

;WITH YourData AS
(
    SELECT 
      CONCAT(STU.LN, ', ', STU.FN) AS [Student Name], 
      STU.ID AS [PermID], 
      CONVERT(date,ATT.DT) AS [Date], 
      ATT.A1 AS Per1, 
      ATT.A2 AS Per2, 
      ATT.A3 AS Per3, 
      ATT.A4 AS Per4, 
    FROM STU
       LEFT JOIN ATT 
        ON (STU.SN = ATT.SN AND STU.DEL = 0)
    WHERE 
      (
          ATT.A1 in ('L', 'M', 'A', 'T', 'U') OR 
          ATT.A2 in ('L', 'M', 'A', 'T', 'U') OR 
          ATT.A3 in ('L', 'M', 'A', 'T', 'U') OR 
          ATT.A4 in ('L', 'M', 'A', 'T', 'U') OR 
      ) AND
      ATT.DT >= GETDATE()-30 AND
      ATT.DT != '2018-10-10' AND
      STU.SP <> 'E'
)
SELECT
    T.[Student Name],
    T.PermID,
    Per1 = COUNT(T.Per1),
    Per2 = COUNT(T.Per2),
    Per3 = COUNT(T.Per3),
    Per4 = COUNT(T.Per4)
FROM
    YourData AS T
GROUP BY
    T.[Student Name],
    T.PermID

当您要“展平”时,应该想到GROUP BY。除非所有列未按分组,否则它们将丢失(SQL引擎无法选择要显示的列,因为您正在按组“平整” N行),除非它们在聚合操作中使用,例如COUNT,{ {1}},SUMAVG

您还可以在“变平”之前在这些值上使用表达式,例如:

FIRST_VALUE

答案 2 :(得分:1)

作为对戈登的一个反驳,假设“空白”值是空字符串,则条件聚合应该起作用。

html
{
max-width: 1024px

}