Как посчитать разные значения из двух столбцов в одно число (продолжение) - PullRequest
2 голосов
/ 10 марта 2020

Это дополнительный вопрос к Как посчитать отдельные значения из двух столбцов в одно число

Я хотел знать, как выполнить подсчет, и пренебрег тем, что я уже присоединяюсь некоторые другие таблицы в миксе.

Ответ на предыдущий вопрос является правильным для этого случая.

Вот моя дополнительная проблема.

У меня 3 таблицы :

Назначения

+----+-------------------+
| id |       name        |
+----+-------------------+
| 1  | first-assignment  |
| 2  | second-assignment |
+----+-------------------+

Представления

+----+---------------+------------+
| id | assignment_id | student_id |
+----+---------------+------------+
|  1 |             1 |          2 |
|  2 |             2 |          1 |
|  3 |             1 |          3 |
+----+---------------+------------+

Group_submissions

+----+---------------+------------+
| id | submission_id | student_id |
+----+---------------+------------+
| 1  |             1 |          1 |
| 2  |             2 |          2 |
+----+---------------+------------+

Каждое представление относится к назначению.

Заявки могут быть индивидуальной или групповой.

Когда они индивидуальны, тот, кто отправил заявку в назначении (assignment_id), попадает в таблицу представлений (student_id)

Когда они групповые Представление то же самое происходит с двумя дополнительными деталями:

  1. Тот, кто выполняет отправку, попадает в таблицу представлений
  2. Остальные go в группу таблицы p_submissions и связаны с идентификатором в таблице представлений (поэтому submission_id - это FK из таблицы представлений)

Я хочу вернуть каждое задание с его столбцами, но также добавить количество студентов, которые сделали представления в этом назначении. Помните, что учащиеся, которые не подали заявку (не находятся в таблице подачи заявок), но участвовали в групповой подаче заявки (находятся в таблице group_submissions), также считают

Примерно так:

+----+-------------------+----------+
| id |       name        | students |
+----+-------------------+----------+
| 1  | first-assignment  |       11 |
| 2  | second-assignment |        2 |
+----+-------------------+----------+

Я попробовал 2 способа получения чисел:

count(distinct case when group_submissions.student_id is not null then
group_submissions.student_id when assignment_submissions.student_id is
not null then assignment_submissions.student_id end)

Это не работает, потому что инструкция case будет коротко замкнута, как только будет выполнено первое условие. Например: если один студент сделал групповые представления, но фактически никогда не делал представления, он / она будет отображаться только в таблице group_submissions. Таким образом, если в таблице представлений идентификатор равен 1, а в таблице group_submission идентификатор равен 2, а идентификатор 2 не встречается в таблице представлений, он не будет засчитан.

count(distinct case when group_submissions.student_id is not null then group_submissions.student_id end) 
+ count(distinct case when submissions.student_id is not null then submissions.student_id end)

Это не работать, потому что он дает дубликаты, если ученик находится в обеих таблицах.

ПРИМЕЧАНИЕ: Это MySQL база данных

Ответы [ 3 ]

1 голос
/ 10 марта 2020

Поскольку вы не можете изменить данные, вам нужно использовать подзапрос UNION, а затем агрегировать по нему.

SELECT a.id, a.name, COUNT(DISTINCT x.student_id) AS students
FROM Assignments AS a
LEFT JOIN (
   SELECT assignment_id, student_id FROM Submissions
   UNION 
   SELECT s.assignment_id, g.student_id
   FROM Submissions AS s
   INNER JOIN Group_submissions AS g ON s.id = g.submission_id
) AS x ON a.id = x.assignment_id
GROUP BY a.id, a.name
;

Редактировать: первая часть vhu лучше, если вы не можете иметь задание X, предоставленное студентом Y с кредитом group_submission студента Z, и другое для задания X, представленного непосредственно студентом Z или имеющим кредит group_submission или студента Y (потому что тогда они будут учитываться дважды).

1 голос
/ 10 марта 2020

Вы уже пометили вопрос как mysqk, номер версии обычно также интересен для хорошего ответа

следующее дает вам правильный ответ

