加入没有唯一标识符的 SQL

Posted

技术标签:

【中文标题】加入没有唯一标识符的 SQL【英文标题】:Join SQL without Unique Identifier 【发布时间】:2021-02-24 10:49:56 【问题描述】:

我有两张桌子:

表 A:

EmployeeID DailyHour Date
ID001 2 2021-02-01
ID001 4 2021-02-03
ID001 4 2021-02-04
ID001 4 2021-02-10
ID001 8 2021-02-15
ID002 8 2021-02-20

表 B:

EmployeeID Week StandardHours
ID001 2021-02-05 40
ID001 2021-02-12 40
ID001 2021-02-19 40
ID002 2021-02-12 40

我怎样才能得到每个EmployeeIDDailyHour, StandardHours 的总和(DateWeek 的范围内)

预期输出: 对于EmployeeID = ID001DateFeb 1 2021Feb 12 2021 之间

EmployeeID DailyHours StandardHours
ID001 14 80

提前谢谢你。

【问题讨论】:

先在子查询/CTE中单独聚合,然后JOIN 【参考方案1】:

您需要先聚合,然后然后 JOIN 根据员工 ID 聚合数据:

WITH Daily AS(
    SELECT EmployeeID,
           SUM(DailyHour) AS DailyHours
    FROM dbo.TableA
    WHERE [Date] >= '20200201'
      AND [Date] <= '20200212'
    GROUP BY EmployeeID),
Standard AS(
    SELECT EmployeeID,
           SUM(StandardHours) AS StandardHours
    FROM dbo.TableB
    WHERE [Week] >= '20200201'
      AND [Week] <= '20200212'
    GROUP BY EmployeeID)
SELECT D.EmployeeID,
       D.DailyHours,
       S.StandardHours
FROM Daily D
     JOIN Standard S ON D.EmployeeID = S.EmployeeID;

如果员工可能没有标准或每日工作时间,您需要使用LEFT JOINFULL OUTER JOIN,以及ISNULL(在SELECT 中)。

【讨论】:

【参考方案2】:

如果员工不在两个表中,这将变得很棘手。这为您提供了两种选择,其中一种是在加入之前使用 full join 和聚合 - 并且对于过滤到特定员工或日期范围变得很棘手。

另一个是union all 和聚合:

select employeeid, sum(dailyhour), sum(standardhours)
from ((select employeeid, date, dailyhour, null as standardhours
       from a
      ) union all
      (select employeeid, date, null as dailyhour, 
       from b
      )
     ) ab
where employeeid = 'ID001' and
      date >= '2021-02-01' and
      date <= '2021-02-12'
group by employeeid;

【讨论】:

以上是关于加入没有唯一标识符的 SQL的主要内容,如果未能解决你的问题,请参考以下文章

sql2005中设置字段属性时,如何设标识列(自增1)和必须唯一

使用带有 Linq to Sql 的 Sql Server 唯一标识符/更新日期列 - 最佳方法

HSQLDB 的 MS SQL“唯一标识符”数据类型的替代方案是啥?

SQL:如何选择每个唯一标识符的值最低的记录

将 XML 文件导入 SQL Server 时唯一标识符转换失败

JPA:如何映射 SQL Server 唯一标识符类型