2012-03-29 6 views
5

すべての行を選択するMySqlステートメントと、その行の合計行数が必要です。MySqlは行数を余分な列として選択していますか?

私は...

mysql_query("SELECT * FROM posts LIMIT 0, 5"); 

を使用して、カウントを追加しようとしていた。

mysql_query("SELECT *, COUNT(*) AS total FROM posts LIMIT 0, 5"); 

を...しかし、それは、単一の行を返します。

また、各行に余分な列を追加するよりも合計を取得する方が良い場合は、代わりにその列を使用してください。ありがとうございました!

+2

PHPを使用している場合は、mysql_num_rowsを使用しないでください。 – hjpotter92

+1

@ hjpotter92しかし、それはOPの「トータル」が何であるかによって異なります。現在選択されている合計( 'mysql_num_rows'は正常です)またはテーブル全体の行数です。 –

+0

良い点、@Michal。私は答えの両方のケースに取り組んだ。 –

答えて

9

は私は、MySQLのすべての行を選択します声明だけでなく、どのように多くの合計行があるが必要です。

文字通り取られた場合、これは不可能です。 SQLクエリの結果は(仮想)テーブルです。その結果表の各行の列は、その行にのみ関連する値を提供し、行は実質的に互いに独立しています。

結果全体の行数を取得するには多くの方法がありますが、2つのステートメントまたは概念的に異なるクエリを使用して実行します。

など

があるどのように多くの合計行これは、どちらかの意味するかもしれない:(以下ソリューションズ)

1つの複数の方法で解釈することができ、あなたの元の質問で側面があります:

  1. 結果に返された各ローをカウントします。
  2. (私は両方の以下のための答えを考え出すだろう)それは(この場合は5行に結果を切り捨て)LIMIT句

のためではなかった場合に返されたであろう各行をカウント

しかし、それはただ1つの行を返します。 COUNT(*)は各行で同じになるため、何らかの理由でMySqlが一意の値を持つ行のみを返すためです。私は見当もつかない。

COUNTは集約関数です。集計関数を使用することによって、データベースに行のグループを束ね、その一部を単一の行に投影するように要求しています。混乱しているのは、mysqlは非集約式と集約式を同じSELECTリストに混ぜることです。他のほとんどのデータベースではこれを許可せず、このエラーを出力しますが、MySQLはそうではありません。

ただし、COUNT(*)はすべての行を1つの行に集約します。これは行グループ全体を表します。

さらに、各行に余分な列を追加するよりも合計を取得する方が良い場合は、代わりにその行を入力してください。ありがとうございました!

はい、いくつかの方法があります。

PHPに返される行の数を取得する場合は、MySQLが制限句を適用した後に、mysql_query呼び出し後にPHP関数mysql_num_rowshttp://www.php.net/manual/en/function.mysql-num-rows.php)を呼び出すことをおすすめします。

LIMIT句がない場合に返される行の数を取得する場合は、2段階で実行することをお勧めします。最初に、元のクエリのスローモディファイしたバージョンを実行してから直後それは、MySQLのFOUND_ROWS関数を呼び出します。それは次のようになります

http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_found-rowsを参照してください):

$result = mysql_query('SELECT SQL_CALC_FOUND_ROWS * FROM posts LIMIT 0, 5'); 
//do stuff with the result, but don't do any other queries 

//get the total number of rows (disregarding the LIMIT clause) 
$result = mysql_query('SELECT FOUND_ROWS()'); 

SQL_CALC_FOUND_ROWS修飾子はLIMIT句を適用する前に、行の合計数を追跡するためにMySQLを伝え、FOUND_ROWS()はその番号を返します。心の中で2つのことをしてください:

  1. これらの両方のmysql_query呼び出しが
  2. mysql_query

