我正在尝试从一个会员中提取查询。我们有几张桌子:
am_user - Contains user data - PK = user_id
am_invoice - Contains one line per invoice - PK invoice_id, FK to user_id
am_invoice_item - Contains one line per product - FK to invoice_id
我们目前使用4种不同的product_ids销售2种不同的产品(它的软件,产品有2种不同的版本)。用户只能购买第1集,仅第2集或两者。 (我们对那些尚未购买的人不感兴趣)。
我的查询如下所示:
SELECT
u.user_id, login, u.added
, CASE ii.item_id
WHEN 3 THEN i.tm_added
WHEN 5 THEN i.tm_added
ELSE NULL END AS Episode1Bought
, CASE ii2.item_id
WHEN 7 THEN i2.tm_added
WHEN 6 THEN i2.tm_added
ELSE NULL END AS Episode2Bought
FROM
am_user u
LEFT JOIN am_invoice i ON u.user_id = i.user_id
LEFT JOIN am_invoice_item ii ON i.invoice_id = ii.invoice_id AND ii.item_id IN (3, 5)
LEFT JOIN am_invoice i2 ON u.user_id = i2.user_id
LEFT JOIN am_invoice_item ii2 ON i2.invoice_id = ii2.invoice_id AND ii2.item_id IN (7, 6)
WHERE i.status = 1 AND i2.status = 1 -- Only paid invoices
ORDER BY user_id
但是,对于同时购买这两集的客户,最终会返回最多4行。对于其他只购买1集的人来说,它的工作正常:
1 user1 2013-12-07 18:06:01 Episode1_EN 2014-01-11 13:28:19 Episode2_DK 2014-02-15 10:22:30
1 user1 2013-12-07 18:06:01 NULL NULL Episode2_DK 2014-02-15 10:22:30
1 user1 2013-12-07 18:06:01 Episode1_EN 2014-01-11 13:28:19 NULL NULL
1 user1 2013-12-07 18:06:01 NULL NULL NULL NULL
我希望它只返回包含购买细节的行:
1 user1 2013-12-07 18:06:01 Episode1_EN 2014-01-11 13:28:19 Episode2_DK 2014-02-15 10:22:30
我打赌我忽略了一些非常简单的事情,但因为我的生活无法弄清楚我哪里出错了。我有什么想法可以摆脱多余的行?
答案 0 :(得分:0)
我设法通过使用两个单独的查询来解决它;一个用于product1
,另一个用于product2
。在product1
查询中,我添加了NUL
L列,其别名为Episode2Bought
。在product2
查询中,我也这样做,但对于Product1Bought
。这样我可以UNION
两个结果集。
但是,如果用户购买了这两种产品,这仍会导致重复行。为了解决这个问题,我在结果集周围包装了一个SELECT,在ProductBought列上使用MAX()
函数来删除NULLS并使用GROUP BY将重复的行合并在一起。
结束查询如下所示:
SELECT
user_id
, login
, added
, MAX(Episode1Bought) AS Episode1Bought
, MAX(Episode2Bought) AS Episode2Bought
FROM
(
SELECT
u.user_id, login, u.added
, CASE ii.item_id
WHEN 3 THEN i.tm_added
WHEN 5 THEN i.tm_added
ELSE NULL END AS Episode1Bought
, NULL AS Episode2Bought
FROM
am_user u
JOIN am_invoice i ON u.user_id = i.user_id
JOIN am_invoice_item ii ON i.invoice_id = ii.invoice_id AND ((ii.item_id IN (3, 5)) )
WHERE i.status = 1
UNION
SELECT
u.user_id, login, u.added
, NULL AS Episode1Bought
, CASE ii.item_id
WHEN 6 THEN i.tm_added
WHEN 7 THEN i.tm_added
ELSE NULL END AS Episode2Bought
FROM
am_user u
JOIN am_invoice i ON u.user_id = i.user_id
JOIN am_invoice_item ii ON i.invoice_id = ii.invoice_id AND ((ii.item_id IN (6, 7)) )
WHERE i.status = 1
)
as a
GROUP BY user_id, login, added
ORDER BY user_id
;
这正确地返回了所需的结果:
1 user1 2013-12-07 18:06:01 Episode1_EN 2014-01-11 13:28:19 Episode2_DK 2014-02-15 10:22:30