2014-02-14 70 views
1

我想編寫一個查詢,以確定如何我的庫存多在給定時間承諾,即電流,下個月等如何使用group by子句獲得左連接以返回所有行?

一個簡單的例子:

我的物品的清單表。我有一個報價表,用於說明客戶,報價何時開始以及報價何時到期。我有第三個表格將這兩者聯繫起來。

create table inventory 
(id int not null auto_increment , name varchar(32) not null, primary key(id)); 

create table offer 
(id int not null auto_increment , customer_name varchar(32) not null, starts_at datetime not null, expires_at datetime, primary key (id)); 

create table items 
(id int not null auto_increment, inventory_id int not null, offer_id int not null, primary key (id), 
    CONSTRAINT fk_item__offer FOREIGN KEY (offer_id) REFERENCES offer(id), 
    CONSTRAINT fk_item__inventory FOREIGN KEY (inventory_id) REFERENCES inventory(id)); 

創造一些庫存

insert into inventory(name) 
    values ('item 1'), ('item 2'),('item 3'); 

創建兩個報價本月

insert into offer(customer_name, starts_at) 
    values ('customer 1', DATE_FORMAT(NOW(), '%Y-%m-01')), ('customer 2', DATE_FORMAT(NOW(), '%Y-%m-01')); 

,一個用於下個月

insert into offer(customer_name, starts_at) 
    values ('customer 3', DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')); 

現在添加一些項目到每個提供

insert into items(inventory_id, offer_id) 
    values (1,1), (2,1), (2,2), (3,3); 

我想要的是一個查詢,它會顯示本月所有庫存和已提交庫存的數量。庫存將被視爲犯如果starts_at小於或等於現在和報價尚未過期(expires_at爲空或expires_at是在未來)

我希望是這樣的結果:

+----+--------+---------------------+ 
| id | name | committed_inventory | 
+----+--------+---------------------+ 
| 1 | item 1 |     1 | 
| 2 | item 2 |     2 | 
| 3 | item 3 |     0 | 
+----+--------+---------------------+ 
3 rows in set (0.00 sec) 

,我覺得應該工作的查詢是:

SELECT inventory.id 
    , inventory.name 
    , count(items.id) as committed_inventory 
    FROM inventory 
    LEFT JOIN items 
    ON items.inventory_id = inventory.id 
    LEFT JOIN offer 
    ON offer.id = items.offer_id 
WHERE (offer.starts_at IS NULL OR offer.starts_at <= NOW()) 
    AND (offer.expires_at IS NULL OR offer.expires_at > NOW()) 
GROUP BY inventory.id, inventory.name; 

然而,從該查詢結果不包括第三個項目。我得到的是這樣的:

+----+--------+---------------------+ 
| id | name | committed_inventory | 
+----+--------+---------------------+ 
| 1 | item 1 |     1 | 
| 2 | item 2 |     2 | 
+----+--------+---------------------+ 
2 rows in set (0.00 sec) 

我不知道如何獲得第三個庫存項目顯示。由於庫存是外部連接的驅動表,我認爲它應該始終顯示。

回答

0

問題是where子句。試試這個:

SELECT inventory.id 
    , inventory.name 
    , count(offers.id) as committed_inventory 
    FROM inventory 
    LEFT JOIN items 
    ON items.inventory_id = inventory.id 
    LEFT JOIN offer 
    ON offer.id = items.offer_id and 
     (offer.starts_at <= NOW() or 
     offer.expires_at > NOW() 
    ) 
GROUP BY inventory.id, inventory.name; 

問題是你得到一個匹配的報價,但它目前不是有效的。因此,where子句失敗,因爲要約日期不是NULL匹配),並且日期比較失敗,因爲該要約不是最新的。

+0

這將返回第三個清單項,但不正確計數爲1.第三項在當月沒有提交。我想要返回的是第三個月零的committed_inventory。 –

+0

@CharlieWhite。 。 。我把'count'改爲'offering.id',我認爲這是你想要的。 –

+0

非常好。我想過把where子句移到join中,但是我自己也很聰明。我一直使用連接子句來指定連接中的字段,並使用where子句來過濾結果。我想我只是沒有想到通過所有的方式。謝謝 –

0

對於項目3 starts_atoffer表設置爲月,01 2014是大於NOW所以(offer.starts_at IS NULL OR offer.starts_at <= NOW())條件將跳過第3項紀錄

See fiddle demo

相關問題