使用连接聚合和计算不同的值

Aggregate and count disctinct values with a join

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

我就是没办法让它同时工作。

我有两个 tables :

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

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

请注意,table B 中没有任何 Start 或 End 在 Table A 中不存在(Table 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

这是我的注意事项,但我无法理解如何在没有 SQL 服务器抱怨它不在聚合或分组依据中的情况下从执行 "distinct" 的位中获取 ErrorType。或者,一旦我将其放入分组依据中,所有不同的错误类型就会被第一个出现的错误类型擦除。我最终到处都只有 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

再次声明:这在语法上是不正确的,原因我在上面已经解释过了。

您可以使用聚合:

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