3

複数の列の属性で集計された行のデータを検索したいと考えています。それはおそらく意味不明なことのように聞こえるので、例を挙げましょう...これは3つの列を持つデータベーステーブルです:

GroupingId     Type           Date
1              NULL           1/1/11
1              NULL           2/2/22
2              NULL           1/1/11
2              A              2/2/22
3              A              1/1/11
3              B              2/2/22
4              A              1/1/11
4              NULL           2/2/22

GroupingId で SELECT と GROUP BY を実行したいと思います。それは簡単です。

しかし、他の 2 つの列については、両方の列に実際に依存するものが必要です。特定のグループの最大日付だけが必要な場合、それは簡単です。私が本当に欲しいのは、Type が NOT NULL を優先することですが、Date は MAX である必要がありますが、常に同じ行から取得したいのです (Type 値が NOT NULL を優先します)。

だから私の結果は次のようになるはずです

1       NULL      2/2/22       // both Types are null, so last date chosen
2       A         2/2/22       // one Type not null, so that date chosen
3       B         2/2/22       // both Types not null, so last date chosen
4       A         1/1/11       // one Type not null, so that date chosen (and it is not the most recent date)

私がデートでMAXをしたら、それは正しくありません。Type で COALESCE を実行すると、NULL よりも null 以外の値が得られますが、必ずしも最新の値とは限りません。

これを行うためのきれいな方法はありますか?一連の選択、テーブル変数、およびUNIONを使用してこれを行う方法がわかると思いますが、これは私が前進しようとしている方法ですが、誰かがうなずくことができるクリーンなSQLソリューションがあれば、それは大歓迎です。

私はSQL Serverにいますが、それを行うためのきれいなSQLの方法があれば、おそらくDBにとらわれないだろうと推測しています。

4

2 に答える 2

2

そのような?

;WITH CTESample (GroupingId, Type, Date) AS
(
    SELECT 1, NULL, '1/1/11'    UNION ALL
    SELECT 1, NULL, '2/2/22'    UNION ALL
    SELECT 2, NULL, '1/1/11'    UNION ALL
    SELECT 2, 'A', '2/2/22'     UNION ALL
    SELECT 3, 'A', '1/1/11'     UNION ALL
    SELECT 3, 'B', '2/2/22'     UNION ALL
    SELECT 4, 'A', '1/1/11'     UNION ALL
    SELECT 4, NULL, '2/2/22'    
)
,Partitioned AS
(
    SELECT *
            ,rNum = ROW_NUMBER() OVER (PARTITION BY GroupingID ORDER BY Type DESC, Date DESC)
    FROM CTESample
)
SELECT *
FROM Partitioned
WHERE rNum = 1
于 2013-01-09T21:00:41.597 に答える
1

これはを使用するための候補ですRank()

だから、私は遅すぎる...上司に言わないでください。

とにかく例:

SELECT
  [sub].[GroupingID],
  [sub].[Type],
  [sub].[Date]
FROM
(
  SELECT 
    [GroupingID],
    [Type],
    [Date],
    Rank() OVER(PARTITION BY [GroupingID] ORDER BY (CASE WHEN [Type] IS NULL THEN 0 ELSE 1 END) DESC, [Date] DESC, [Type] ASC) AS [Rank]
  FROM [Data]
) AS [sub]
WHERE [sub].[Rank] = 1
ORDER BY [GroupingID] ASC
于 2013-01-09T20:46:51.087 に答える