我開始拼湊在一起之前寫幾個子查詢。我個人的建議是在整個解決方案之前總是將問題分解成更小的一部分。
例如,我需要知道的一件事是每個客戶都沒有購買的所有產品。我這樣做是由已經在順序表中存在的交叉連接的客戶和產品表(讓所有配對),除去對,是這樣的:
-- Get all customer/product pairings where customer_product
-- does not exist in orders table
SELECT c.id, p.id
FROM customer c
CROSS JOIN product p
WHERE (c.id, p.id) NOT IN (SELECT * FROM orders)
ORDER BY c.id;
我也寫了一個子查詢,以獲得平均收視率每個產品。這個查詢將返回NULL,如果產品沒有等級:
SELECT p.id, AVG(r.rate) AS averageRating
FROM product p
LEFT JOIN rate r ON r.product_id = p.id
GROUP BY p.id;
現在,我可以包括這兩個子查詢和選擇客戶ID,產品ID,和他們沒有購買每個產品的評價:
SELECT t1.customerID, t1.productID, t2.averageRating
FROM(
SELECT c.id AS customerID, p.id AS productID
FROM customer c
CROSS JOIN product p
WHERE (c.id, p.id) NOT IN (SELECT * FROM orders)
ORDER BY c.id) t1
JOIN(
SELECT p.id AS productID, AVG(r.rate) AS averageRating
FROM product p
LEFT JOIN rate r ON r.product_id = p.id
GROUP BY p.id) t2 ON t2.productID = t1.productID;
這是最難的部分。剩下的唯一要做的事就是進行一些聚合,以便從每個客戶沒有購買的商品中獲得最大的評分,然後在上面的查詢中加入聚合查詢,條件是最高評分與平均評分相匹配。所以,這裏是我已經把滔天查詢:
SELECT t1.customerID, t1.productID, t1.averageRating
FROM(
SELECT t1.customerID, t1.productID, t2.averageRating
FROM(
SELECT c.id AS customerID, p.id AS productID
FROM customer c
CROSS JOIN product p
WHERE (c.id, p.id) NOT IN (SELECT * FROM orders)
ORDER BY c.id) t1
JOIN(
SELECT p.id AS productID, AVG(r.rate) AS averageRating
FROM product p
LEFT JOIN rate r ON r.product_id = p.id
GROUP BY p.id) t2 ON t2.productID = t1.productID) t1
JOIN(
SELECT t1.customerID, MAX(t2.averageRating) AS maxRating
FROM(
SELECT c.id AS customerID, p.id AS productID
FROM customer c
CROSS JOIN product p
WHERE (c.id, p.id) NOT IN (SELECT * FROM orders)
ORDER BY c.id) t1
JOIN(
SELECT p.id AS productID, AVG(r.rate) AS averageRating
FROM product p
LEFT JOIN rate r ON r.product_id = p.id
GROUP BY p.id) t2 ON t2.productID = t1.productID
GROUP BY t1.customerID) t2 ON t2.customerID = t1.customerID AND t2.maxRating = t1.averageRating
ORDER BY t1.customerID;
這裏是從MySQL工作臺結果的快照:
要注意的重要一點是,我並沒有消除領帶。因此,例如,客戶2沒有購買產品1或2並且它們具有相同的評級,因此返回兩行。
我在MySQL的測試,因爲SQL小提琴是行不通的,但我得到了工作,所以這裏是一個Fiddle例如,如果你喜歡的。
你想爲所有客戶的所有此類產品的列表,或只爲特定的客戶? – eggyal 2015-03-08 17:23:47
對於顧客還沒有購買但評價過的所有產品。 – Dino 2015-03-08 17:24:38
您是否想要爲所有客戶提供所有此類產品的清單,還是隻爲特定客戶提供? – eggyal 2015-03-08 17:25:37