我有以下产品和价格表:
表格:产品
productID
---------
1
2
3
4
5
表格:价格
priceID productID started expires
-------------------------------------------
1 1 2011-11-05 NULL
2 1 2011-11-05 2011-11-20
3 2 2011-11-05 NULL
4 3 2011-11-05 NULL
5 3 2011-11-06 2011-11-08
我希望以这样一种方式加入他们:
price.started <= NOW() AND ( price.expires >= NOW() || price.expires IS NULL )
price.priceID
这四个标准定义了有效价格的最有效(为了更好的条款)。因此对于NOW() == 2011-11-09
,最终结果应为:
priceID productID started expires
-------------------------------------------
2 1 2011-11-05 2011-11-20
3 2 2011-11-05 NULL
4 3 2011-11-05 NULL
我陷入了
price.priceID
要求,这源于对一段时间内任何特定产品的多个有效价格的异乎寻常的业务要求。我的sql fu非常差,我走得很远:
SELECT
product.*,
price.*
FROM
product
LEFT JOIN
price
ON
price.productID = product.productID
AND price.started <= NOW()
AND (
price.expires IS NULL
OR price.expires >= NOW()
)
NOW() == 2011-11-09
当然导致:
productID priceID productID started expires
-------------------------------------------------------
1 1 1 2011-11-05 NULL
1 2 1 2011-11-05 2011-11-20
2 3 2 2011-11-05 NULL
3 4 3 2011-11-05 NULL
澄清(基于评论和答案):
答案 0 :(得分:3)
<强>更新强>
以下(完整)查询应该可以解决问题:
SELECT
product.*,
price.*
FROM
product,
(SELECT price.* FROM price
WHERE price.started <= NOW()
AND
(price.expires IS NULL
OR price.expires >= NOW())
GROUP BY price.productId
BY price.priceId DESC LIMIT 1) AS `price`
WHERE price.productID = product.productID;
答案 1 :(得分:1)
SELECT
pro.*
, pri.*
FROM
product AS pro
JOIN
price AS pri
ON pri.priceID =
( SELECT p.priceID
FROM price p
WHERE p.productID = pro.productID
AND p.started <= CURRENT_DATE()
AND ( p.expires IS NULL
OR p.expires >= CURRENT_DATE()
)
ORDER BY p.priceId DESC
LIMIT 1
)
答案 2 :(得分:0)
SELECT
p.*,
( SELECT
TOP 1 pr.price
FROM price pr
WHERE pr.productID = p.productID
AND pr.started <= NOW()
AND ( pr.expires IS NULL
OR pr.expires >= NOW())
ORDER BY
pr.productID DESC
) AS price
FROM product p
答案 3 :(得分:0)
如果要避免子查询,可以尝试以下语句:
SELECT
product.*,
price.*,
MAX(price.priceID)
FROM
product
LEFT JOIN
price
ON
price.productID = product.productID
AND price.started <= NOW()
AND (
price.expires IS NULL
OR price.expires >= NOW()
)
GROUP BY price.productID
GROUP BY将仅使用max priceID强制结果中的不同产品。希望它有所帮助!
答案 4 :(得分:0)
WITH pc AS (
SELECT pc1.priceid, pc1.productid
, pc1.started, pc1.expires
FROM tmp.price pc1
WHERE pc1.started <= now()
AND (pc1.expires IS NULL OR pc1.expires > now() )
AND NOT EXISTS ( SELECT *
FROM tmp.price pcx
WHERE pcx.productid = pc1.productid
AND pcx.started <= now()
AND (pcx.expires IS NULL OR pcx.expires > now() )
AND pcx.priceid > pc1.priceid
)
)
SELECT pd.productid
, pd.productname
, pc.started
, pc.expires
FROM pc
JOIN tmp.product pd ON pc.productid = pd.productid
;
CTE是无名视图。如果您的DBMS不支持CTE,您可以将查询的第一个(CTE)部分放入命名视图中;子聚合物是相同的。因人而异。