Объединить два запроса с разными таблицами ‘FROM’, но похожими таблицами ‘JOIN’

#sql-server

#sql-сервер

Вопрос:

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

Запрос 1:

 SELECT t1.evalID, t2.[Order], COUNT(t2.StepID) AS 'Total Categories'
FROM Evals t1
JOIN Steps t2 ON t1.TemplateID = t2.TemplateID 
JOIN GradingCats t3 ON t2.StepID = t3.StepID 
GROUP BY t1.EvalID, t2.[Order]
ORDER BY t2.[Order]
  

Запрос 2:

 SELECT t4.EvaluatorID, t6.StepID, t6.[Order], COUNT(t4.Grade) AS 'Grades Entered'
FROM Grading t4
JOIN GradingCats t5 ON t4.GradingCatID = t5.GradingCatID 
JOIN Steps t6 ON t5.StepID = t6.StepID
GROUP BY t6.StepID, t4.EvaluatorID, t6.[Order]
  

Моя конечная цель — определить, на каких этапах оценки отсутствуют оценки.

редактировать (пример данных): Запрос # 1

 |---------------------|------------------|---------------------|
|      evalID         |     Order        |  Total Categories   |
|---------------------|------------------|---------------------|
|          81         |      01.00       |         17          |
|---------------------|------------------|---------------------|
|          81         |      02.00       |         17          |
|---------------------|------------------|---------------------|
|          81         |      03.00       |         17          |
|---------------------|------------------|---------------------|
  

Запрос # 2

 |---------------------|------------------|---------------------|------------------|
|     evaluatorID     |       Step       |        Order        |   Grades Entered |
|---------------------|------------------|---------------------|------------------|
|        1178         |        609       |        01.00        |        2         |
|---------------------|------------------|---------------------|------------------|
|        1178         |        615       |        02.00        |        3         |
|---------------------|------------------|---------------------|------------------|
|        9441         |        609       |        01.00        |        17        |
|---------------------|------------------|---------------------|------------------|
|        9441         |        609       |        02.00        |        17        |
|---------------------|------------------|---------------------|------------------|
|        9441         |        609       |        03.00        |        17        |
|---------------------|------------------|---------------------|------------------|
  

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

1. Это не так просто, как UNION ALL не так ли? Образцы данных и желаемые результаты могут помочь здесь, если нет.

2. С другой стороны, я предлагаю как можно скорее отказаться от привычки использовать псевдонимы типа t1 , t2 , … t6 : Вредные привычки, от которых нужно избавиться: использование псевдонимов таблиц типа (a, b, c) или (t1, t2, t3) .

3. Вам нужно иметь похожие столбцы (типы данных и количество. И выполнить объединение всех между запросами.

4. Не уверен, что это ОБЪЕДИНЕНИЕ. Звучит больше как ВНЕШНЕЕ объединение, но это предположение, основанное на последнем предложении в вопросе. Без примеров данных и желаемых результатов вопрос недостаточно ясен для ответа.

5. @TabAlleman Правильно… Я пробовал ОБЪЕДИНЕНИЕ. Я также попробовал несколько ВНЕШНИХ соединений, но, очевидно, не те, которые были правильными.

Ответ №1:

Начиная с первого запроса, который показывает все шаги, связанные с оценкой, вы можете выполнить ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ ко второму запросу, и шаги, которые равны NULL в правой части запроса, будут теми, в которых отсутствуют оценки.

Для того, чтобы сделать это, в ваших таблицах должен быть какой-то способ связывания Grading с Evals . Этот столбец не виден из опубликованного вами кода, но я предполагаю, что он там есть. Возможно, это через GradingCats .

В сокращенном псевдокоде, просто чтобы показать, что я имею в виду:

 SELECT ...
FROM Evals e
INNER JOIN Steps s ON e.TemplateID = s.TemplateID 
LEFT OUTER JOIN Grading g ON g.EvalID = e.EvalID  --use whatever means you have to show which Eval a Grade is from
LEFT OUTER JOIN Steps gs ON {join to Grading through GradingCats as in your second query}
WHERE gs.StepID IS NULL
  

При анализе результата этого запроса все шаги каждого Eval будут в s.StepID , и когда в той же строке есть значение NULL для gs.StepID , это означает, что шаг не получил оценку.

Обратите внимание, что вы не захотите выполнять какую-либо ГРУППИРОВКУ ПО в этом запросе, поскольку вам нужен анализ на уровне строк.

Ответ №2:

Коллега (обладающий большими знаниями о данных, чем я) слегка изменил мой запрос:

 SELECT query1.stepID, Categories, Graded
FROM
(
    SELECT rs.stepid, COUNT(c.category) AS 'Categories'
    FROM Evals e
    JOIN RunScriptSteps rs ON e.TemplateID = rs.TemplateID
    JOIN GradingCats c ON rs.StepID = c.StepID
    WHERE EvalID = *(someNumber)*
    GROUP BY rs.stepid
)AS query1
LEFT JOIN
(
    SELECT s.StepID, COUNT(Grade) AS 'Graded'
    FROM Grading g
    JOIN GradingCats c ON g.GradingCatID = c.GradingCatID
    JOIN Steps s ON c.StepID = s.StepID
    WHERE EvalID = *(someNumber)*
    GROUP BY s.stepid
) AS query2
ON query1.stepid = query2.stepid
ORDER BY stepid ASC