-2

250 レコードを返す次のクエリがあります。

SELECT DISTINCT p.* FROM Persons AS p
                      INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId 
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
                      LIMIT 240,10;

-- Returns 198 records
SELECT DISTINCT p.* FROM Persons AS p
                      INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId 
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')

-- Returns 250 records. Why?
SELECT DISTINCT COUNT(*) FROM Persons AS p
                      INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId 
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')

上記を実行すると、合計 250 のレコードがあるにもかかわらず、レコードが表示されません。LIMITを に変更したときにのみレコードが返され始めLIMIT 197,10、レコードの 1 つが表示されます。

なぜこうなった?

4

3 に答える 3

1

カウントの場所が間違っています。すべての行 (250) を数え、個別の行の値を選択します。250 である 1 つの行しかありません。

あなたが意味したのは select count(distinct p.*) で、これは 198 を返します

于 2013-08-02T22:38:26.353 に答える
0

デフォルトの順序はASC

順序を逆にして、そのようなレコードを 10 個だけ取得してみてください

     Order by RAND ()  LIMIT 10

ORDER BY がない場合、デフォルトのソート順はありません。 したがって、順序が指定されていない場合はランダムであり、位置 240 を設定せずに 10 レコードを単純に制限できます。

編集:

 SELECT  COUNT(*) as counts FROM Persons AS p
                  INNER JOIN Colors AS c ON c.ColorId = p.FavoriteColorId 
 WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED','BLUE','YELLOW')
 GROUP BY c.Id ORDER BY c.Id LIMIT 240,10
于 2013-08-02T20:12:56.077 に答える
0

質問を読み直しましたが、どのクエリが何を返しているのかわかりません。

期待されること:

  • 最初のクエリ: 行が返されません (198 行のみ、スキップする 240 行はありません)

  • 2 番目のクエリ: 198 行が返されました。

  • 3 番目のクエリ: 値が 250 の 1 行を返しますが、これも妥当です。

それがあなたが見ている行動であるなら、これはすべて予想されることです。

DISTINCT 演算子は重複する行を削除します。これにより、198 と 250 の違いが説明されます。実行計画の最後のステップ (またはほぼ最後のステップ) として LIMIT が適用されるため、最初のクエリで行が返されない理由が説明されます。

2 番目のクエリによって返される 198 行の数を取得するには、2 番目のクエリ (198 行を返す) を別のクエリでラップし、そこから COUNT を取得するのが簡単な方法の 1 つです。

SELECT COUNT(1) AS mycount
  FROM (
         SELECT DISTINCT p.*
           FROM Persons p
           JOIN Colors c
             ON c.ColorId = p.FavoriteColorId
            AND c.ColorName IN ('RED','BLUE','YELLOW')
          WHERE p.Name = 'John Doe'
       ) q

PersonsPersons テーブルから重複を排除せずに、テーブルから行数を取得したい場合、それを取得する 1 つの方法は次のとおりです。

SELECT COUNT(1) AS mycount
  FROM Persons p
 WHERE p.Name = 'John Doe'
   AND EXISTS ( SELECT 1 
                  FROM Colors c
                 WHERE c.ColorName IN ('RED','BLUE','YELLOW')
                   AND c.ColorId = p.FavoriteColorId
              )

たとえば、 Persons テーブルに UNIQUE で NOT NULL の列が 1 つある場合、次のid INT PRIMARY KEYようにすることができます。

SELECT COUNT(DISTINCT p.id) AS mycount
  FROM Persons p
  JOIN Colors c 
    ON c.ColorName IN ('RED','BLUE','YELLOW')
   AND c.ColorId = p.FavoriteColorId
 WHERE p.Name = 'John Doe'

元の答え

その最初のクエリは 10 行以下を返す必要があります。

2 番目のクエリが 198 行を返すことを報告します。その最初のクエリ (LIMIT 句の追加を除いてこれと同じ) がどのように行を返す必要があるのか​​ わかりません。

3 番目のクエリは、単一の行を返す必要があります。

あなたが見ている結果についての良い説明はありません。

Q使用しているクライアント アプリケーションでの動作を除外するためだけに、msyql コマンド ライン クライアントでこの動作を再現できますか?

Q実行している MySQL のバージョンは何ですか? (これは、MySQL のバージョンのバグである可能性があります。)

Qこれらのテーブルはどのエンジン (MyISAM、InnoDB) を使用していますか?

Qテーブルが と一致していることを確認しましたCHECK TABLE tablename EXTENDEDか?

Qまた、クエリの実行中に他のプロセスが行を挿入、更新、および/または削除していないことを確認しましたか?

LIMIT最初のクエリは、句を指定するという点で少し奇妙ですが、行が返される順序を規定するGROUP BYor句やその他のものはありません。ORDER BY

DISTINCT3 番目のクエリは、キーワードが必要ないという点で少し奇妙です。句がない場合、単一の行が返されるGROUP BYことを期待しています。SELECT COUNT(*)

私の一部は、観察された行動の報告が正確かどうか疑問に思っています。その 3 番目のクエリは実際に 250 行を返しているのでしょうか、それともカウントの値が 250 の単一の行を返しているのでしょうか? (これらは 2 つの非常に異なるものです。)

通常、演算子が重複行を削除する場合、 a が返す行数よりも大きなSELECT COUNT(*)値を返すことが期待されます。SELECT DISTINCT p.*DISTINCT

于 2013-08-02T22:01:25.070 に答える