#sql #sql-server
#sql #sql-server
Вопрос:
Я пытаюсь сравнить две таблицы: таблицу, содержащую результаты, и таблицу, содержащую ответ / ключ. Я хочу, чтобы в таблице результатов были записи, которые точно соответствуют тому, что есть в таблице ответов для определенного идентификатора столбца. Эта таблица результатов имеет:
Я использую SQL Server 2008, и это мой запрос:
select id
from Answer
left outer join Result on Answer.mappingId = Result.mappingId
and Answer.answerValue = Result.answerValue
left outer join Check on Result.checkId = Check.checkId
Вот таблицы, которые я использую:
Таблица результатов — checkId = 100 — это то, что я хочу в этом примере
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
1 | 15 | 100 | 1
2 | 16 | 100 | 1
3 | 17 | 100 | 1
4 | 18 | 100 | 1
5 | 15 | 200 | 1
6 | 16 | 200 | 1
7 | 17 | 200 | 2
8 | 18 | 200 | 2
Таблица ответов:
id | mappingId | answerValue
--- ------------- ------------
1 | 15 | 1
2 | 16 | 1
3 | 17 | 1
4 | 18 | 1
В таблице результатов обратите внимание, что для checkId используются одинаковые идентификаторы (4 из id 100 и 4 из id 200). Я хочу иметь возможность знать, равно ли значение ответа 1 для всех одного конкретного checkId. Итак, таблица результатов для checkId = 100 — это то, что я хочу, чтобы запрос обнаружил существование, поскольку в ней есть все правильные ответы для этого единственного значения идентификатора (4 записи для этого checkId = 100, что мне и нужно, потому что в таблице ответов есть 4 ответа. Идентификаторы сопоставления также должны совпадать, что они и делают: 15, 16, 17, 18). Но для 200 в ней нет всех ответов. У него есть только правильный ответ для сопоставления идентификаторов 15, 16.
Пример результирующей таблицы, которая не является тем, что я хочу, но все равно, похоже, передает мой запрос
Таблица результатов — все еще проходит, даже если это не предполагается
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
1 | 15 | 100 | 1
2 | 16 | 100 | 1
3 | 17 | 100 | 2
4 | 18 | 100 | 2
5 | 15 | 200 | 2
6 | 16 | 200 | 2
7 | 17 | 200 | 1
8 | 18 | 200 | 1
Это должно быть неверно, поскольку только два вопроса имеют правильное значение ответа 1 — для mappingId 15/16 для checkId = 100. Но проблема в том, что, поскольку checkId = 200 имеет остальные правильные значения — для mappingId 17/18, мой запрос по-прежнему считает это правильным, хотя я хочу mappingId: 15, 16, 17, 18 со значениями ответа 1 для всех для одного конкретного checkId = 100. Примечание: это просто должно быть для любого конкретного checkId, поэтому приведенное ниже все в порядке и то, что я хотел бы:
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
1 | 15 | 100 | 2
2 | 16 | 100 | 2
3 | 17 | 100 | 2
4 | 18 | 100 | 2
5 | 15 | 200 | 1
6 | 16 | 200 | 1
7 | 17 | 200 | 1
8 | 18 | 200 | 1
Потому что checkId 200 имеет mappingId: 15, 16, 17, 18 со всеми значениями ответа как 1.
Это то, что я хочу вернуть
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
5 | 15 | 200 | 1
6 | 16 | 200 | 1
7 | 17 | 200 | 1
8 | 18 | 200 | 1
или:
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
1 | 15 | 100 | 1
2 | 16 | 100 | 1
3 | 17 | 100 | 1
4 | 18 | 100 | 1
Если любое из приведенных выше значений неверно, это вообще ничего не вернет. В ней должны быть все правильные ответы для одного конкретного checkId. В принципе, все или ничего.
То, что я на самом деле возвращаю, неверно, поскольку оно охватывает 2 контрольных идентификатора
id | mappingId | checkId | answerValue
--- ------------- ---------- ---------------
1 | 15 | 100 | 1
2 | 16 | 100 | 1
3 | 17 | 200 | 1
4 | 18 | 200 | 1
Всем спасибо за помощь! Я новичок в stack overflow, поэтому дайте мне знать, если есть что-то, что я мог бы сделать лучше. Я не мог понять, как раскрасить SQL-запрос, поэтому простите меня, и я надеюсь, что это читаемо.
Ответ №1:
Один концептуально простой способ справиться с этим — объединить две таблицы, а затем объединить с помощью checkId
, утверждая, что каждый ответ соответствует:
SELECT
c.checkId
FROM [Check] c
LEFT JOIN Answer a
ON c.mappingId = a.mappingId AND c.answerValue = a.answerValue
GROUP BY
c.checkId
HAVING
COUNT(*) = COUNT(a.mappingId);
ДЕМОНСТРАЦИЯ
Комментарии:
1. Работает как шарм! Хотя, чтобы добавить, если бы я хотел усложнить задачу, где все ответы должны совпадать для определенного checkId, но также и для другого конкретного id, который появляется в другой таблице, к которой мне пришлось бы присоединиться. Как это изменит ваш запрос, чтобы справиться с этим. Возможно, вы можете представить столбец «checkId2» для каждого. Потребуется ли для этого какой-либо цикл, например, внутри while? Еще раз спасибо.
2. Возможно, вы сможете адаптировать мой ответ к этим новым требованиям, хотя на этом этапе вам может потребоваться просто открыть новый вопрос. В следующий раз, когда вы будете спрашивать, просто постарайтесь предоставить нам минимальное количество выборочных данных, достаточное для того, чтобы мы поняли суть вашей проблемы.