【问题标题】:SQL Join Not Returning What I ExpectSQL Join 没有返回我所期望的
【发布时间】:2009-01-20 22:32:34
【问题描述】:

我有一个临时表,我正在创建以下格式的查询。其中包含几年内每个 CustomerID、Year 和 Month 的记录。

#T

客户 |客户ID |年份 |月份

例如

Foo | 12345 | 2008 | 12  
Foo | 12345 | 2008 | 11  
Bar | 11224 | 2007 | 7

当我将此临时表连接到另一个以下格式的表时,我得到的结果比我预期的要多。

事件

事件ID |客户ID |开业日期

例如

1100 | 12345 | '2008-12-11 10:15:43'
1100 | 12345 | '2008-12-11 11:25:17'

我正在尝试获取事件计数的结果集以及这样的客户、年份和月份。

SELECT COUNT(EventID), Customer, Year, Month
FROM [Event] 
JOIN #T ON [Event].CustomerID = #T.CustomerID
WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
GROUP BY Customer, Year, Month
ORDER BY Year, Month

我获得了每年和每月的记录,而不仅仅是 2008 年 12 月的记录。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您在事件表上指定了日期,但没有在联接上指定日期——因此它将临时表中的所有记录与匹配的客户 ID 联接起来。

    试试这个:

    SELECT COUNT(e.EventID), T.Customer, T.Year, T.Month
    FROM [Event] e
    INNER JOIN #T T ON (
      T.CustomerID = e.CustomerID and 
      T.Year = year(e.DateOpened) and 
      T.Month = month(e.DateOpened) 
      ) 
    WHERE T.Year = 2008 
      and T.Month = 12 
    GROUP BY T.Customer, T.Year, T.Month
    ORDER BY T.Year, T.Month
    

    【讨论】:

      【解决方案2】:

      也许你的意思是:

      SELECT COUNT(EventID)
          ,Customer
          ,Year
          ,Month
      FROM [Event] 
      INNER JOIN #T
          ON [Event].CustomerID = #T.CustomerID
          AND YEAR([Event].DateOpened) = #T.YEAR
          AND MONTH([Event].DateOpened) = #T.MONTH
      WHERE [Event].DateOpened >= '2008-12-01'
          AND [Event].DateOpened < '2009-01-01'
      GROUP BY Customer
          ,Year
          ,Month
      ORDER BY Year
          ,Month
      

      注意,我已经修复了您代码中的另一个潜在错误:您的 BETWEEN 将排除日期时间,例如 '2008-12-31 10:15:43' 您可以使用这种或类似的技术。

      【讨论】:

      • 很好地抓住了范围截断。如果将 DateOpened 转换为 DATE 值(没有时间分量),那么原始值就可以了。
      • 另外,我喜欢您在 Event.DateOpened 与 #T.Year 和 #T.Month 之间进行连接的方式。比我的回答更简洁。
      • 有很多方法可以给这只猫换皮——如果数据库设计更简洁,还有很多方法可以减少代码。我讨厌混合 YEAR 和 MONTH int 列和 datetime 列 - 选择一个约定并坚持下去。
      【解决方案3】:

      问题是#T 中有两行 CustomerID = 12345。这些行中的每一行都与Event 中的每一行相连接。如果您只想要 12 月的 CustomerID,那么您也需要过滤 #T

      SELECT COUNT(EventID), Customer, Year, Month
          FROM [Event] 
          JOIN #T ON [Event].CustomerID = #T.CustomerID
          WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
            AND #T.Year = 2008
            AND #T.Month = 12
          GROUP BY Customer, Year, Month
          ORDER BY Year, Month
      

      如果您有其他期望,最好澄清您的问题。

      【讨论】:

        【解决方案4】:

        如果您只想要客户名称,#T 似乎有多余的信息。

        你可以用一个子查询来解决它

        SELECT COUNT(EventID), (select TOP 1 #T.Customer from #T Where #T.CustomerID = [Event].CustomerID ), Year, Month
        FROM [Event] 
        WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
        GROUP BY CustomerID, Year, Month
        ORDER BY Year, Month
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-30
          • 1970-01-01
          • 2021-12-11
          • 2018-05-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多