Есть ли способ проверить, содержит ли одна таблица все записи из таблицы ответов для одного конкретного идентификатора в одном столбце?

#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. Возможно, вы сможете адаптировать мой ответ к этим новым требованиям, хотя на этом этапе вам может потребоваться просто открыть новый вопрос. В следующий раз, когда вы будете спрашивать, просто постарайтесь предоставить нам минимальное количество выборочных данных, достаточное для того, чтобы мы поняли суть вашей проблемы.