T-SQL:基于最大值选择列(其他列)

T-SQL:基于最大值选择列(其他列),sql,sql-server,tsql,greatest-n-per-group,Sql,Sql Server,Tsql,Greatest N Per Group,我希望有一种不使用子查询的简单方法: SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC) FROM TableA WHERE Key = 1 场景:您有“TableA”,其中包含“Key”、“SubKey”和“Value”列。我需要获得给定“键”的最大值(“子键”)的“值” 因此,如果表中包含行: KEY SUBKEY VALUE 1 1 100 1 2 200 1 3 300 对于Key=1,

我希望有一种不使用子查询的简单方法:

SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC)
FROM TableA
WHERE Key = 1
场景:您有“TableA”,其中包含“Key”、“SubKey”和“Value”列。我需要获得给定“键”的最大值(“子键”)的“值”

因此,如果表中包含行:

KEY SUBKEY VALUE
1   1      100
1   2      200
1   3      300
对于Key=1,我需要值300。我希望做这样的事情:

SELECT
  VALUE
FROM
  TableA
WHERE
  Key = 1
HAVING
  SubKey = MAX(SubKey)
但那是不可能的。是否有一种方法可以在不执行“WHERE SubKey=(subselect for max SubKey)”的情况下执行此操作?

使用自联接: 如果存在多个值,这将返回子键值匹配的所有值

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
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
使用RANK&CTE(SQL Server 2005+): 如果存在多个值,这将返回子键值匹配的所有值

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
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
使用行号和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
  SELECT TOP 1
         t.value
    FROM TABLE t
   WHERE t.key = 1
ORDER BY t.subkey DESC
使用TOP: 这将返回一行,即使有多行具有相同的子键值

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
  SELECT TOP 1
         t.value
    FROM TABLE t
   WHERE t.key = 1
ORDER BY t.subkey DESC

我的天哪,小马们用的方法最多。这里还有一个:

SELECT
    T1.value
FROM
    My_Table T1
LEFT OUTER JOIN My_Table T2 ON
    T2.key = T1.key AND
    T2.subkey > T1.subkey
WHERE
    T2.key IS NULL

T2.key唯一为NULL的时间是在左连接中没有匹配项时,这意味着不存在具有较高子键的行。如果有多行具有相同(最高)子键,则会返回多行。

如果您总是希望一个键值只包含一行,而不是一次包含多个键的答案,则所有连接内容都是无用的过度构建。只需使用OMG Ponies已经提供给您的前1个查询。

如果多个键使用CTE:

WITH CTE AS
(
    SELECT key1, key2, MAX(subkey) AS MaxSubkey
    FROM TableA 
    GROUP BY key1, key2
)
SELECT a.Key1, a.Key2, a.Value
FROM TableA a
    INNER JOIN CTE ON a.key1 = CTE.key1 AND a.key2 = CTE.key2 AND
                      a.subkey = CTE.MaxSubkey
's
ROW\u NUMBER
方法在所有情况下都是最有效的方法,因为如果有两个
MAX
值,且返回的记录数相同,并且打破了该
记录集可能提供的插入,则该方法不会失败

缺少的一件事是,当还存在多个键时,如果必须返回与每个max值关联的子键,如何执行此操作。只需将您的
摘要
表与
MIN
“自身”连接起来,就可以开始了

WITH summary AS (
  SELECT t.*,
         ROW_NUMBER() OVER(ORDER BY t.subkey DESC) AS rank
    FROM TABLE t
   WHERE t.key = 1)
SELECT s.*
  FROM summary s
  join  (select key, min(rank) as rank
        from summary
        group by key) sMAX
        on s.key = sMAX.key and r.rank = sMAX.rank

非常简单,无连接,无子查询:

SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC)
FROM TableA
WHERE Key = 1
如果需要每个键的最大值:

SELECT DISTINCT Key, 
FIRST_VALUE(Value) OVER (PARTITION BY Key ORDER BY SubKey DESC)
FROM TableA

由于实际的查询是多个表链接在一起的,因此我最终使用了“selecttop1,ordereddesc”方法,因为这似乎是最容易实现的方法read@John:这很好,但是如果您需要处理每个键的最高值,那么分析版本(排名、行数)会更方便。如果您使用的是SQL Server 2012或更高版本,请参阅以下@Nguyen的答案。这非常适合为每个键拉出一行。