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

时间:2022-12-01 12:33:45

I'm hoping there's a simple way to do this without using a sub-query:

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

Scenario: You have "TableA" with columns "Key", "SubKey", and "Value". I need to get the "Value" of the MAX("SubKey") for a given "Key".

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

So if the Table contained the rows:

因此,如果表包含行:

KEY SUBKEY VALUE
1   1      100
1   2      200
1   3      300

For Key = 1, I need the value 300. I was hoping to do something like this:

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

SELECT
  VALUE
FROM
  TableA
WHERE
  Key = 1
HAVING
  SubKey = MAX(SubKey)

But that's a no-go. Is there a way to do this without doing a 'WHERE SubKey = (subselect for max subkey)'?

但那是不行的。有没有办法在不执行'WHERE SubKey =(max subkey的子选择)'的情况下执行此操作?

7 个解决方案

#1


43  

Using a self join:

This will return all the values with subkey values that match, in case there are multiples.

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

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

Using RANK & CTE (SQL Server 2005+):

This will return all the values with subkey values that match, in case there are multiples.

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

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

Using ROW_NUMBER & CTE (SQL Server 2005+):

This will return one row, even if there are more than one with the same subkey value...

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

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

Using TOP:

This will return one row, even if there are more than one with the same subkey value...

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

  SELECT TOP 1
         t.value
    FROM TABLE t
   WHERE t.key = 1
ORDER BY t.subkey DESC

#2


8  

Very simple, no join, no sub-query:

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

SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC)
FROM TableA
WHERE Key = 1

If you need max value for each Key:

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

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

#3


4  

SELECT MAX(Value)
FROM TableA t1
GROUP BY Key, SubKey
HAVING SubKey = (SELECT MAX(SubKey) FROM TableA t2 WHERE t1.Key = t2.Key)
  AND Key = 1

#4


3  

OMG Ponies hit most of the ways to do it. Here's one more:

OMG小马在很多方面都做到了。还有一个:

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

The only time that T2.key will be NULL is when there is no match in the LEFT JOIN, which means that no row exists with a higher subkey. This will return multiple rows if there are multiple rows with the same (highest) subkey.

T2.key将为NULL的唯一时间是LEFT JOIN中没有匹配,这意味着没有行存在更高的子键。如果有多个行具有相同(最高)的子键,则将返回多行。

#5


1  

OMG Ponie's ROW_NUMBER method is the one that will work best in all scenarios as it will not fail in the event of having two MAX values with the same amount returning more records than expected and breaking a possible insert you might have being fed by that recordset.

OMG Ponie的ROW_NUMBER方法是在所有场景中都能发挥最佳效果的方法,因为如果两个具有相同数量的MAX值返回的记录超过预期并且打破了可能由该记录集提供的插入,它将不会失败。

One thing that is missing is how to do it in the event of having to return the subkey associated to each max value, when there are also multiple keys. Simply join your summary table with a MIN and GROUP "itself" and off you go.

缺少的一件事是,当还有多个键时,如果必须返回与每个最大值相关联的子键,该怎么做。只需将您的汇总表与MIN和GROUP“本身”一起加入即可。

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

#6


0  

If you'll always want just one row for one key value rather than the answer for many keys at once, all the join stuff is useless overbuilding. Just use the TOP 1 query OMG Ponies already gave you.

如果你总是只需要一行代表一个键值,而不是一次只需要多个键的答案,那么所有的联接内容都是无用的过度构建。只需使用OMG小马已经给你的TOP 1查询。

#7


0  

In case of multiple keys using a CTE:

如果使用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

#1


43  

Using a self join:

This will return all the values with subkey values that match, in case there are multiples.

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

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

Using RANK & CTE (SQL Server 2005+):

This will return all the values with subkey values that match, in case there are multiples.

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

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

Using ROW_NUMBER & CTE (SQL Server 2005+):

This will return one row, even if there are more than one with the same subkey value...

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

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

Using TOP:

This will return one row, even if there are more than one with the same subkey value...

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

  SELECT TOP 1
         t.value
    FROM TABLE t
   WHERE t.key = 1
ORDER BY t.subkey DESC

#2


8  

Very simple, no join, no sub-query:

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

SELECT FIRST_VALUE(Value) OVER (ORDER BY SubKey DESC)
FROM TableA
WHERE Key = 1

If you need max value for each Key:

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

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

#3


4  

SELECT MAX(Value)
FROM TableA t1
GROUP BY Key, SubKey
HAVING SubKey = (SELECT MAX(SubKey) FROM TableA t2 WHERE t1.Key = t2.Key)
  AND Key = 1

#4


3  

OMG Ponies hit most of the ways to do it. Here's one more:

OMG小马在很多方面都做到了。还有一个:

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

The only time that T2.key will be NULL is when there is no match in the LEFT JOIN, which means that no row exists with a higher subkey. This will return multiple rows if there are multiple rows with the same (highest) subkey.

T2.key将为NULL的唯一时间是LEFT JOIN中没有匹配,这意味着没有行存在更高的子键。如果有多个行具有相同(最高)的子键,则将返回多行。

#5


1  

OMG Ponie's ROW_NUMBER method is the one that will work best in all scenarios as it will not fail in the event of having two MAX values with the same amount returning more records than expected and breaking a possible insert you might have being fed by that recordset.

OMG Ponie的ROW_NUMBER方法是在所有场景中都能发挥最佳效果的方法,因为如果两个具有相同数量的MAX值返回的记录超过预期并且打破了可能由该记录集提供的插入,它将不会失败。

One thing that is missing is how to do it in the event of having to return the subkey associated to each max value, when there are also multiple keys. Simply join your summary table with a MIN and GROUP "itself" and off you go.

缺少的一件事是,当还有多个键时,如果必须返回与每个最大值相关联的子键,该怎么做。只需将您的汇总表与MIN和GROUP“本身”一起加入即可。

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

#6


0  

If you'll always want just one row for one key value rather than the answer for many keys at once, all the join stuff is useless overbuilding. Just use the TOP 1 query OMG Ponies already gave you.

如果你总是只需要一行代表一个键值,而不是一次只需要多个键的答案,那么所有的联接内容都是无用的过度构建。只需使用OMG小马已经给你的TOP 1查询。

#7


0  

In case of multiple keys using a CTE:

如果使用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