2009-12-10 47 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。但是,与通常的内部连接相比,它们仍然是外连接还是很好的。

相关问题