SQL内部联接返回重复项

时间:2019-07-15 14:37:11

标签: sql join google-bigquery

我有以下2张桌子:

tab1有37146行 table1

week_ref有730行

table2

我要做的就是在年和周上连接这些表,以便第一个工作日和最后一个工作日将显示在第一个表的列旁边。

下面是我的查询:

SELECT tab1.year
      ,tab1.week
      ,tab1.col3
      ,tab1.col4
      ,tab1.col5
      ,tab1.col6
      ,tab1.total
      ,tab1.col7
      ,week_ref.first_week_day
      ,week_ref.last_week_day

FROM dtsetname.tab1

JOIN spyros.week_ref ON (week_ref.year = tab1.year AND week_ref.week = tab1.week)

查询的返回返回2个额外的列,但行为255535。因此,该行中充满了重复项。我过去常常了解join的工作原理,但我想不再是xd了……对此有任何帮助吗?正确的输出表应该只给我37146行,因为我只想添加2个额外的列。

谢谢

4 个答案:

答案 0 :(得分:1)

问题在于您的week_ref表每天而不是每周都有一行。

您只能选择一天。如果您有一个工作日的电话号码或姓名(我想是的话),可以使用:

FROM dtsetname.tab1 JOIN
     spyros.week_ref wr
     ON wr.year = tab1.year AND
        wr.week = tab1.week AND
        wr.dayname = 'Monday'

如果此类列不可用,则可以extract()信息或进行汇总:

FROM dtsetname.tab1 JOIN
     (SELECT ANY_VALUE(wr).*
      FROM spyros.week_ref wr
      GROUP BY wr.year, wr.week
     ) wr
     ON wr.year = tab1.year AND
        wr.week = tab1.week 

答案 1 :(得分:1)

以下是用于BigQuery标准SQL

在加入之前,您只需要在week_ref表中删除数据,如下例所示

#standardSQL
SELECT tab1.year
      ,tab1.week
      ,tab1.col3
      ,tab1.col4
      ,tab1.col5
      ,tab1.col6
      ,tab1.total
      ,tab1.col7
      ,week_ref.first_week_day
      ,week_ref.last_week_day
FROM dtsetname.tab1 tab1
JOIN (SELECT DISTINCT year, week, first_week_day, last_week_day FROM spyros.week_ref) week_ref
ON (week_ref.year = tab1.year AND week_ref.week = tab1.week) 

答案 2 :(得分:0)

首先,我希望year + week和year + day是相应表中的主键,否则问题就出现了。

如果是,这是另一个要检查的提示: 我注意到您按年和周加入了它们,但是,在第一个表中,我在一个星期列中看到许多52,在第二个表中看到0作为值。

一年只有52周,还有一天,所以您可能需要加入

week_ref.year = tab1.year AND week_ref.week = tab1.week+1

答案 3 :(得分:0)

如果您希望加入参考表以获取星期开始/结束日期,我认为其他人提到的解决方案应该可以使用。

但是,如果您认为tab1表中的weekyear列中有确定的值(并且如果我正确理解了您的数据),则可以完全避免联接获得所需的结果:

select 
  year
  ,week
  ,col3
  ,col4
  ,col5
  ,col6
  ,total
  ,col7
  ,date_sub(weekdate, interval IF(EXTRACT(DAYOFWEEK FROM weekdate) = 1, 6, EXTRACT(DAYOFWEEK FROM weekdate) - 1) day) as first_week_day
  ,date_add(date_sub(weekdate, interval IF(EXTRACT(DAYOFWEEK FROM weekdate) = 1, 6, EXTRACT(DAYOFWEEK FROM weekdate) - 1) day), interval 6 day) as last_week_day
from (  
  select 
     tab1.year
    ,tab1.week
    ,tab1.col3
    ,tab1.col4
    ,tab1.col5
    ,tab1.col6
    ,tab1.total
    ,tab1.col7
    date_add(date(cast(tab1.year as int64), 1, 1), interval cast(tab1.week as int64) week) as weekdate
  from `mydataset.tab1` as tab1
)

希望它会有所帮助:)