查询会员

时间:2014-03-10 07:08:22

标签: mysql 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

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

1 个答案:

答案 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