0

我正在尝试从 aMember 中提取查询。我们有几张桌子:

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

我敢打赌我忽略了一些非常简单的事情,但是对于我的生活来说,我无法弄清楚我哪里出错了。有什么想法可以摆脱多余的行吗?

4

1 回答 1

0

我设法通过使用两个单独的查询来解决它;一个为product1,另一个为product2。在product1查询中,我添加了NUL一个别名为 的 L 列Episode2Bought。在product2查询中,我做同样的事情,但对于Product1Bought. 这样我可以UNIONthw两个结果集。

但是,如果用户购买了两种产品,这仍然会导致重复行。为了解决这个问题,我在该结果集周围包装了一个 SELECT,使用MAX()ProductBought 列上的函数来删除 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
于 2014-03-10T20:07:24.037 回答