Select

“對於滿足條件 X 的每組結果,僅選擇列值 A 最小的結果”

  • June 22, 2011

我有一個包含數據和日期的表格,如下所示:

DECLARE @p TABLE (P_key int, P_Data char(1), P_ValidUntil datetime)

INSERT @p VALUES (20, 'T', '2003-02-28')
INSERT @p VALUES (21, 'U', '2005-05-31')
INSERT @p VALUES (30, 'V', '2006-09-30')
INSERT @p VALUES (30, 'W', '2008-04-30')
INSERT @p VALUES (31, 'X', '2007-06-30')
INSERT @p VALUES (32, 'Y', '2005-01-31')
INSERT @p VALUES (32, 'Z', '2007-06-30')
INSERT @p VALUES (33, 'A', '2005-06-30')

給定:qKey(只有 10 的倍數),qDate

查找:在第一位匹配 qKey 並且日期大於 qDate 的所有條目。每個 P_key 僅返回一個結果(具有下一個更高 P_ValidUntil 到 qDate 的結果)。

目前的解決方案是:

DECLARE @qKey AS int;
DECLARE @qDate AS datetime;

SET @qKey=30;
SET @qDate='2006-01-01';

SELECT * FROM @p WHERE
@qKey = (P_Key/10)*10
AND @qDate <= P_ValidUntil

返回:

30    V    2006-09-30 00:00:00.000
30    W    2008-04-30 00:00:00.000
31    X    2007-06-30 00:00:00.000
32    Z    2007-06-30 00:00:00.000

這基本上是正確的,除了 30 有兩個條目(都大於@qDate)。我只想要結果中這些多次點擊中的最小日期:

30    V    2006-09-30 00:00:00.000
31    X    2007-06-30 00:00:00.000
32    Z    2007-06-30 00:00:00.000

提前致謝!

第一個解決方法是:

SELECT p2.*
from @p p2
JOIN (
   SELECT min(p_validUntil) Min_P_ValidUntil, P_Key
   FROM @p p
   WHERE @qKey = (P_Key/10)*10
   AND @qDate <= P_ValidUntil
   group BY P_Key
) p3 ON p3.Min_P_ValidUntil = p2.P_ValidUntil AND p3.P_Key = p2.P_Key

謝謝。

使用視窗函式

SELECT
   P_Key, P_Data, P_ValidUntil
FROM
   (
   SELECT
       *,
       ROW_NUMBER() OVER (PARTITION BY P_Key ORDER BY P_ValidUntil) AS rn
   FROM
       @p
   WHERE
      P_Key / @qKey = 1 AND @qDate <= P_ValidUntil
   ) p2
WHERE
  rn = 1

僅供參考:2個答案中使用的兩種技術都很常見,因為這是一個常見問題。此 DBA-SE 問題中的範例:如何獲取 MAX 行

引用自:https://dba.stackexchange.com/questions/3428