替代 SQL GROUPBY(例如避免在聚合字段上重复)

问题描述 投票:0回答:5

有没有办法让查询返回 8 个字段,但仅按一个字段进行分组,并对另一字段仅执行一个聚合函数? 我收到一个错误,表明我需要按没有聚合函数的所有字段进行分组。

我需要查找每个月已完成的调查数量,但需要包含其他信息,例如会话开始时间、会话状态、会话 ID 等。

当我尝试执行此操作时:

SELECT Datepart("m", starttime), 
       COUNT(sessionid), 
       sessionstatus, 
       starttime, 
       endtime, 
       surveyid, 
       surveybook, 
       userdesk 
FROM   survey_sessions 
GROUP  BY Datepart("m", starttime) 

我收到错误: “您尝试执行一个不包含指定表达式“SessionStatus”作为聚合函数一部分的查询”

我不需要任何其他聚合,并且按剩余字段分组并不能让我获得每月总计。

sql group-by
5个回答
3
投票

如果您使用 GROUP BY,则无论如何都必须将所有选定的字段包含在 GROUP BY 中。

如果您将所有内容都包含在 group by 子句中,您可能不会得到您期望的结果,因为我假设在对这么多列进行分组时,每一行几乎都是唯一的。

假设您正在使用 SQL Server 可以尝试:

SELECT Datepart("m", starttime), 
   COUNT(sessionid) OVER(PARTITION BY Datepart("m", starttime)) AS Count, 
   sessionstatus, 
   starttime, 
   endtime, 
   surveyid, 
   surveybook, 
   userdesk 
FROM   survey_sessions 

这将显示您正在查找的所有信息,并在每行显示该月中发生的信息数。

我不是 100% 确定你想要完成什么,所以很难更具体。

编辑:添加替代访问解决方案。

如果您也需要它在访问中工作,您可以尝试以下操作。将 '' 替换为与第一个查询返回的数据类型对应的数字、日期或字符串。这会将行放在查询的底部,其中包含每月的总计。

SELECT Datepart("m", starttime), 
   0 AS COUNT
   sessionstatus, 
   starttime, 
   endtime, 
   surveyid, 
   surveybook, 
   userdesk 
FROM   survey_sessions 

UNION ALL 

SELECT Datepart("m", starttime),
   COUNT(sessionid) as Count,
   '',
   '',
   '',
   '',
   '',
   ''
FROM survey_sessions
GROUP BY Datepart("m", starttime)

1
投票

既然搜索错误消息指向MS-Access,最简单的方法就是先使用

SELECT Datepart("m", starttime), 
       COUNT(sessionid), 
       FIRST(sessionstatus), 
       FIRST(starttime), 
       FIRST(endtime), 
       FIRST(surveyid), 
       FIRST(surveybook), 
       FIRST(userdesk) 
FROM   survey_sessions 
GROUP  BY Datepart("m", starttime) 

如果您想模拟

COUNT OVER
,您可以使用内联视图(使用两个,因为我认为表达式在 Access SQL 中不起作用

 SELECT 
         main.Month,
         q.Kount,
         main.sessionstatus, 
         main.starttime, 
         main.endtime, 
         main.surveyid, 
         main.surveybook, 
         main.userdesk,
         main.sessionstatus
   FROM
    (SELECT Datepart("m", s.starttime) month, 

       s.sessionstatus, 
       s.starttime, 
       s.endtime, 
       s.surveyid, 
       s.surveybook, 
       s.userdesk 
      FROM   survey_sessions) main 
     INNER JOIN (SELECT Datepart("m", starttime) [MONTH],
                         COUNT(sessionid) kount
                   FROM survey_sessions 
                   GROUP BY Datepart("m", starttime)) q
       ON main.month = q.month

0
投票

您正在对一列进行分组,但 SELECT 子句中有多个列...


0
投票

GROUP BY
子句中包含所有非聚合列并没有什么坏处。通常,它只是从选择列中进行简单的复制和粘贴。从语法上来说,它有点重复,但它产生相同的结果。您的新查询:

SELECT 
     Datepart("m", starttime) 
    ,COUNT(sessionid)
    ,sessionstatus
    ,starttime
    ,endtime
    ,surveyid
    ,surveybook 
    ,userdesk 
FROM survey_sessions 
GROUP BY 
     Datepart("m", starttime)
    ,sessionstatus
    ,starttime
    ,endtime
    ,surveyid
    ,surveybook 
    ,userdesk 

0
投票

我知道这个已经很老了,但你可以在 2008 年之后做到这一点

SELECT 
     Datepart("m", starttime) 
     Grouping(sessionid) 
    ,COUNT(sessionid)
    ,sessionstatus
    ,starttime
    ,endtime
    ,surveyid
    ,surveybook 
    ,userdesk 
FROM survey_sessions 
GROUP BY sessionid WITH ROLLUP;

它对我对微软或分组

的解释有用
© www.soinside.com 2019 - 2024. All rights reserved.