8

让我们假设下表:

Name             SubName        Message    Time
USA             MA              M1         1
USA             NY              M2         2
USA             WA              M3         3
USA             MA              M4         4
USA             WA              M5         5
USA             NY              M6         6
FIN             HEL             M7         7
FIN             TAM             M8         8
FIN             HEL             M9         9

我想要一个 SQL 查询,它将返回以下内容:

Name             SubName        Message    Time
FIN              HEL            M9         9
FIN              TAM            M8         8
USA              NY             M6         6
USA              WA             M5         5
USA              MA             M4         4

所以 a ORDER BY time DESC,它按不同的名称分组,并按不同的子名称分组。

这可能吗?我正在寻找一种不是特定于 DBMS 的解决方案 - 可以在大多数 DBMS 中运行的解决方案。

4

6 回答 6

6

您没有标记您的 RDBMS,因此ANSI-SQL您可以使用大多数 RDBMS ROW_NUMBER()

SELECT s.* FROM (
    SELECT t.*,
           ROW_NUMBER() OVER(PARTITION BY t.name,t.subname ORDER BY t.time DESC) as rnk
    FROM YourTable
    ) s
WHERE s.rnk = 1
ORDER BY s.time DESC,s.name

编辑:这是 Core ANSI SQL 的答案,它应该适用于您可以使用的任何数据库NOT EXISTS()

SELECT * FROM YourTable t
WHERE NOT EXISTS(SELECT 1 FROM YourTable s
                 WHERE t.name = s.name and t.subname = s.subname
                   AND s.time > t.time)
于 2016-08-10T12:59:36.493 回答
5
SELECT * FROM 
#TEMP T1 WHERE TIME=
(SELECT MAX(TIME) FROM #TEMP T2
WHERE T1.NAME=T2.NAME AND T2.SUBNAME=T1.SUBNAME)

输出:

Name    SubName Message Time
USA       WA    M5       5
USA       NY    M6       6
USA       MA    M4       4
FIN       TAM   M8       8
FIN       HEl   M9       9
于 2016-08-10T13:09:36.450 回答
4

如果您的 dbms 不支持 ANSI SQL 的扩展 T611,基本 OLAP 操作:

select t1.*
from tablename t1
  join (select name, subname, max(Time) maxtime
        from tablename
        group by name, subname)
   on t1.name = t2.name and
      t1.subname = t2.subname and
      t1.time= t2.maxtime
order by name, subname, time desc

使用 Core SQL-2003 之外的以下功能:F591,“派生表”

请注意,ANSI SQL 具有time保留字,因此您可能需要将其分隔为"time".

于 2016-08-10T13:11:29.033 回答
3

您可以分两步执行此操作。首先为每个name/subname组合选择最好的。然后订购它们。在大多数数据库中,您可以使用row_number()第一部分:

select t.*
from (select t.*,
             row_number() over (partition by t.name, t.subname order by time desc) as seqnum
      from t
     ) t
order by time desc;
于 2016-08-10T13:01:29.330 回答
3

可以使用ROW_NUMBER()WHERE s.rank = 1通过分区获取每个组中的第一条记录:

SELECT s.Name,s.SubName,s.Message, s.Time
FROM (
    SELECT t.*,
           ROW_NUMBER() OVER(PARTITION BY t.Name, t.SubName ORDER BY t.Time DESC) as rank
    FROM YourTable t) s
WHERE s.rank = 1
ORDER BY s.Time DESC
于 2016-08-10T13:01:35.587 回答
1

我没有对此进行测试,但我认为这应该可行:

select
    t1.name as name,
    t1.subname as subname,
    (select max(t2.message) from table t2 where t2.name = t1.name and t2.subname = t1.subname) as message,
    (select max(t2.time) from table t2 where t2.name = t1.name and t2.subname = t1.subname) as time
from
    table t1
group by
    t1.name,
    t1.subname
order by
    t1.name
于 2016-08-10T17:55:00.003 回答