ああ、最後の音符にこれらの呼び出し中間に別のクエリを実行しないでください同じ接続で実行する必要があります使用している場合LIMITの場合は、通常、結果を特定の順序で並べ替える必要があります。通常、人々はページ分割にLIMITを使用します。行を順序付けしない場合、順序は不確定であり、オフセットはLIMITのオフセットが異なる場合でも、後続の問合せによって、以前の文によってすでに戻された行が戻される場合があります。 ORDER BY句を使用して結果を明示的に並べ替えることができます。 (http://dev.mysql.com/doc/refman/5.5/en/select.html

+0

はい、私は完全にあなたの最後のステートメントに同意します。実際には、結果セットを明示的に 'ORDER BY'節を使用して順序付けることが可能です。実際には、私は "ORDER BY'節を使って" ** **だけ "と言っています。 ;)ちょっと皮肉なことに、申し訳ありません。私はあなたの答えが精巧で教育的であることがわかります。 –

+1

+1 'FOUND_ROWS()'のために+1 –

+0

@Andriy heh、ありがとう:)ちょうどニンピクですが、MySQLでは、良いか悪いかにかかわらず、GROUP BY句は順序付きの結果セットを返すことも保証されています。 GROUP BYリストの式にASC修飾子とDESC修飾子を指定することもできます。 –

8

あなたが考えている合計がわかりません:現在選択されている合計か、テーブル全体のすべての行の数です。これは、各行に同じ値で、もちろん、全体のテーブルのすべての行数を返します。

mysql_query("SELECT *, (select COUNT(*) from posts) AS total FROM posts LIMIT 0, 5"); 
+0

申し訳ありませんが、ありがとう、それは完璧です。私はそれを欲しいものの数を選択するために他のクエリを変更することができると仮定します。これはひどく非効率的ですか?それは2倍の数のクエリを作成していますか? – mowwwalker

+0

@Walkerneoそれが実際の質問であれば、mysql_num_rowsが最適な解決策です。 – hjpotter92

+0

@Walkerneoそれは相関関係がありません(外側クエリと内側クエリの間に相関はありません)ので、効率を失ってはいけません。そして、あなたはあなたが望むものに内側のクエリを制限することができます。 –

1

あなたはこの問題を複雑にしていると思います。私は2つのクエリを使用することに問題は見られません。総記事を取得する

まずクエリ(私はあなたがテーブル全体で合計をしたいと仮定しています):

SELECT COUNT(*) AS total FROM posts; 

そして第二に、あなたの記事を照会する:

SELECT * FROM posts LIMIT 0, 5 

理由は、複数のクエリを使用してデータを取得することは、特に意味がある場合は、必ずしも悪いことではありません。

副問合せを使用して追加の列として追加する場合は、各行に合計がありますが、基本的には2つの問合せが実行されます(または、すべての行に対してサブクエリが実行されます。覚えていないのですか?)

また、クエリの複雑さによっては、いくつかのクエリが間違った合計カウントを返すため、より柔軟にカウントを取得できます。そして、正確な合計を取得し、正しく改ページできるように、カウントクエリを変更する必要があるかもしれません。

たとえば、1対多問合せの場合、投稿とコメントを取得したいとします。その投稿のコメントごとに投稿が重複するため、間違ったカウントを取得します。

略称例:だから

post_id | comment_id 
1  | 1 
1  | 2 
2  | 3 
3  | 4 
3  | 5 

はそれを正しく行うには、まず、全ポスト取得するには、次のクエリを実行する必要があるだろう:

SELECT COUNT(*) AS total FROM posts; 

をそして、あなたが実行する必要があるでしょう:

SELECT id FROM posts limit 0, 5; 

そして最後に、あなたが実行したい:

select p.id, c.id from posts p left join comments c on c.post_id = p.id where id in(id list from above query) 

明らかに、あなたのクエリは上記の問題に遭遇しません。しかし、私は単なる別のクエリで総カウントを得ることが良い理由を説明しようとしています。

+1

複数のクエリを使用するには、並行性について考える必要があります。最初のクエリが終了した後、2番目のクエリが開始される前に何かが行を追加または削除するとどうなりますか? 2番目のクエリによって返されたカウントは、最初のクエリの結果と矛盾します。(十分な独立性レベルを持つ1つのトランザクションで両方のクエリを実行することで回避できます)。 – Wyzard

+0

はい、トランザクション内でクエリを実行するとよい点があります。 – Gohn67

関連する問題