0

我是 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
;

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

4

3 回答 3

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_two 或 @m_three 中的 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 中至少出现一次,并且恰好出现在所讨论的三个月中的两个月中。

于 2012-04-07T03:27:26.990 回答
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
  • 并且根据您的情况,应该只使用其中一个月份,所以 sum 应该是1
于 2012-04-07T06:31:32.817 回答
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)

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

于 2012-04-07T02:08:26.637 回答