T-SQL - 执行连接以检索0的计数

时间:2014-11-15 18:11:10

标签: sql sql-server tsql join aggregate-functions

我正在使用一个有三个表的气候数据库。一个事件表,它包含发生天气事件的日期时间,事件类型和事件发生的状态。第二个表是一个死亡事件表,它通过第一个表中的ID号链接。最后,有一张表格列出了年份(1950年,1951年,1952年等)。

我写了以下内容: -

SELECT
    State,
    YEAR(BeginDate) as Year,
    COUNT(*) as CountOfEvents
FROM 
    [StormEvents].[dbo].[DT_Event]
JOIN 
    [StormEvents].[dbo].[DT_FatalityEvent] ON [StormEvents].[dbo].[DT_Event].EventID = [StormEvents].[dbo].[DT_FatalityEvent].EventID
WHERE 
    EventType like'%tornado%'
    AND YEAR(BeginDate) >= 1995 
    AND YEAR(BeginDate) <= 2014
GROUP BY 
    State, YEAR(BeginDate)
ORDER BY 
    State, YEAR(BeginDate)

总结了每个州每月死亡事件的数量。上面的查询有效,但它省略了任何返回计数为0的计数。

我在阅读了关于联接之后尝试添加这一行: -

RIGHT JOIN 
    [StormEvents].[dbo].[DT_YearValues] ON YEAR([StormEvents].[dbo].[DT_Event].BeginDate) = [StormEvents].[dbo].[DT_YearValues].[Year]

但是,在该州和年份的死亡事件计数为0的字段中,这不会返回0。

有人可以建议我哪里出错吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

假设EventType在[StormEvents]中。[dbo]。[DT_FatalityEvent]
以下将打破右连接 其中EventType类似于&#39;%tornado%&#39;

SELECT State,
       YEAR(BeginDate) as Year,
       COUNT([StormEvents].[dbo].[DT_FatalityEvent].[EventID]) as CountOfEvents
  FROM [StormEvents].[dbo].[DT_Event]
 right JOIN [StormEvents].[dbo].[DT_FatalityEvent] 
    ON [StormEvents].[dbo].[DT_Event].[EventID] = [StormEvents].[dbo].[DT_FatalityEvent].[EventID]
   and EventType like'%tornado%'
   AND YEAR(BeginDate) >= 1995 
   AND YEAR(BeginDate) <= 2014
 GROUP BY State, YEAR(BeginDate)
 ORDER BY State, YEAR(BeginDate)

您需要确定列来自哪个表

答案 1 :(得分:1)

我认为你需要一个左连接。如果您的DT_FatalityEvent表仅包含您正在执行内部联接的死亡事件的记录,则它可能应该是左联接,如解释here

以下是我将如何编码查询的示例。 (注意:我通常对表进行别名,以便更容易知道您在SELECT子句中引用了哪些表。)

我还假设您为每个活动设置了NumberOfFatalities,在这种情况下,您可能需要考虑使用SUM

SELECT 
  A.State,
  YEAR(A.BeginDate) [Year],
  SUM(ISNULL(B.NumberOfFatalities,0)) [Fatalities]
FROM
  DT_Event A 
LEFT JOIN
  DT_FatalityEvent B ON A.EventId = B.EventID
WHERE 
  A.EventType like'%tornado%'
  AND YEAR(A.BeginDate) >= 1995 AND YEAR(A.BeginDate) <= 2014
GROUP BY 
  A.State, YEAR(A.BeginDate)
ORDER BY 
  A.State, YEAR(A.BeginDate)

这将确保您从DT_Event表获取记录,即使没有匹配的EventID的DT_FatalityEvent记录也是如此。在这些情况下,NumberOfFatalities字段(我的猜测)将为NULL,因此在使用SUM之前,您应该确保值为0.

答案 2 :(得分:0)

非常感谢快速回复。我肯定会接受Blam所说的关于使用别名的内容,因为这样可以更轻松地编写代码,所以感谢您的建议。我太复杂了,事实上bigtlb说没有必要使用YearValues表。

这是完成我需要的代码!

SELECT
    A.State,
    YEAR(A.BeginDate),
    COUNT(B.EventID)
FROM [StormEvents].[dbo].[DT_Event] A
LEFT JOIN [StormEvents].[dbo].[DT_FatalityEvent] B
    ON
        A.EventID = B.EventID
        AND A.EventType like '%tornado%'
GROUP BY State, YEAR(A.BeginDate)
ORDER BY State, YEAR(A.BeginDate)

感谢所有人&#39;建议! 麦克