MySQL:显示在Month1和Month2或Month3中购买的客户,但不是两者

时间:2012-04-07 01:48:47

标签: mysql sql

我是MySQL的新手,请原谅我的无知。

我认为这样可行,但事实并非如此。

SELECT DISTINCT c_id
,       c_name
FROM    a_bkorders.bkv_CustOrders
WHERE   Date_Format(order_date, '%Y-%m') = @m_one
AND     c_id IN (
            SELECT DISTINCT c_id
            FROM    a_bkorders.bkv_CustOrders
            WHERE   Date_Format(order_date, '%Y-%m') = @m_two 
            XOR     Date_Format(order_date, '%Y-%m') = @m_three )
;

所以我试着用它进行比较,但它没有回复我的预期:

SELECT DISTINCT c_id
,       c_name
FROM    a_bkorders.bkv_CustOrders
WHERE   Date_Format(order_date, '%Y-%m') = @m_two 
XOR     Date_Format(order_date, '%Y-%m') = @m_three
;

我知道我可能会忽略一些简单而基本的东西。 : - / 有人可以指出我正确的方向。

3 个答案:

答案 0 :(得分:0)

我不太确定您的数据是什么样的,但我假设您有2个表,一个包含客户数据,另一个包含与客户相关的订单数据和ID。所以,这样的事情应该有效:

SELECT DISTINCT customer.id
FROM customers
LEFT JOIN orders
WHERE (Date_Format(orders.date, '%Y-%m') = @m_one AND Date_Format(orders.date, '%Y-%m') = @m_two)
OR (Date_Format(orders.date, '%Y-%m') = @m_one AND Date_Format(orders.date, '%Y-%m') = @m_three)

显然用自己的名字替换表名,但我相信你会得到你想要的东西。

答案 1 :(得分:0)

条件

WHERE   Date_Format(order_date, '%Y-%m') = @m_two 
  XOR   Date_Format(order_date, '%Y-%m') = @m_three )

没有做你想要的。如果你考虑一下,你会发现在这种情况下,XOR与OR相同,因为一个order_date值不可能在两个不同的月份。 WHERE子句在每个单独的行上进行评估,因此一次只能在一个order_date值上进行评估。

您确实需要@m_thwo中的月份@m_two的order_date值,但不是全部。您想要排除两者中出现的那些。你可以使用一堆EXISTS和NOT EXISTS条件,或者你可以做这样的事情。 (这有些笨拙,所以想想比我更多。)

SELECT
  c_id, c_name
FROM a_bkorders.bkv_CustOrders
WHERE Date_Format(order_date, '%Y-%m') IN (@m_one,@m_two,@m_three)
GROUP BY c_id, c_name
HAVING -- some order from month @m_one
  MAX(CASE WHEN Date_Format(order_date, '%Y-%m') = @m_one THEN 1 END) = 1
AND -- having orders from exactly two distinct months of the three in question
  COUNT(DISTINCT Date_Format(order_date, '%Y-%m')) = 2;

换句话说,这会从订单表中选择c_id,c_name值,这些值在@m_one中至少出现一次,并且恰好是三个月中的两个月。

答案 2 :(得分:0)

我发现这种方法更加明显:

SELECT DISTINCT
    c_id,
    c_name
  FROM a_bkorders.bkv_CustOrders
 WHERE Date_Format(order_date, '%Y-%m') = @m_one
   AND c_id IN (
    SELECT c_id
      FROM a_bkorders.bkv_CustOrders
     WHERE (
        (CASE WHEN Date_Format(order_date, '%Y-%m') = @m_two THEN 1 ELSE 0 END) +
        (CASE WHEN Date_Format(order_date, '%Y-%m') = @m_three THEN 1 ELSE 0 END) = 1) )
;

我没有MySQL数据库来测试它。逻辑在这里非常简单:

  • 如果订单月份与给定月份匹配,则每个CASE ... END表达式将产生1;
  • 根据您的情况,只应使用其中一个月,因此总和应为1