列在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中

时间:2013-04-19 11:37:39

标签: sql sql-server group-by

我正在尝试按名称选择最新日期和分组,并保留其他列。

例如:

        name  status  date
        -----------------------
         a    l       13/19/04
         a    n       13/09/05
         a    dd      13/18/03
         b    l       13/01/01
         b    dd      13/01/02
         b    n       13/01/03

我希望结果如下:

        name status date
        -----------------
          a    n      13/09/05
          b    n      13/01/03

这是我的代码

SELECT
    Name,
    MAX(DATE) as Date,
    Status
FROM
    [ST].[dbo].[PS_RC_STATUS_TBL] 
GROUP BY 
    Name

我知道我应该放置max(status)因为每种情况都有很多可能性,查询中没有任何内容可以清楚地说明在每个组中为状态选择哪个值。无论如何使用内连接?

5 个答案:

答案 0 :(得分:2)

我不清楚你想要最大或最小状态。相反,在我看来,你想要一个确定日期的名称和状态。也就是说,您希望每个名称的行具有最新日期。所以要求:

select * from PS_RC_STATUS_TBL as T
where exists (
      select 1 from PS_RC_STATUS_TBL
      where name = T.name
      group by name
      having max(date) = T.date
)

考虑它的另一种方法是

select T.* 
from PS_RC_STATUS_TBL as T
join (
      select name, max(date)  as date
      from PS_RC_STATUS_TBL
      group by name
) as D
on T.name = D.name
and T.date = D.date

答案 1 :(得分:1)

这只是意味着您需要将所有非聚合列放在GROUP BY子句中,因此在您需要放置另一个

的情况下
Select  Name , 
        MAX(DATE) as Date ,
        Status
FROM    [ST].[dbo].[PS_RC_STATUS_TBL] PS
Group   by Name, Status

答案 2 :(得分:1)

SQL Server需要知道如何处理您没有分组的行(它有多行显示在一行 - 所以如何?)。如果您已对它们进行汇总(MINMAXAVG等),那么您将告诉它如何处理这些行。如果不是,它将不知道该怎么做 - 并会给你一个错误,就像你得到的那样。

根据你所说的话 - 听起来好像你想按状态分组。听起来你根本就不感兴趣。让我知道如果这个假设是错误的。

SELECT
    Name,
    MAX(Date) AS 'Date',
FROM
    PS_RC_STATUS_TBL
GROUP BY
    Name

如果你真的想要这个状态,但又不想对它进行分组 - 试试这个:

SELECT 
    MyTable1.Name,
    MyTable2.Status,
    MyTable1.Date
FROM
   (SELECT Name, MAX(Date) AS 'Date' FROM PS_RC_STATUS_TBL GROUP BY Name) MyTable1
     INNER JOIN 
   (SELECT Name, Date, Status FROM PS_RC_STATUS_TBL) MyTable2
     ON MyTable1.Name = MyTable2.Name 
    AND MyTable1.Date = MyTable2.Date

这给出了您要求的确切结果 - 以下方法使用CTE也是如此。

OR

WITH cte AS (
    SELECT Name, MAX(Date) AS Date 
      FROM PS_RC_STATUS_TBL
  GROUP BY Name)

SELECT cte.Name,
       tbl.Status,
       cte.Date
  FROM cte INNER JOIN 
     PS_RC_STATUS_TBL tbl ON cte.Name = tbl.Name 
                         AND cte.Date = tbl.Date

SQLFiddle example

答案 3 :(得分:1)

这是SQL聚合方案中文本字段的常见问题。在字段列表中使用MAX(状态)或MIN(状态)是一种解决方案,通常是MAX(状态),因为词汇排序:

"" < " " < "a"

如果您确实需要更详细的订购:

  • 在主查询中加入StatusOrder关系(* Status,OrderSequence);
  • 在汇总查询中选择 Max(OrderSequence);和
  • OrderSequence 上加入StatusOrder关系,选择正确的状态值进行显示。

答案 4 :(得分:0)

除了聚合功能之外,您选择的是哪个字段,需要在group by子句中提及。

SELECT 

gf.app_id,
ma.name as name,
count(ma.name) as count

FROM [dbo].[geo_fen_notification_table]  as gf 
inner join dbo.mobile_applications as ma on gf.app_id = ma.id

GROUP BY app_id,name

这里我在select中访问app_id和name,所以我需要在group by子句之后提及。否则会引发错误。