:
SELECT
cGift.gidnumb,
cGift.id,
cGift.date,
first.isfirst
FROM cGift
LEFT JOIN (
SELECT id, MIN(date) AS date, 't' AS isfirst
FROM cGift
GROUP BY id
) first ON cGift.id = first.id AND cGift.date = first.date
UPDATE(アドレス指定の基準を追加):
人がで複数回寄付する場合その後、
ある
SELECT
cGift.gidnumb,
cGift.id,
cGift.date,
first.isfirst
FROM cGift
LEFT JOIN (
SELECT
MIN(g.gidnumb) AS g.gidnumb,
g.id,
g.date,
't' AS isfirst
FROM cGift g
INNER JOIN (
SELECT id, MIN(date) AS date
FROM cGift
GROUP BY id
) f ON g.id = f.id AND g.date = f.date
GROUP BY g.id, g.date
) first ON cGift.id = first.id AND cGift.date = first.date
、最も内側のクエリは、前の溶液中でのように、すべての人のための最低限の日数を見つけ、しかし:は、あなたが唯一の寄付がt
でマークしたい、あなたは、例えば、これを行うことができます特定のgidnumb
値を持つリストについても詳細を示し、cGift
テーブルのこのリストと1人あたり1行だけ一致するようにします。
このクエリは、どのDBMSでも実行可能でなければなりません。二重のグループ分けを考えれば、それほど効率が悪いかもしれません。ここではまた、唯一の標準SQLを使用して代替が、何のベンダー固有の機能は、(それはまた、前のクエリよりも少し柔軟であるべきではありません)です。
SELECT
gidnumb,
id,
date,
CASE
WHEN NOT EXISTS (
SELECT *
FROM cGift
WHERE id = g.id
AND (
date < g.date OR
date = g.date AND gidnumb < g.gidnumb
)
)
THEN 't'
END AS isfirst
FROM cGift g
あなたが見ることができるように、isfirst
列を使用して計算されますテーブルのセルフテスト:このテーブルに同じid
とそれより前の日付の行がない場合、または同じ日付の場合はgidnumb
より小さく、この行にはt
とマークする必要があります。の一部がなく、CASE
の部分には、ELSE NULL
が含まれます。できれば、ELSE 'f'
のようなものを追加してください。
しかし、SQL製品には、よりシンプルで効率的なクエリを構築することで恩恵を受ける可能性のある機能がある可能性があります。
SELECT
gidnumb,
id,
date,
CASE ROW_NUMBER() OVER (PARTITION BY id ORDER BY date, gidnumb)
WHEN 1
THEN 't'
END AS isfirst
FROM cGift g
:一部の製品は、例えば、ランキング機能をサポートここでは(あまりにもすでにSQL標準の一部であり、それは彼らが普遍的にまだサポートされていないだけということだ)、そしてあなたがROW_NUMBER()
呼ばランキング機能で何ができるかですこのクエリは、それらをに分割し、最初にdate
、次にgidnumb
でソートする行をランク付けします。この場合のランクが1
のすべての行は、t
と区別する必要があります。
ありがとう、これは完全にうまくいった – slicedtoad
OK、1つは間違っていました。どうやら、同じ日に2回以上寄付をした人がいたため、複数のisfirst = 't'を持つ人々が生まれました。 min()の2番目の基準としてgidnumb(常にユニーク)を使用できますか?私は試みましたが、私はグループ化と結合に問題があります。注:gidnumbは必ずしも日付順ではないので、 'min(date)'の代わりに 'min(gidnumb)'だけを使うことはできません。 – slicedtoad
@slicedtoad:私の更新を見てください。 –