SQL:個別の行を選択しながら、1つのフィールドの最小値でグループ化
これが私がやろうとしていることです。このテーブルtがあるとしましょう:
id | record_date | other_cols
18 | 2011-04-03 | x
18 | 2012-05-19 | y
18 | 2012-08-09 | z
19 | 2009-06-01 | a
19 | 2011-04-03 | b
19 | 2011-10-25 | c
19 | 2012-08-09 | d
各IDについて、最小のrecord_dateを含む行を選択します。だから私は得るだろう:
id | record_date | other_cols
18 | 2011-04-03 | x
19 | 2009-06-01 | a
この問題について私が見た唯一の解決策は、すべてのrecord_dateエントリが異なることを前提としていますが、私のデータではそうではありません。 2つの条件でサブクエリと内部結合を使用すると、一部のIDに対して行が重複しますが、これは望ましくありません。
id | record_date | other_cols
18 | 2011-04-03 | x
19 | 2011-04-03 | b
19 | 2009-06-01 | a
のようなものはどうですか
SELECT mt.*,
FROM MyTable mt INNER JOIN
(
SELECT ID, MIN(Record_Date) MinDate
FROM MyTable
GROUP BY ID
) t ON mt.ID = t.ID AND mt.Record_Date = t.MinDate
これにより、IDごとの最小日付が取得され、それらの値に基づいて値が取得されます。重複するのは、同じIDに重複する最小record_datesがある場合のみです。
mysql でこれを行うだけで、期待どおりの結果が得られます。
SELECT id, min(record_date), other_cols
FROM mytable
GROUP BY id
これはあなたのために働きますか?
各カテゴリで最も安い製品を取得するには、次のように相関サブクエリでMIN()関数を使用します。
SELECT categoryid,
productid,
productName,
unitprice
FROM products a WHERE unitprice = (
SELECT MIN(unitprice)
FROM products b
WHERE b.categoryid = a.categoryid)
外部クエリは、製品テーブル内のすべての行をスキャンし、相関サブクエリによって返される各カテゴリの最低価格と一致する単価を持つ製品を返します。
firstアイテムは必要ないが、たとえばサブクエリでrownumberを使用して、結果セットのベースにすることができる2番目の番号を言う場合、ここで他の回答のいくつかに追加したいと思いますそれ。
SELECT * FROM
(
SELECT
ROW_NUM() OVER (PARTITION BY Id ORDER BY record_date, other_cols) as rownum,
*
FROM products P
) INNER
WHERE rownum = 2
これにより、サブクエリ内の複数の列を並べ替えることもできます。これは、2つのrecord_dateの値が同じ場合に役立ちます。必要に応じて、カンマで区切ることにより、複数の列を分割することもできます
これは単にそれを行います:
select t2.id,t2.record_date,t2.other_cols
from (select ROW_NUMBER() over(partition by id order by record_date)as rownum,id,record_date,other_cols from MyTable)t2
where t2.rownum = 1
以下のクエリは、各作業指示書の最初の日付を取得します(すべてのステータス変更を示すテーブル内):
SELECT
WORKORDERNUM,
MIN(DATE)
FROM
WORKORDERS
WHERE
DATE >= to_date('2015-01-01','YYYY-MM-DD')
GROUP BY
WORKORDERNUM
これは古い質問ですが、これは誰かに役立ちます私の場合、私は大きなクエリを持っているので、サブクエリを使用できませんクエリ。私はMysqlを使用しています
select t.*
from (select m.*, @g := 0
from MyTable m --here i have a big query
order by id, record_date) t
where (1 = case when @g = 0 or @g <> id then 1 else 0 end )
and (@g := id) IS NOT NULL
基本的に、結果を順序付けしてから、各グループの最初のレコードのみを取得するために変数を配置しました。