0

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

例如:

        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) 因为在每种情况下都有很多可能性,并且查询中的任何内容都没有明确说明为每个组中的状态选择哪个值。反正有使用内部联接吗?

4

5 回答 5

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
于 2013-05-06T05:47:57.133 回答
1

It just means that you need to put all non-aggregated columns in the GROUP BY clause, so in the case you need to put the other one

Select  Name , 
        MAX(DATE) as Date ,
        Status
FROM    [ST].[dbo].[PS_RC_STATUS_TBL] PS
Group   by Name, Status
于 2013-04-19T11:40:33.407 回答
1

SQL Server 需要知道如何处理未分组的行(它在 1 行上显示多行 - 那么如何?)。如果您对它们进行了聚合(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 的方法也是如此。

或者

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 示例

于 2013-05-05T22:28:20.943 回答
1

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

"" < " " < "a"

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

  • 在主查询中加入 StatusOrder 关系(*Status,OrderSequence)
  • 在聚合查询中选择Max(OrderSequence);和
  • 加入 OrderSequence 上的 StatusOrder 关系选择正确的 Status 值进行显示。
于 2013-05-06T01:24:35.370 回答
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 子句之后提及。否则会抛出错误。

于 2016-03-24T04:03:33.027 回答