左连接:当有重复时,如何仅在连接时使用左表中的一个值?

时间:2016-06-23 14:16:21

标签: sql sql-server join

我在这里已经阅读了很多关于SQL连接的答案,但我似乎无法找到解决这个问题的任何东西。我有两张桌子要加入。第一个(j_weather)是天气数据。它包含一个日期时间字段(称为'有效'),每小时至少有一个条目,但通常不止一个。第二个表(j_collisions)包含交通事故的警察记录数据。它有一个日期和时间字段(称为' date_time'),它被莫名其妙地格式化为字符串(我没有创建表)。但是到目前为止,我已经能够使用子字符串函数解决这个问题(这在我下面的SQL查询中很明显)。这两个日期/时间字段都被格式化了#yyyy-MM-dd HH:ss'

我想要的结果是数据集中每小时的流量冲突数量:

date_hour        | collisions
-----------------|------------
2005-12-01 00:00 |     0
2005-12-01 01:00 |     0
2005-12-01 02:00 |     1
2005-12-01 03:00 |     1
2005-12-01 04:00 |     0
2005-12-01 05:00 |     1

如果该小时没有碰撞,则应返回零。我不能只从j_collisions表中做一个选择,因为在分析期间每小时都没有崩溃,我希望每小时都能显示,即使它只显示零崩溃。

这是我构建的查询:

select
    format(w.valid, 'yyyy-MM-dd HH') + ':00' as date_hour,
    count(c.master_file_number) as collisions
from
    hollings.dbo.j_weather as w
left join
    hollings.dbo.j_collisions as c
on
    format(w.valid, 'yyyy-MM-dd HH') = substring(c.date_time, 1, 13)
group by
    format(w.valid, 'yyyy-MM-dd HH')
order by
    date_hour

但是,正如我上面提到的,一些小时有多个天气读数记录。因此,例如,如果2005-12-01的03:00有三个天气读数,我的结果将(错误地)读取如下,而不是上面正确的预期结果。注意03:00时3次碰撞的结果,而不是正确的1次碰撞。

date_hour        | collisions
-----------------|------------
2005-12-01 00:00 |     0
2005-12-01 01:00 |     0
2005-12-01 02:00 |     1
2005-12-01 03:00 |     3
2005-12-01 04:00 |     0
2005-12-01 05:00 |     1

我是SQL的初学者,但我尝试了很多我想到的/在线发现的选项。如果我错过了任何细节,我会提前道歉,这是我第一次在这里问一个问题。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

尝试使用count(distinct c.master_file_number)

select
    format(w.valid, 'yyyy-MM-dd HH') + ':00' as date_hour,
    count(distinct c.master_file_number) as collisions
from
    hollings.dbo.j_weather as w
left join
    hollings.dbo.j_collisions as c
on
    format(w.valid, 'yyyy-MM-dd HH') = substring(c.date_time, 1, 13)
group by
    format(w.valid, 'yyyy-MM-dd HH')
order by
    date_hour

答案 1 :(得分:0)

试试这个......

SELECT *
    FROM
    (   select
            format(w.valid, 'yyyy-MM-dd HH') + ':00' as date_hour,
            count(c.master_file_number) as collisions,
            ROW_NUMBER() OVER(PARTITION BY format(w.valid, 'yyyy-MM-dd HH') ORDER BY c.master_file_number ) AS RowNo
        from
            hollings.dbo.j_weather as w
        left join
            hollings.dbo.j_collisions as c
        on
            format(w.valid, 'yyyy-MM-dd HH') = substring(c.date_time, 1, 13)
        group by
            format(w.valid, 'yyyy-MM-dd HH')
    ) xx
    where RowNo = 1
    order by
        date_hour