Несколько запросов к одной производной таблице?

#mysql #derived

#mysql #производная

Вопрос:

У меня есть запрос, который выглядит следующим образом, и он дает кучу информации

 mysql> SELECT impacted.incident_id AS id,
    -> impacted.severity_id as sev,
    -> ((UNIX_TIMESTAMP(incident.stable_time) - UNIX_TIMESTAMP(incident.start_time)) / 60) AS duration,
    -> ops.department.name AS department,
    -> ops.country.name AS country
    -> FROM incident
    -> LEFT JOIN incident_impactedDepartments AS impacted ON incident.incident_id = impacted.incident_id
    -> LEFT JOIN incident_impacted ON incident.incident_id = incident_impacted.incident_id
    -> LEFT JOIN ops.department ON impacted.dept_id = ops.department.dept_id
    -> LEFT JOIN ops.country ON incident_impacted.entity_id = ops.country.country_id
    -> WHERE incident.status in ('OPEN','STABLE','ALL CLEAR','POST MORTEM COMPLETE')
    -> AND incident.incident_id in (35880,35992,33304);
 ------- ------ ----------- ------------------- --------------- 
| id    | sev  | duration  | department          | country       |
 ------- ------ ----------- ------------------- --------------- 
| 33304 |    1 |   29.0000 | Marketing         | NULL          | 
| 33304 |    1 |   29.0000 | Marketing         | GLOBAL        | 
| 33304 |    1 |   29.0000 | Accounting        | NULL          | 
| 33304 |    1 |   29.0000 | Accounting        | GLOBAL        | 
| 35880 |    1 |  109.5833 | Marketing         | Argentina     | 
| 35880 |    1 |  109.5833 | Marketing         | Brazil        | 
| 35880 |    1 |  109.5833 | Marketing         | Canada        | 
| 35880 |    1 |  109.5833 | Marketing         | Chile         | 
| 35880 |    1 |  109.5833 | Marketing         | Mexico        | 
| 35880 |    1 |  109.5833 | Marketing         | Peru          | 
| 35880 |    1 |  109.5833 | Marketing         | United States | 
| 35880 |    1 |  109.5833 | Accounting        | Argentina     | 
| 35880 |    1 |  109.5833 | Accounting        | Brazil        | 
| 35880 |    1 |  109.5833 | Accounting        | Canada        | 
| 35880 |    1 |  109.5833 | Accounting        | Chile         | 
| 35880 |    1 |  109.5833 | Accounting        | Mexico        | 
| 35880 |    1 |  109.5833 | Accounting        | Peru          | 
| 35880 |    1 |  109.5833 | Accounting        | United States | 
| 35880 |    2 |  109.5833 | Finance           | Argentina     | 
| 35880 |    2 |  109.5833 | Finance           | Brazil        | 
| 35880 |    2 |  109.5833 | Finance           | Canada        | 
| 35880 |    2 |  109.5833 | Finance           | Chile         | 
| 35880 |    2 |  109.5833 | Finance           | Mexico        | 
| 35880 |    2 |  109.5833 | Finance           | Peru          | 
| 35880 |    2 |  109.5833 | Finance           | United States | 
| 35992 |    3 | 1295.2667 | Accounting        | Italy         | 
 ------- ------ ----------- ------------------- --------------- 
 

Вы можете видеть, что инцидент 35880 влияет на финансы 7 стран. Моя цель — собрать следующую информацию для каждого инцидента.

  ------- ------ ---------- ------------------------------ --------------------------------------------------------- 
| id    | sev  | duration | department                   | country                                                 |
 ------- ------ ---------- ------------------------------ --------------------------------------------------------- 
| 35880 |    1 | 109.5833 | Marketing,Accounting,Finance | Argentina,Brazil,Canada,Chile,Mexico,Peru,United States | 
 ------- ------ ---------- ------------------------------ --------------------------------------------------------- 
 

И я могу сделать это с помощью такого запроса, как этот:

 SELECT id, sev, duration, GROUP_CONCAT(DISTINCT department SEPARATOR ',') as department, GROUP_CONCAT(DISTINCT country SEPARATOR ',') as country
FROM
(SELECT impacted.incident_id AS id,
impacted.severity_id as sev,
((UNIX_TIMESTAMP(incident.stable_time) - UNIX_TIMESTAMP(incident.start_time)) / 60) AS duration,
ops.department.name AS department,
ops.country.name AS country
FROM incident
LEFT JOIN incident_impactedDepartments AS impacted ON incident.incident_id = impacted.incident_id
LEFT JOIN incident_impacted ON incident.incident_id = incident_impacted.incident_id
LEFT JOIN ops.department ON impacted.dept_id = ops.department.dept_id
LEFT JOIN ops.country ON incident_impacted.entity_id = ops.country.country_id
WHERE incident.status in ('OPEN','STABLE','ALL CLEAR','POST MORTEM COMPLETE')
AND incident.incident_id in (35880))
AS q1
 

