2009-12-10 45 views
0

我有2個表,這樣定義:SQL加入該顯示器左表即使右表不匹配,其中

CREATE TABLE `product` (
`pid` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
`name` VARCHAR(50) NOT NULL, 
`description` TEXT, 
`qty` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0', 
`category` ENUM('1', '2', '3', '4', '5', '6', '7', '8') NOT NULL DEFAULT '1', 
`price` DECIMAL(7, 2) UNSIGNED NOT NULL 
) ENGINE = InnoDB; 

CREATE TABLE `discount` (
`did` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
`pid` SMALLINT(5) UNSIGNED NOT NULL, 
`sDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`eDate` DATETIME NOT NULL, 
`dPrice` DECIMAL(7, 2) UNSIGNED NOT NULL, 
FOREIGN KEY (`pid`) REFERENCES `product`(`pid`) 
    ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE = InnoDB; 

我試圖得到完全排1的結果爲每一個產品和一個NULL dPrice或dPrice是否有sDate < NOW()eDate > NOW()的折扣條目。

我想:

select p.pid, name, price, dPrice, qty 
from product p left join discount d 
on p.pid = d.pid 
where d.sDate<now() and d.eDate>now(); 

的問題,這是它僅返回產品具有有效的折扣。沒有折扣或過期/未來折扣的產品不顯示。

接下來我想:

select p.pid, name, price, dPrice, qty 
from product p left join discount d 
on p.pid = d.pid 
where (d.sDate<now() and d.eDate>now()) or dPrice is null; 

在此之前1步步接近我想要的結果,在這裏上市的產品有合法的折扣和產品沒有折扣,但我仍然失蹤過期/未來產品折扣定義。

檢查在任何時候只有1個折扣處於活動狀態是在PHP中完成的,不需要包含在本聲明中。任何幫助深表感謝!

+0

什麼數據庫系統?什麼版本? – 2009-12-10 22:13:18

回答

4
select p.pid, name, price, dPrice, qty 
from product p 

left join discount d on p.pid = d.pid and d.sDate<now() and d.eDate>now() 

更高效的和超過一個子查詢更「標準」。

+0

嗚!這個作品太... – 2009-12-10 22:21:44

+0

這是一樣的接受的答案,但我更早前發佈;) – 2009-12-10 23:37:23

1

您可能希望子查詢返回discount的過濾版本,然後您可以將它們與product一起加入。

select p.pid, name, price, dPrice, qty 
from product p left join 
(select * from discount where sDate<now() and eDate>now()) d 
on p.pid = d.pid; 

(有可能是在這裏的SQL語法略有誤差,但你的想法:因爲你只想要WHERE條款適用於一個表,你把它應用到表中的子查詢,然後加入的結果數據集,而不是第一連接表和然後過濾。)

+0

不,沒有錯誤。 =) 謝謝你! – 2009-12-10 22:19:12

2

什麼

SELECT p.name, d.dPrice 
FROM product p LEFT JOIN discount d 
ON  p.pid = d.pid AND now() BETWEEN d.sDate AND d.eDate 
+0

大聲笑! 3種方式完成工作,我不能拿出一個!謝啦! – 2009-12-10 22:23:24

0

這正是Outer Joins已經被髮明瞭。

select p.*,d.dPrice from product p left outer join discount d on p.pid=d.pid and now() between d.sDate and d.eDate

您可以使用縮寫left join,而不是完整left outer join。但是,與通常的內部連接相比,它們仍然是外連接還是很好的。

相關問題