【问题标题】:Aggregate and count disctinct values with a join使用连接聚合和计算不同的值
【发布时间】:2020-06-28 21:37:12
【问题描述】:

这个问题是这些重复的混合:

我只是无法一次完成所有工作。

我有两张桌子:

TABLE A
IntervalId    Starts  Ends
-------------------------
1              0      10
2             10      25
3             25      32
4             32      40

TABLE B
Id            ErrorType    Starts    Ends
----------------------------------------
1                   666       0      25
2                   666       10     32
3                   777       0      32
4                   666       25     40
5                   777       10     25

从表 B 中的时间间隔开始,我试图计数并列出,在每个时间间隔内,可能在该时间间隔内发生的错误类型。并删除重复项

请注意,表 B 中没有任何表 A 中不存在的 Start 或 End(表 A 是从它们生成的)。

结果重复会是这样的:

Starts      Ends        ErrorsCount      Errors
-----------------------------------------------
0           10          2                 666, 777
10          25          4                 666, 666, 777, 777
25          32          3                 666, 777, 666
32          40          1                 666

我正在寻找的结果是没有重复

Starts      Ends        DistinctErrorsCnt  DistinctErrors
-----------------------------------------------
0           10          2                 666, 777
10          25          2                 666, 777
25          32          2                 666, 777
32          40          1                 666

这是我的 attemot,但我无法理解如何在没有 SQL 服务器抱怨它不在聚合或分组中的情况下从执行“不同”的位中获取 ErrorType。或者,一旦我将它放入 Group by,那么所有不同的错误类型都会被第一个出现的错误类型擦除。我最终到处只有 666 个。

SELECT 
    IntervalId,
    Starts,
    Ends,
    COUNT([TableB].ErrorType) as DistinctErrorsCnt,
    DistinctErrors= STRING_AGG([TableB].ErrorType, ',')
FROM
(
    SELECT DISTINCT  
        [TableA].IntervalId,

    FROM TableB LEFT JOIN TableA ON
        (
            [TableA].Starts= [TableB].Starts
        OR [TableA].Ends = [TableB].Ends
        OR ([TableA].Starts >= [TableB].Starts AND [TableA].Ends <= [TableB].Ends)

        )
    GROUP BY 
        [TableA].IntervalId,
        [TableA].Starts, 
        [TableA].Ends, 
) NoDuplicates
GROUP BY 
    NoDuplicates.IntervalId,
    NoDuplicates.Starts, 
    NoDuplicates.Starts

再次重申:由于我在上面解释过的原因,这在语法上不正确。

【问题讨论】:

  • STRING_AGG(DISTINCT...) 在 SQL 服务器中不存在

标签: sql sql-server tsql group-by distinct


【解决方案1】:

你可以使用聚合:

select 
    a.starts,
    a.ends,
    count(distinct b.errorType) DistinctErrorsCnt,
    string_agg(b.errorType, ', ') within group(order by b.starts) DistinctErrors
from tablea a
inner join tableb b on b.starts >= a.ends and b.ends <= a.start
group by a.intervalId, a.start, a.end

如果您想避免重复,可以使用子查询,或者更好的是cross apply

select
    a.starts,
    a.ends,
    count(*) DistinctErrorsCnt,
    string_agg(b.errorType, ', ') within group(order by b.starts) DistinctErrors
from tablea a
cross apply (
    select distinct errorType from tableb b where b.starts >= a.ends and b.ends <= a.start
) b
group by a.intervalId, a.start, a.end

【讨论】:

  • 尽管别名 b 被使用了两次并且 b.starts 需要被替换为带有 string_agg 的行上的 a.starts,这仍然有效。谢谢!
猜你喜欢
  • 2013-06-10
  • 2012-10-11
  • 2020-08-10
  • 2018-07-30
  • 2013-09-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
相关资源
最近更新 更多