2016-03-21 11 views
1

mySQLの割り当ての場合、2014-01-01の間で注文されたデータベースのプリントのitem_id、title、artist、unit_price、およびorder_qtyを含むビューを作成しますおよび2014-03-28。オーダービューそこにはいけないアイテムを追加する

CREATE VIEW orders_v AS 
    SELECT items.item_id, title, artist, unit_price, 
    order_qty 
    FROM items, orderline, orders 
    WHERE items.item_id = orderline.item_id 
    AND orderline.order_id = orders.order_id 
    AND orders.order_date like '2014-01%' 
    OR orders.order_date like '2014-02%' 
    GROUP BY items.item_id; 

ただし、注文されていないアイテムについてはデータが表示されているため、その理由がわかりません。 ORDER_IDの9、10、11、および12

order_id: 9, item_id: 100, order_qty: 3 
order_id: 10, item_id: 450, order_qty: 6 
order_id: 10, item_id: 600, order_qty: 8 
order_id: 10, item_id: 200, order_qty: 4 
order_id: 11, item_id: 700, order_qty: 2 
order_id: 12, item_id: 300, order_qty: 4 

しかし、その代わりに、それは今までに注文されていない項目を表示しています:私のテストでは

、唯一の希望の期間内に収まっ4桁があるはずですitem_id:400などの、または時間範囲外で注文されたアイテムです。

何か助けや助言をいただければ幸いです。

私のコードは見て、それをテストするともっと助けるとhereが見つかります。 ANDORよりも優先され、そしてその括弧なしで、あなたが以前のすべての条件のいずれかが真でなければならないと言って、または最後にしているためである

(orders.order_date like '2014-01%' 
    OR orders.order_date like '2014-02%' 
) 

:あなたは括弧の間に次の部分を配置する必要があり

答えて

1

1つ(それ自身で)。前の条件が常に真実であることを望むので、これはあなたが意図したものではありません。

第2に、結果をアイテム別にグループ化していますが、注文数量を合計していないため、一致する最初のレコードの注文数量を取得するだけです。これはおそらくあなたが望むものではありません。ちょうどその周りsum()をラップ:それは長い期間の保守性、およびより正確な範囲については、さらに難しいことではないようLIKE作品で日付を照合、あなたが日付を比較する方法を変更することを検討すべきである

select ... sum(order_qty) 

が。代わりに、あなたが一日までの制限を設定することができBETWEENを使用します。

orders.order_date between '2014-01-01' and '2014-02-28' 

参照this SQL fiddle修正を有しています。次の結果セットが返されます。

+---------+---------------+------------------+------------+-----------+ 
| item_id |  title  |  artist  | unit_price | order_qty | 
+---------+---------------+------------------+------------+-----------+ 
| 100 | Under the Sun | Donald Arley  |  46.8 | 3  | 
| 200 | Dark Lady  | Keith Morris  | 120.99 | 4  | 
| 300 | Happy Days | Andrea Reid  |  78  | 3  | 
| 450 | The Hunt  | Walter Alford |  39.99 | 6  | 
| 600 | Rainbow Row | Judy Ford  |  46  | 8  | 
| 700 | Skies Above | Alexander Wilson |  98  | 6  | 
+---------+---------------+------------------+------------+-----------+ 
+0

ありがとう、私はそれを認識しませんでした。私は変更を加えましたが、検索された日付範囲内にあるitem_id番号700の注文の1つを数えていない点を除いて、すべて正しいものになりました。 – Zach

+0

質問のサンプルデータに日付を入力していないため、確認できません。あなたはそれらを追加できますか? – trincot

+0

日付は最後に提供されたリンクにありますが、その数は多いですが、関連するものは です。 'order_id:9、order_date:2014-01-18 order_id:10、order_date :2014-01-31 order_id:11、order_date:2014-02-01 order_id:12、order_date:2014-02-27' – Zach

1

括弧はお友達です。 ORの優先順位はANDよりも高いため、2月のすべての注文でデカルト製品が得られます。あなたのビューは、

CREATE VIEW orders_v AS 
    SELECT items.item_id, title, artist, unit_price, order_qty 
    FROM items, orderline, orders 
    WHERE items.item_id = orderline.item_id 
     AND orderline.order_id = orders.order_id 
     AND (orders.order_date like '2014-01%' 
     OR orders.order_date like '2014-02%') 
    GROUP BY items.item_id; 
1

と定義する必要があります。クエリを改善する方法はいくつかあります。まず、JOIN syntaxを使用してwhere節とjoinを区切ります。これにより、クエリを読みやすくなり、問題を発見するのに役立ちます。

SELECT items.item_id, title, artist, unit_price, order_qty 
    FROM items 
    JOIN orderline ON items.item_id = orderline.item_id 
    JOIN orders ON orderline.order_id = orders.order_id 
    WHERE orders.order_date like '2014-01%' 
    OR orders.order_date like '2014-02%' 
    GROUP BY items.item_id 

他の回答で指摘されているように、これはもはやAND/OR優先順位の問題がないため、問題が修正されます。

第2に、CHAR(10)を使用して日付を保存する不幸な選択です。幸いにもISO 8601形式を使用しているため、簡単に並べ替えることができますが、MySQL's date functionsの全範囲と日付のインデックス付けを利用し、記憶領域を少なくするためには、DATEまたはDATETIMEとして保存する方がよいでしょう。 order_dateDATEだった場合は、BETWEENでクエリを書くことができます。

SELECT items.item_id, title, artist, unit_price, order_qty 
    FROM items 
    JOIN orderline ON items.item_id = orderline.item_id 
    JOIN orders ON orderline.order_id = orders.order_id 
    WHERE orders.order_date BETWEEN '2014-01-01' AND '2014-02-28' 
    GROUP BY items.item_id 
+0

私のクエリを改善する方法の提案ありがとう。残念なことに何らかの理由でインストラクターが日付のために 'CHAR(10) 'を使用することを望んでいるので、私は私がやったように物事について行きました。 – Zach

+0

@Zachインストラクターがあなたに言ったのですか?大井ここでそれらを取得し、我々はまっすぐにそれらを設定します。 :) – Schwern

+0

私はそれの背後にある目的は、現実の世界では時々このような状況があるかもしれないので、このような状況をどのように処理するかについてボックス外で考えるようになったと思う:pしかし、ありがとう、ハハ! – Zach

関連する問題