初歩的な質問で恐縮なのですが、SQLの書き方です。
pythonとsqliteを使っています。
所定の条件で検索した際に、そのレコードと共に、ヒット件数を表示させたいと思っています。
sql
1select count(*) from table where age>20; 2
などとすればもちろん件数は分かるのですが、ただcountを使うと、同時にレコードをselectすることはできないように思います。
現状では
sql
1select count(*) from table where age>20; 2 3select * from table where age>20;
という具合に、2回SQLを実行しています。
これがどう見ても不細工ですし、効率も悪いように思うので、
なんとか1回のSQLで処理をしたいです。
どのようにすればよいのでしょうか。
ご指導お願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
一度に取得するとしたら以下の様にすれば取得はできますが、これはこれで不細工な感じですね。
SQL
1select *,(select count(*) from table t where age>20) from table where age>20
※他にもfrom 句でインラインビューの直積などでもできますけど、不細工さは同じ
全ての行に件数が埋め込まれますので、先頭を取得した際にでも取得すればいいのですけど。
上記で行うのなら、fetchall()の結果をlen()で求める方がすっきりします。
表示する際にページ制御を行う場合は、count()を別に取得する事が多いです。
selectで全件取得はせずに、ページに表示する件数をoffset とlimitで制御して行うことになりますが、
この際のoffsetは全体の件数(=count())とページ表示件数(=limitの値)から求めます。
※取得するデータの数と開始位置を指定
項目の取得と件数の取得を一度に行ってしまうと、必ず全体の取得になるので、遅くなることがあります。
※元々ページ制御を行うのは取得件数を限定して高速にしようというのが殆ど。
これはfetchall()でも同じなので、状況に応じて使い分けて下さい。
こんなのもありました。※まあ、そのような設計になっていればですけど。
OFFSETを使わない高速なページネーションの実現
投稿2018/04/03 06:36
編集2018/04/03 07:16総合スコア25300
0
PHPとMySQLの組み合わせのように
「SELECT * 」した際の行数を拾えるプログラムとSQLの組み合わせもあります
ただし上記参考サイトにもあるように、ほとんどのデータベースでは、
SELECT 文によって作用した行数つかむような処理はありません
SELECT COUNT(*)してからSELECT *するのは
不細工ですし、効率も悪い
ということはありません。普通の運用方法です。
逆に無理に1文にしてしまうのは、すべての行に同じ内容のデータを
表示することになり逆正規化のような考え方なのであまりおすすめできません。
投稿2018/04/04 03:29
総合スコア116623
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
SQL
1select count(*) as cnt, * from table where age>20;
で、count(*)
の結果をカラム名cnt
として同時に取れます。
**追記しました:**2018/04/03 15:58
saziさんのコメントを受けて再度確認しました。ご指摘のエラーにはなりませんでしたが、全件のデータを取れないので、回答としては間違っていて、NGですね。私の確認不足でした。申し訳ありません。(評価を下げてください)
C>sqlite3 SQLite version 3.18.0 2017-03-28 18:48:43 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> CREATE TABLE t1 (age integer, name text); sqlite> INSERT INTO t1 (age, name) VALUES (5, 'name#1'); sqlite> INSERT INTO t1 (age, name) VALUES (10, 'name#2'); sqlite> INSERT INTO t1 (age, name) VALUES (20, 'name#3'); sqlite> INSERT INTO t1 (age, name) VALUES (21, 'name#4'); sqlite> INSERT INTO t1 (age, name) VALUES (35, 'name#5'); sqlite> INSERT INTO t1 (age, name) VALUES (40, 'name#5'); sqlite> sqlite> select * from t1; 5|name#1 10|name#2 20|name#3 21|name#4 35|name#5 40|name#5 sqlite> SELECT * FROM t1 WHERE age > 20; 21|name#4 35|name#5 40|name#5 sqlite> SELECT COUNT(*) AS cnt, * FROM t1 WHERE age > 20; 3|40|name#5 sqlite>
投稿2018/04/03 06:18
編集2018/04/03 07:00総合スコア9254
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/03 06:36
2018/04/03 07:01
2018/04/03 07:01
2018/04/03 07:02
2018/04/03 07:02
2018/04/03 07:17 編集
2018/04/03 07:05
2018/04/03 07:28
退会済みユーザー
2018/04/05 21:59
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/04/05 22:04