こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

2つのSQL文で結果に差違が発生する

私の知識ではお手上げのため、ご教授願いたいのですが、
下記のようなテーブルが仮にあったとして、レコードがそれぞれいくつか入っています。

【itemsテーブル】
  id・・・・・連番
  cat_id・・・category.id
  price ・・・価格
  max_num ・・セット数
  date・・・・発売日

【categioryテーブル】
  id・・・・・連番
  cat_name・・カテゴリ名

【orderテーブル】
  id・・・・・連番
  item_id ・・items.id
  paid_price・支払価格


以下の2つのSQL文を実行させた場合、「total_price」の値に違いは発生しますか?

【SQL文 A】-----------------------------
SELECT
items.cat_id,
`category`.`cat_name`,
SUM(`items`.`price` * `items`.`max_num`) AS `total_price`,
SUM(IF(`order`.`paid_price` > 0, `order`.`paid_price`, 0)) AS `total_paid`,
SUM(IF(`order`.`paid_price` = 0 , `items`.`price`, 0)) AS `not_payment`
FROM `items`
INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`)
INNER JOIN `order` ON (`items`.`id` = `order`.`item_id`)
WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511
GROUP BY `items`.`cat_id`
ORDER BY `items`.`cat_id` ASC

------------------------------------


【SQL文 B】-----------------------------
SELECT
items.cat_id,
`category`.`cat_name`,
SUM(`items`.`price` * `items`.`max_num`) AS `total_price`
FROM `items`
INNER JOIN `category` ON (`items`.`cat_id` = `category`.`id`)
WHERE AND DATE_FORMAT(`items`.`date`, '%Y%m') = 201511
GROUP BY `items`.`cat_id`
ORDER BY `items`.`cat_id` ASC

------------------------------------


こちらで上記と同じようなSQL文を実行すると、Bで出てほしい値がAでは出てこないのです。
Aの場合は「WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511」が抽出条件として実行されていないような感じです。
すべてのレコードの「SUM(`items`.`price` * `items`.`max_num`) AS `total_price`」が計算されています。
Bだけで実行すればちゃんとほしい値が返ってきます。

何か間違っていますか?

投稿日時 - 2015-11-16 19:03:39

QNo.9081334

困ってます

質問者が選んだベストアンサー

AとBとでは、SQLの目的が異なるように見えます。
Bは2015/11に発売されたアイテムの定価をカテゴリーごとに合算したもの、
Bは2015/11に発売されたアイテムの売上をカテゴリーごとに合算したものに見えます。

例えば、あるアイテムに対してorderテーブル内に5つのレコードがあった場合、Aではそのアイテムに対する価格が5回加算されますが、Bでは1回しか加算されません。
従って、AとBでは結果が異なると思います。

投稿日時 - 2015-11-17 10:51:23

お礼

遅くなって申し訳ありません。

よく見ると確かにSQLの意味が違いますね。
すみませんでした。

投稿日時 - 2016-02-12 14:32:06

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

>以下の2つのSQL文を実行させた場合、「total_price」の値に違いは発生しますか?
⇒発生します。特にorderテーブルにレコードがあるかどうかで。

>こちらで上記と同じようなSQL文を実行すると、Bで出てほしい値がAでは出てこないのです。
⇒意味がよくわからないのですが、、出てほしい値はBで出ているんですかね?その上でAには出てこないという意味でしょうか。
 そういう意味ならorderテーブルにINNER JOINしてる分Aのほうが抽出条件が厳しいので
 やっぱり出てこない値のitems.idの値がorderテーブルに含まれていないんじゃないかと推測します。

>Aの場合は「WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511」が抽出条件として実行されていないような感じです。
>すべてのレコードの「SUM(`items`.`price` * `items`.`max_num`) AS `total_price`」が計算されています。
>Bだけで実行すればちゃんとほしい値が返ってきます。
⇒値が違う理由は上記だと思うので ここは無視しします。

何か間違っていますか?
⇒2つのSQL文が間違っているかどうかは、そのSQLで何が出したいのか
 言葉にして頂けるとはっきり答えれるのですが、そうでないと
 何とも言えません。
 
回答が中途半端になり、申し訳ないですが
進捗があることを切に願います。

投稿日時 - 2015-11-23 23:20:44

ANo.3

> Aの場合は「WHERE DATE_FORMAT(`items`.`date`, '%Y%m') = 201511」が抽出条件として実行されていないような感じです。

その予想が正しいかどうかは簡単に検証できます。
AのWHERE句を削除した形で、同じ結果が得られるか確認すればいいのです。
私の予想では、異なる結果が得られるのではないかと思います。

両方のSQLを、結合条件と抽出条件はそのままにSELECT * とし、GROUP BYを削除して、抽出されているレコードを比べてみましょう。違いがあるはずです。

私の予想では、orderテーブルのitem_idが一意でないのではないかと思います。

投稿日時 - 2015-11-17 15:36:53

単純に A で order テーブルを内部結合 ( INNER JOIN ) しているからではないですかね? これを外部結合 ( LEFT JOIN ) に変えたらどうなりますか?

投稿日時 - 2015-11-16 23:24:01

あなたにオススメの質問