如何使用自定义列对连接表进行分组

Posted

技术标签:

【中文标题】如何使用自定义列对连接表进行分组【英文标题】:How to group on a join table with custom columns 【发布时间】:2021-07-20 11:42:08 【问题描述】:

我是 SQL 新手,我似乎被困在应该很简单的事情上。

假设我有两个包含以下信息的表:

用途:

Date User Metric1 Metric2
2021-07-20 John Doe 200 400
2021-07-20 XYZ 100 180
2021-07-20 ABC 20 600

原始数据

Date Account Item_ID
2021-07-20 10:30:00 XYZ 1
2021-07-20 11:31:00 XYZ 2
2021-07-20 12:30:00 John Doe 3
2021-07-20 13:30:00 John Doe 4
2021-07-20 14:30:00 ABC 5

我在这里想要实现的是,将这两者结合起来,为员工显示给定日期的 Item_ID 计数:

Date User Metric1 Metric2 Counter
2021-07-20 John Doe 200 400 2
2021-07-20 XYZ 100 180 2
2021-07-20 ABC 20 600 1

可悲的是,以下内容会出现以下错误:

列 Raw_Data.Date 在选择列表中无效,因为它不是 包含在聚合函数或 GROUP BY 子句中。

这是我尝试过的查询:

select
util.*,
count(rd.Item_ID) as Counter

from Utilisation util
join Raw_Data rd
on util.Date = cast(rd.Date as date)
where util.Date>='2021-07-19'

group by util.Date, util.User;

我的主要怀疑是我尝试了错误的联接类型,或者组部分杀死了结果,但是我找不到解决方案。

【问题讨论】:

所有字段必须分组或聚合。将您的 select *.. 替换为 select field1, field2... 并按所有非聚合字段分组。 您不需要在加入中包含帐户吗? @SMor 更新了查询,但没有改变结果。 没关系,我很愚蠢 - 在我按非聚合的所有内容分组后它起作用了。谢谢,@Arvo! 【参考方案1】:

这是简单的连接。试试这个

表和数据脚本供想尝试的人使用

create table #Utilisation([Date] date,  [User] varchar(30),     Metric1 int, Metric2 int)
insert into #Utilisation values('2021-07-20',   'John Doe', 200,    400),('2021-07-20', 'XYZ',  100,    180),('2021-07-20', 'ABC',  20, 600)

create table #Raw_Data ([Date] datetime,    Account varchar(30), Item_ID int)
insert into #Raw_Data values ('2021-07-20 10:30:00',    'XYZ',  1),('2021-07-20 11:31:00',  'XYZ',  2),('2021-07-20 12:30:00',  'John Doe', 3),('2021-07-20 13:30:00',  'John Doe', 4), ('2021-07-20 14:30:00', 'ABC',  5)

解决方案脚本

SELECT U.[Date], U.[User], U.Metric1, U.Metric2, R.Counter
FROM #Utilisation U
INNER JOIN (
    SELECT CONVERT(DATE, [DATE])[date], Account, Count(Item_ID)counter
    FROM #Raw_Data
    group by CONVERT(DATE, [DATE]), Account
) R ON U.Date = R.date AND U.[User] = R.Account

如果您想要 Utilization 表中的所有记录,以防 raw_data 表不包含该 dat 和帐户的任何数据,则使用左外连接而不是内连接。

【讨论】:

【参考方案2】:

一个简单的方法是关联子查询:

select u.*,
       (select count(*)
        from Raw_Data rw
        where rw.account = u.user and
              rw.date >= u.date and
              rw.date < dateadd(day, u.date, 1)
       ) as cnt
from utilisation u
where u.date = '2021-07-20'

为了提高性能,您可能需要在Row_Data(account, date) 上建立索引。

【讨论】:

以上是关于如何使用自定义列对连接表进行分组的主要内容,如果未能解决你的问题,请参考以下文章

Oracle:如何在获取结果之前按某些列对记录进行分组

您如何优化连接自身并执行“自定义”分组的 MySQL 查询?

按 2 列对表进行分组并优先考虑非空值?

如何使用laravel中其他表中的列对数据进行排序

SQL:按选定列对记录进行分组

如何按列对pyspark中的数据框进行分组并以该列作为键并以记录列表作为其值来获取字典?