T-SQL:根据MAX选择列(其他列)

Joh*_*ohn 36 sql t-sql sql-server greatest-n-per-group

我希望有一种简单的方法可以在不使用子查询的情况下执行此操作:

场景:您有"TableA",其中包含"Key","SubKey"和"Value"列.对于给定的"Key",我需要获得MAX("SubKey")的"Value".

因此,如果表包含行:

KEY SUBKEY VALUE
1   1      100
1   2      200
1   3      300
Run Code Online (Sandbox Code Playgroud)

对于Key = 1,我需要值300.我希望做到这样的事情:

SELECT
  VALUE
FROM
  TableA
WHERE
  Key = 1
HAVING
  SubKey = MAX(SubKey)
Run Code Online (Sandbox Code Playgroud)

但那是不行的.有没有办法在不执行'WHERE SubKey =(subselect for max subkey)'的情况下执行此操作?

OMG*_*ies 57

使用自联接:

如果存在倍数,这将返回匹配的子键值的所有值.

SELECT a.value
  FROM TABLE a
  JOIN (SELECT MAX(t.subkey) AS max_subkey
          FROM TABLE t
         WHERE t.key = 1) b ON b.max_subkey = a.subkey
 WHERE a.key = 1
Run Code Online (Sandbox Code Playgroud)

使用RANK&CTE(SQL Server 2005+):

如果存在倍数,这将返回匹配的子键值的所有值.

WITH summary AS (
  SELECT t.*,
         RANK() OVER(ORDER BY t.subkey DESC) AS rank
    FROM TABLE t
   WHERE t.key = 1)
SELECT s.value
  FROM summary s
 WHERE s.rank = 1
Run Code Online (Sandbox Code Playgroud)

使用ROW_NUMBER&CTE(SQL Server 2005+):

这将返回一行,即使有多个具有相同的子键值...

WITH summary AS (
  SELECT t.*,
         ROW_NUMBER() OVER(ORDER BY t.subkey DESC) AS rank
    FROM TABLE t
   WHERE t.key = 1)
SELECT s.value
  FROM summary s
 WHERE s.rank = 1
Run Code Online (Sandbox Code Playgroud)

使用TOP:

这将返回一行,即使有多个具有相同的子键值...

  SELECT TOP 1
         t.value
    FROM TABLE t
   WHERE t.key = 1
ORDER BY t.subkey DESC
Run Code Online (Sandbox Code Playgroud)


Ngu*_*ong 22

很简单,没有连接,没有子查询:

SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC)
FROM TableA
WHERE Key = 1
Run Code Online (Sandbox Code Playgroud)

如果您需要每个密钥的最大值:

SELECT DISTINCT Key, 
FIRST_VALUE(Value) OVER (PARTITION BY Key ORDER BY SubKey DESC)
FROM TableA
Run Code Online (Sandbox Code Playgroud)

  • FIRST_VALUE适用于SQL Server 2012+ (3认同)
  • 对于第二个示例,您可以使用命名窗口获取多个列。https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html (2认同)