プロが教える店舗&オフィスのセキュリティ対策術

SELECT a.num b.num FROM
  サブクエリA(いろんな処理 WHERE a_id=ANY(サブクエリC(いろんな処理)) ) AS a,
  サブクエリB(いろいろ処理 WHERE b_id=ANY(サブクエリD(いろんな処理)) ) AS b

このような処理をしているのですが、サブクエリCとサブクエリDは一字一句違わない全く同じ処理をしています。
2回全く同じ処理をするのは処理コストが無駄にかかりますし、同じ内容を示す表記が2度出てくるのは保守性も悪くします。

サブクエリCとDを共通化して一つにまとめる方法はありますでしょうか。

A 回答 (3件)

これって合計じゃなくて単にcount処理をフラグやグレードを指定して取っているだけですね。



//準備
create table A (id int,flag tinyint);
create table B (id int,grade tinyint);
create table C (id int,val int);
insert into A values(1,0),(2,1),(3,0),(4,1),(5,1),(6,0),(7,0);
insert into B values(1,0),(2,0),(3,2),(4,2),(5,0),(6,0),(7,0);
insert into C values(1,10),(2,20),(3,30),(4,40),(5,50),(6,60),(7,70);

//非効率SQL
SELECT num_a, num_b FROM
(SELECT SUM(IF(flag=0, 1, 0)) AS num_a FROM A
WHERE id=ANY(SELECT id FROM C WHERE val<=50)) AS sub_a,
(SELECT SUM(IF(grade=2, 1, 0)) AS num_b FROM B
WHERE id=ANY(SELECT id FROM C WHERE val<=50)) AS sub_b

//調整後
SELECT count(flag) as num_a,count(grade) as num_b
FROM C
LEFT JOIN A on C.id=A.id and flag=0
LEFT JOIN B on C.id=B.id and grade=2
WHERE val<=50;
    • good
    • 0
この回答へのお礼

いろいろいじってみましたが、調整後の形は高速化にも繋がってますね。
とても勉強になりました。
ありがとうございました!

お礼日時:2013/02/07 02:30

>joinについてはどういう風にやるのかもう少し詳しくお願いできますでしょうか。



うーん、元のSQLが微妙なのでなんとも言えません
見た感じサブクエリC(D)によりAとBを抽出して結合し列記するという命題であれば
たとえばサブクエリAで得られるnumが(1,2)サブクエリBで得られるnumが(1,3)だと
このクエリで抽出されるデータは
num_a num_b
1 1
2 1
1 3
2 3
のようにA×Bの冗長なデータになりますがほんとにそういう考え方でよいのですか?

この回答への補足

問題のソースをできる限り簡素化して具体的な形が見えるようにしてみました。

SELECT a.totalNum, b.totalNum FROM
(SELECT SUM(IF(flag=0, 1, 0)) AS totalNum FROM x
WHERE id=ANY(SELECT id FROM zzz WHERE 条件)) AS a,
(SELECT SUM(IF(grade=2, 1, 0)) AS totalNum FROM y
WHERE id=ANY(SELECT id FROM zzz WHERE 条件)) AS b

比較するために二つの合計数(a.totalNum、b.totalNum)を得るものです。
ANYの中身はどちらも完全に同じクエリです。
いかがでしょうか。

補足日時:2013/02/04 16:07
    • good
    • 0

たぶん共通のサブクエリに対してjoinしていくだけでよいような気がしますが


場合によってはviewやテンポラリテーブルをつかってもよいかもしれません

この回答への補足

ありがとうございます。
viewやテンポラリテーブルについてはさっそく試してみました。

joinについてはどういう風にやるのかもう少し詳しくお願いできますでしょうか。
できればクエリは複数でなく一つで済むと助かるのですが。

補足日時:2013/02/04 02:17
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!