1

次の 2 つのクエリを検討してください。

SELECT *, MAX(age) AS maxAge FROM someTable ORDER BY age ASC;
SELECT *, 'dummyC' AS dummyC FROM someTable ORDER BY age ASC;

前者のクエリは、テーブルのすべての行とすべての列に加えて、追加のダミー列を返します。後のクエリは、最小の主キーを持つ行である単一の行のみを返します。それはなぜですか、どうすれば回避できますか? 古いが安定した Debian サーバー上の MySQL 5.1 でテスト済み。

4

3 に答える 3

3

これはMySQL拡張機能です。

MySQLはGROUPBYの使用を拡張して、選択リストがGROUPBY句で指定されていない非集計列を参照できるようにします。これは、前述のクエリがMySQLで有効であることを意味します。この機能を使用すると、不要な列の並べ替えやグループ化を回避して、パフォーマンスを向上させることができます。ただし、これは主に、GROUPBYで指定されていない各非集計列のすべての値が各グループで同じである場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、同じでない限り、選択される値は不確定です。さらに、各グループからの値の選択は、ORDERBY句を追加しても影響を受けません。結果セットのソートは値が選択された後に行われ、ORDERBYはサーバーが選択する値に影響を与えません。

あなたが得る価値は不確定です。多くの場合、テーブルに挿入された最初の行を取得しますが、これは保証されていません。

最も高い年齢を含む行の対応する値が必要な場合は、との組み合わせを使用することをお勧めしORDER BYますLIMIT 1

SELECT *
FROM someTable
ORDER BY age DESC
LIMIT 1;
于 2012-08-15T21:50:24.053 に答える
2

最初のクエリには集計関数 ( MAX) がありますがGROUP BY、ありません。つまり、結果セット全体を集計 (値を収集して結合) し、1 つの行として返します。ほとんどの SQL 方言では、集計されていない列をそのようなクエリに表示することは許可されていませんが、MySQL では明確に許可されています。ただし、これらの非集計列には、MySQL が検出した最初の行 (任意の行) の値が入力されます。問題のテーブルから一度も削除したことがない場合、MySQL は通常、ディスクに格納されているのと同じ順序でテーブルをスキャンするため (少なくともテーブル全体のスキャンが必要な場合)、最小 ID の行を最初に見つけます。DELETEテーブルで一連のステートメントと後続のステートメントを実行するとINSERT、少なくともいくつかのクエリで他の行が取得されます。要するに、特定の行を取得することを期待しないでください。

2 番目のクエリには集計関数がないため、暗黙的なグループ化は実行されません。完全な結果セットが得られるだけです。

于 2012-08-15T21:55:56.850 に答える
1

最初のクエリでは、*は非表示の列です

MySQLドキュメントの引用:

MySQLはGROUPBYの使用を拡張して、選択リストがGROUPBY句で指定されていない非集計列を参照できるようにします。これは、前述のクエリがMySQLで有効であることを意味します。この機能を使用すると、不要な列の並べ替えやグループ化を回避して、パフォーマンスを向上させることができます。ただし、これは主に、GROUPBYで指定されていない各非集計列のすべての値が各グループで同じである場合に役立ちます。

于 2012-08-15T21:49:38.530 に答える