web-dev-qa-db-ja.com

行に最大日付があるテーブルから情報を選択します

私のテーブルは次のようになります。

group    date      cash  checks
  1    1/1/2013     0      0
  2    1/1/2013     0      800
  1    1/3/2013     0      700
  3    1/1/2013     0      600
  1    1/2/2013     0      400
  3    1/5/2013     0      200

-そのテーブルに詳細な情報があることを示すだけで現金は必要ありません

日付が最大でチェックが0より大きい各一意のグループを取得したいので、戻り値は次のようになります。

group    date     checks
  2    1/1/2013    800
  1    1/3/2013    700
  3    1/5/2013    200

試みたコード:

SELECT group,MAX(date),checks
    FROM table
    WHERE checks>0
    GROUP BY group
    ORDER BY group DESC

問題は、最大日付行だけでなく、すべての日付とチェックを提供することです。

ms SQL Server 2005を使用する

42
kqlambert
SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group

これは、最大日付を取得するために機能します。他の列を取得するためにデータに結合します:

Select group,max_date,checks
from table t
inner join 
(SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group)a
on a.group = t.group and a.max_date = date

内部結合は、最大レコードのみを取得するフィルターとして機能します。

参考までに、列名はひどいものです。列(グループ、日付、表)に予約語を使用しないでください。

113
Twelfth

次のように window MAX()を使用できます。

SELECT
  *, 
  max_date = MAX(date) OVER (PARTITION BY group)
FROM table

他のデータと一緒にgroupごとに最大日付を取得するには:

group  date      cash  checks  max_date
-----  --------  ----  ------  --------
1      1/1/2013  0     0       1/3/2013
2      1/1/2013  0     800     1/1/2013
1      1/3/2013  0     700     1/3/2013
3      1/1/2013  0     600     1/5/2013
1      1/2/2013  0     400     1/3/2013
3      1/5/2013  0     200     1/5/2013

上記の出力を派生テーブルとして使用すると、datemax_dateと一致する行のみを取得できます。

SELECT
  group,
  date,
  checks
FROM (
  SELECT
    *, 
    max_date = MAX(date) OVER (PARTITION BY group)
  FROM table
) AS s
WHERE date = max_date
;

望ましい結果を得るために。

基本的に、これは @ Twelfthの提案 に似ていますが、結合を回避するため、より効率的です。

メソッド SQL Fiddleで を試すことができます。

26
Andriy M

このようにjoinを使用できます。 INを使用する場合、これを回避しようとすると実行速度が遅くなります。

    SELECT *  FROM (SELECT  msisdn, callid, Change_color, play_file_name, date_played FROM insert_log
   WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
 ORDER BY callid ASC) t1 JOIN (SELECT MAX(date_played) AS date_played FROM insert_log GROUP BY callid) t2 ON t1.date_played=t2.date_played
1
SELECT distinct
  group, 
  max_date = MAX(date) OVER (PARTITION BY group), checks
FROM table

動作するはずです。

0
Heather WWW