SELECT  
  a.id,a.name
  , LENGTH(CONCAT(GROUP_CONCAT(s.`student_id`) ,IF(GROUP_CONCAT(gs.student_id) is NULL,'',','),IF(GROUP_CONCAT(gs.student_id) is NULL,'',GROUP_CONCAT(gs.student_id))))
   - LENGTH(REPLACE(CONCAT(GROUP_CONCAT(s.`student_id`) ,IF(GROUP_CONCAT(gs.student_id) is NULL,'',','),IF(GROUP_CONCAT(gs.student_id) is NULL,'',GROUP_CONCAT(gs.student_id))), ',', '')) + 1 as count_studints
FROM 
  Submissions s 
  LEFT JOIN Group_submissions gs ON gs.submission_id = s.id 
  INNER JOIN Assignments a on s.assignment_id = a.id
WHERE s.`student_id` NOT IN (SELECT student_id 
                           FROM Group_submissions gs 
                           WHERE gs.submission_id = s.id)
GROUP BY a.id,a.name;
CREATE TABLE Group_submissions (
  `id` INTEGER,
  `submission_id` INTEGER,
  `student_id` INTEGER
);

INSERT INTO Group_submissions
  (`id`, `submission_id`, `student_id`)
VALUES
  ('1', '1', '1'),
  ('2', '2', '2');

CREATE TABLE Submissions (
  `id` INTEGER,
  `assignment_id` INTEGER,
  `student_id` INTEGER
);

INSERT INTO Submissions
  (`id`, `assignment_id`, `student_id`)
VALUES
  ('1', '1', '2'),
  ('2', '2', '1'),
  ('3', '1', '3'),
  ('4', '3', '1');

CREATE TABLE Assignments (
  `id` INTEGER,
  `name` VARCHAR(17)
);

INSERT INTO Assignments
  (`id`, `name`)
VALUES
  ('1', 'first-assignment'),
  ('2', 'second-assignment'),
  ('3', 'third-assignment');
✓

✓

✓

✓

✓

✓
SELECT  
  a.id,a.name
  , LENGTH(CONCAT(GROUP_CONCAT(s.`student_id`) ,IF(GROUP_CONCAT(gs.student_id) is NULL,'',','),IF(GROUP_CONCAT(gs.student_id) is NULL,'',GROUP_CONCAT(gs.student_id))))
   - LENGTH(REPLACE(CONCAT(GROUP_CONCAT(s.`student_id`) ,IF(GROUP_CONCAT(gs.student_id) is NULL,'',','),IF(GROUP_CONCAT(gs.student_id) is NULL,'',GROUP_CONCAT(gs.student_id))), ',', '')) + 1 as count_studints
from 
  Submissions s 
  LEFT JOIN Group_submissions gs ON gs.submission_id = s.id 
  INNER JOIN Assignments a on s.assignment_id = a.id
WHERE s.`student_id` NOT IN (SELECT student_id 
                           FROM Group_submissions gs 
                           WHERE gs.submission_id = s.id)
GROUP BY a.id,a.name;
id | name              | count_studints
-: | :---------------- | -------------:
 1 | first-assignment  |              3
 2 | second-assignment |              2
 3 | third-assignment  |              1

дБ <> скрипка здесь

1 голос
/ 10 марта 2020

Поскольку учащиеся либо в submissions таблице, либо в group_submissions, вы можете просто присоединиться к таблицам и добавить столбцы:

SELECT a.id,COUNT(s.student_id)+COUNT(gs.student_id) FROM assignments a
JOIN submissions s ON a.id = s.assignment_id
LEFT JOIN group_submissions gs ON s.id = gs.submission_id
GROUP BY a.id;

Если есть дубликаты, то есть учащиеся могут быть оба в submissions и group_submissions таблиц, затем вы можете объединить два и выбрать оттуда:

SELECT assignment_id,COUNT(DISTINCT student_id)
FROM (
    SELECT assignment_id,student_id
    FROM submissions
    UNION
    SELECT assignment_id,gs.student_id
    FROM group_submissions gs
        JOIN submissions s on gs.submission_id = s.id) T1
GROUP BY assignment_id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...