Но извлекаемая серьезность — это серьезность для id 35880 в целом. Видите ли, 35880 повлиял на несколько отделов на разных уровнях, и я хочу иметь возможность видеть серьезность для конкретного отдела, запрашивающего в зависимости от серьезности главного идентификатора. Однако, если я укажу идентификатор отдела в запросе, это все испортит.

 mysql> SELECT id, sev, duration, GROUP_CONCAT(DISTINCT department SEPARATOR ',') as department, GROUP_CONCAT(DISTINCT country SEPARATOR ',') as country
    -> FROM
    -> (SELECT impacted.incident_id AS id,
    -> impacted.severity_id as sev,
    -> ((UNIX_TIMESTAMP(incident.stable_time) - UNIX_TIMESTAMP(incident.start_time)) / 60) AS duration,
    -> ops.department.name AS department,
    -> ops.country.name AS country
    -> FROM incident
    -> LEFT JOIN incident_impactedDepartments AS impacted ON incident.incident_id = impacted.incident_id
    -> LEFT JOIN incident_impacted ON incident.incident_id = incident_impacted.incident_id
    -> LEFT JOIN ops.department ON impacted.dept_id = ops.department.dept_id
    -> LEFT JOIN ops.country ON incident_impacted.entity_id = ops.country.country_id
    -> WHERE incident.status in ('OPEN','STABLE','ALL CLEAR','POST MORTEM COMPLETE')
    -> AND incident.incident_id in (35880)
    -> AND impacted.dept_id = 1473)
    -> AS q1;
 ------- ------ ---------- ------------ --------------------------------------------------------- 
| id    | sev  | duration | department | country                                                 |
 ------- ------ ---------- ------------ --------------------------------------------------------- 
| 35880 |    2 | 109.5833 | Finance    | Argentina,Brazil,Canada,Chile,Mexico,Peru,United States | 
 ------- ------ ---------- ------------ --------------------------------------------------------- 
 

Я больше не получаю полный список затронутых отделов.

Потребуется ли для этого два отдельных запроса?

Комментарии:

1. Вы могли бы сделать max(case dept_id when 1473 then sev end) , что дало бы вам серьезность для конкретного отдела, сохраняя при этом группировку такой же, как и раньше.

2. Куда в запросе я должен добавить это утверждение?

3. Какой sev? «ВЫБЕРИТЕ id, sev» или «impacted.severity_id как sev»? Я попробовал оба и получил «ОШИБКА 1054 (42S22): неизвестный столбец ‘sev’ в ‘списке полей»

Ответ №1:

Я не уверен, что полностью понимаю ваш запрос, но я надеюсь, что любое из приведенных ниже действий может помочь:

Запрос 1:

 SELECT id, sev, sev1, duration, GROUP_CONCAT(DISTINCT department SEPARATOR ',') as department, GROUP_CONCAT(DISTINCT country SEPARATOR ',') as country
FROM
(SELECT impacted.incident_id AS id, impacted.severity_id as sev, impacted1.severity_id as sev1, ((UNIX_TIMESTAMP(incident.stable_time) - UNIX_TIMESTAMP(incident.start_time)) / 60) AS duration, ops.department.name AS department,
ops.country.name AS country
FROM incident
LEFT JOIN incident_impactedDepartments AS impacted ON incident.incident_id = impacted.incident_id
LEFT JOIN incident_impactedDepartments AS impacted1 ON incident.incident_id = impacted1.incident_id AND impacted1.dept_id = 1473
LEFT JOIN incident_impacted ON incident.incident_id = incident_impacted.incident_id
LEFT JOIN ops.department ON impacted.dept_id = ops.department.dept_id
LEFT JOIN ops.country ON incident_impacted.entity_id = ops.country.country_id
WHERE incident.status in ('OPEN','STABLE','ALL CLEAR','POST MORTEM COMPLETE')
AND incident.incident_id in (35880))
AS q1;
 

Запрос 2:

 SELECT id, sev, duration, GROUP_CONCAT(DISTINCT department SEPARATOR ',') as department, GROUP_CONCAT(DISTINCT country SEPARATOR ',') as country
FROM
(SELECT impacted.incident_id AS id, impacted.severity_id as sev, ((UNIX_TIMESTAMP(incident.stable_time) - UNIX_TIMESTAMP(incident.start_time)) / 60) AS duration, ops.department.name AS department,
ops.country.name AS country
FROM incident
LEFT JOIN incident_impactedDepartments AS impacted ON incident.incident_id = impacted.incident_id
LEFT JOIN incident_impacted ON incident.incident_id = incident_impacted.incident_id
LEFT JOIN ops.department ON impacted.dept_id = ops.department.dept_id
LEFT JOIN ops.country ON incident_impacted.entity_id = ops.country.country_id
WHERE incident.status in ('OPEN','STABLE','ALL CLEAR','POST MORTEM COMPLETE')
AND incident.incident_id in (35880))
AS q1
GROUP BY department;
 

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

Комментарии:

1. # 2 близко. Он возвращает 4 строки, каждая с отделом и страной, в виде списка затронутых стран, разделенных запятыми. В идеале у меня будет одна строка и два списка, разделенных запятыми, по одному для каждой страны и отдела, затем я бы запросил incident_impactedDepartments с идентификатором инцидента (35880) и отдела (одного из перечисленных в затронутых отделах) и получил идентификатор серьезности этой комбинации. Я не думаю, что это сработает.

2. О’кей, я внес небольшую поправку в №1. Кажется ли это ближе сейчас? Еще раз прошу прощения, я все еще не до конца понимаю, как вы хотели бы получить желаемый результат. На основе набора данных, который вы указали в вопросе, можете ли вы, возможно, дать снимок того, как бы вы хотели, чтобы результирующий набор выглядел?