使用 Count + STRING_AGG,显示不同的值
Using Count + STRING_AGG, to display distinct values
我正在尝试将 COUNT
与 STRING_AGG
一起使用。问题是,在子查询中,它根据需要进行计数,当有 1 名员工参加课程时,我的计数为 1,但是当我 运行 完整查询时,我得到的结果翻了一番,如下所示:
COMPLETED: 1, COMPLETED: 1
当我将 DISTINCT
计入 STRING_AGG
时,它给我一个错误。知道如何实现吗?
SELECT s1.course_id
, s1.course_name
, STRING_AGG(CONCAT(ts.training_status_name
+ ': ' +
CAST(countt as varchar), ''),', ') AS num_of_attendies_and_status
FROM (
SELECT th.course_id
, c.course_name
, COUNT(DISTINCT e.employee_id) AS countt
FROM course as c
INNER JOIN training_history th ON c.course_id = th.course_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY th.course_id, course_name
) s1
INNER JOIN training_history th ON s1.course_id = th.course_id
INNER JOIN training_status ts ON th.training_status_id = ts.training_status_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY s1.course_id
, s1.course_name
输出示例:
Course_id
Course_name
num_of_attendies_and_status
5
React
COMPLETED: 1, COMPLETED: 1
7
C#
COMPLETED: 1, COMPLETED: 1
9
Selenium
REGISTERED: 1, REGISTERED: 1
13
Finance
IN PROGRESS: 1, IN PROGRESS: 1
我有 table 名员工,员工姓名为 employee_id,课程 ID 为 training_history,这是 course_id 和 employee_id 之间的链接,和培训状态,根据课程 ID 显示课程状态名称。我这里有 3 个状态:完成、注册、进行中。
问题是,当我 运行 子查询时:
SELECT th.course_id
, c.course_name
, COUNT(DISTINCT e.employee_id) AS countt
FROM course as c
INNER JOIN training_history th ON c.course_id = th.course_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY th.course_id
, course_name
我得到以下输出:
Course_id
Course_name
num_of_attendies_and_status
5
React
1
7
C#
1
9
Selenium
1
13
Finance
1
但是第一个查询的最后一个,翻了一番。问题是有 2 名重复的相同员工。所以我需要以某种方式区分它们。在子查询中 COUNT(DISCTINCT employee_id)
工作正常。但是在主查询中,它翻了一番。对于难以理解的问题,我深表歉意。希望有什么是清楚的。
我用 CTE 收集了 count(distinct)
的信息。
注意,我在您的示例数据中添加了一些行,使每门课程有 2 个状态。
with training as
(SELECT
c.course_id,
c.course_name,
th.training_status_id as t_status_id,
count(distinct employee_id) as count_emp
from dbo.course c
join dbo.training_history th on c.course_id = th.course_id
group by
c.course_id,
c.course_name,
th.training_status_id)
select
t.course_id,
t.course_name,
string_agg(concat(ts.training_status_name,':',count_emp),',') as num_of_attendies_and_status
from training t
join dbo.training_status ts
on t.t_status_id = ts.training_status_id
group by
t.course_id,
t.course_name
;
course_id | course_name | num_of_attendies_and_status
--------: | :----------------------------------------------------------- | :-----------------------------
5 | React - The Complete Guide (incl Hooks, React Router, Redux) | COMPLETED: 1, COMPLETED: 1
7 | Learn Parallel Programming with C# and .NET | COMPLETED: 1, COMPLETED: 1
9 | Selenium WebDriver with Docker, Jenkins & AWS | REGISTERED: 1, REGISTERED: 1
13 | Finance for Non Finance Executives | IN PROGRESS: 1, IN PROGRESS: 1
*db<>fiddle here5dab7f3db67ba78a)
我正在尝试将 COUNT
与 STRING_AGG
一起使用。问题是,在子查询中,它根据需要进行计数,当有 1 名员工参加课程时,我的计数为 1,但是当我 运行 完整查询时,我得到的结果翻了一番,如下所示:
COMPLETED: 1, COMPLETED: 1
当我将 DISTINCT
计入 STRING_AGG
时,它给我一个错误。知道如何实现吗?
SELECT s1.course_id
, s1.course_name
, STRING_AGG(CONCAT(ts.training_status_name
+ ': ' +
CAST(countt as varchar), ''),', ') AS num_of_attendies_and_status
FROM (
SELECT th.course_id
, c.course_name
, COUNT(DISTINCT e.employee_id) AS countt
FROM course as c
INNER JOIN training_history th ON c.course_id = th.course_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY th.course_id, course_name
) s1
INNER JOIN training_history th ON s1.course_id = th.course_id
INNER JOIN training_status ts ON th.training_status_id = ts.training_status_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY s1.course_id
, s1.course_name
输出示例:
Course_id | Course_name | num_of_attendies_and_status |
---|---|---|
5 | React | COMPLETED: 1, COMPLETED: 1 |
7 | C# | COMPLETED: 1, COMPLETED: 1 |
9 | Selenium | REGISTERED: 1, REGISTERED: 1 |
13 | Finance | IN PROGRESS: 1, IN PROGRESS: 1 |
我有 table 名员工,员工姓名为 employee_id,课程 ID 为 training_history,这是 course_id 和 employee_id 之间的链接,和培训状态,根据课程 ID 显示课程状态名称。我这里有 3 个状态:完成、注册、进行中。
问题是,当我 运行 子查询时:
SELECT th.course_id
, c.course_name
, COUNT(DISTINCT e.employee_id) AS countt
FROM course as c
INNER JOIN training_history th ON c.course_id = th.course_id
INNER JOIN employee e ON th.employee_id = e.employee_id
GROUP BY th.course_id
, course_name
我得到以下输出:
Course_id | Course_name | num_of_attendies_and_status |
---|---|---|
5 | React | 1 |
7 | C# | 1 |
9 | Selenium | 1 |
13 | Finance | 1 |
但是第一个查询的最后一个,翻了一番。问题是有 2 名重复的相同员工。所以我需要以某种方式区分它们。在子查询中 COUNT(DISCTINCT employee_id)
工作正常。但是在主查询中,它翻了一番。对于难以理解的问题,我深表歉意。希望有什么是清楚的。
我用 CTE 收集了 count(distinct)
的信息。
注意,我在您的示例数据中添加了一些行,使每门课程有 2 个状态。
with training as
(SELECT
c.course_id,
c.course_name,
th.training_status_id as t_status_id,
count(distinct employee_id) as count_emp
from dbo.course c
join dbo.training_history th on c.course_id = th.course_id
group by
c.course_id,
c.course_name,
th.training_status_id)
select
t.course_id,
t.course_name,
string_agg(concat(ts.training_status_name,':',count_emp),',') as num_of_attendies_and_status
from training t
join dbo.training_status ts
on t.t_status_id = ts.training_status_id
group by
t.course_id,
t.course_name
;
course_id | course_name | num_of_attendies_and_status --------: | :----------------------------------------------------------- | :----------------------------- 5 | React - The Complete Guide (incl Hooks, React Router, Redux) | COMPLETED: 1, COMPLETED: 1 7 | Learn Parallel Programming with C# and .NET | COMPLETED: 1, COMPLETED: 1 9 | Selenium WebDriver with Docker, Jenkins & AWS | REGISTERED: 1, REGISTERED: 1 13 | Finance for Non Finance Executives | IN PROGRESS: 1, IN PROGRESS: 1
*db<>fiddle here5dab7f3db67ba78a)