使用连接聚合和计算不同的值
Aggregate and count disctinct values with a join
这个问题是这些重复问题的混合:
- SQL/mysql - Select distinct/UNIQUE but return all columns?
我就是没办法让它同时工作。
我有两个 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
这个问题是这些重复问题的混合:
- SQL/mysql - Select distinct/UNIQUE but return all columns?
我就是没办法让它同时工作。
我有两个 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