次のfoo
テーブルがあります。
+----+--------+-------+
| id | name | qty |
+----+--------+-------+
| 1 | John | 3 |
| 2 | John | 1 |
| 3 | Mary | 5 |
| 4 | Mary | 2 |
| 5 | Gary | 3 |
| 6 | Gary | 4 |
| 7 | Gary | 5 |
+----+--------+-------+
id
でグループ化された最小限のname
のQty
とname
のみを選択したいのですが、次のような結果になります。
+----+--------+
| id | name |
+----+--------+
| 2 | John |
| 4 | Mary |
| 5 | Gary |
+----+--------+
私がこれを行うことができた唯一の方法は、次の操作によるものでした:
SELECT id, name FROM (SELECT id, name, MIN(qty) FROM foo GROUP BY name) AS a;
それを行うためのより「美しい」(または冗長性が低い)方法はありますか?
あなたが述べるように、これは副選択なしでは実行できません。
2つのステップが含まれます。
1。名前ごとに、MIN(qty)のレコードを見つけます。
2。そのレコードのIDを返します。
他のアプローチもありますが、2つのステップが残ります。
投稿したクエリに不足している情報があるようです。これで全部です。
SELECT id, name
FROM (
SELECT name, MIN(qty) minqty
FROM foo fs
GROUP BY name
) AS a
JOIN foo f
ON f.name = fs.name
AND f.qty = fs.minqty
クエリは部分グループを使用します。これは、MySQLの古いバージョン(デフォルト設定)で許可されており、おそらく長年にわたって多くの苦痛と不可解なバグを引き起こしています。これが発生する理由を確認します。考慮してください:
select id, name, min(qty) from foo group by name;
+----+------+----------+
| id | name | min(qty) |
+----+------+----------+
| 1 | John | 1 |
| 3 | Mary | 2 |
+----+------+----------+
数量に関連しないIDが結果に表示されるように、なぜですか?名前だけでグループ化しているため、名前ごとに2つのIDを選択できます。 MySQLはこれらのグループからJohnとMaryのIDをランダムに選択します。結果は正しい場合もあれば、正しくない場合もあります。あなたがする必要があるのは、各名前の最小数量を選択し、その数量と名前を使用して、それに関連付けられているIDを見つけることです。 @Kondybasと@ Shooter-McGavinの両方が、回答でこれを行う方法を示しています。
すばらしいですが、クエリが間違った結果を返します。返された行のid
は、最小限のqty
を含む行に関連付けられていません。しかし、あなたはそのような方法で望ましい結果を得ることができます:
SELECT w.id, w.name
FROM foo AS w
JOIN ( SELECT name, MIN(qty) AS qty
FROM foo
GROUP BY name
) AS z ON z.name = w.name
AND z.qty = w.qty
;