2010-08-09 8 views
2

система: Windows7, Access 2003, .mdb файл, C# язык, VS 2010MS Access - SQL Query вопрос

Я делаю запросы с OleDbCommand, поэтому я пишу полный запрос SQL в строке.


Table Survey (Id) 
Table Questions (Id,IdSurvey) 
Table Answers (Id,IdQuestion) 

таблиц упрощены, чтобы показать только соответствующие данные

Подозрение на 1 опрос 1..n вопросы
Подозрение на 1 вопрос имеет 0..n ответы

I хотите выбрать только опросы, в которых есть ответы 1 и/или 2 для Вопроса3, как это сделать?

тока (и плохое) решение:

SELECT surv.Name FROM Survey surv WHERE 
(1 IN (SELECT answ.Number FROM Answers answ, Questions quest 
WHERE quest.Id = 3 AND quest.IdSurvey = surv.Id) 
AND/OR 
(2 IN (SELECT answ.Number FROM Answers answ, Questions quest 
WHERE quest.Id = 3 AND quest.IdSurvey = surv.Id))) 

Это выглядит как дерьмо, так что я был бы признателен за помощь.

Заранее спасибо.


EDIT

Лучше решение я придумал:

Для 1 или 2, решений, приведенных здесь достаточно (для очень простых логических выражений). Спасибо, ребята

Для 1 и 2, я создал еще одно решение, выглядит своего рода хорошо я думаю, что (опять же, для очень простых логических выражений)

SELECT surv.Name FROM Survey surv WHERE EXISTS 
(SELECT COUNT(*) FROM Answers answ, Questions quest 
WHERE quest.Id = 3 AND answ.Number IN (1,2) HAVING COUNT(*) > 1) 

"" в HAVING означает, что необходимы не менее двух строк, и поскольку ответы не повторяются для одних и тех же вопросов, это необходимо для того, чтобы, по крайней мере, ответы 1 И 2 ​​ существует для заданного вопроса.

Ну, как ИЛИ раствор и раствор И плохо при работе с более сложными логическими выражениями, как (1 и (2 OR (4 и (6 или 7)))), истины является очень маловероятным, что такая сложность будет необходима, но я бы хотел быть в безопасности. Идеальное решение для меня было бы это:

SELECT surv.Name FROM Survey surv WHERE 
(1 IN (SELECT answ.Number FROM Answers answ, Questions quest 
WHERE quest.Id = 3 AND quest.IdSurvey = surv.Id) AS CANT_DO_THIS 
AND/OR 
(2 IN CANT_DO_THIS) AND/OR 5 IN CANT_DO_THIS AND/OR 3 NOT IN CANT_DO_THIS) 

ответ

0
SELECT surv.Name FROM Survery surv 
    INNER JOIN Questions quest ON surv.ID = quest.IDSurvey 
    INNER JOIN Answers answ ON quest.ID = answ.IDQuestion 
    WHERE quest.ID = 3 AND answ.Number IN (1, 2) 

Это будет возвращать одну строку за опрос (потому что вы ссылаетесь только вопрос ID 3 и однозначного ответа на этот вопрос), и только для обследований где ответ на вопрос 3 равен 1 или 2.

ПРИМЕЧАНИЕ. Мне непонятно, как вы присоединяетесь к таблице вопросов и ответов в своей модели данных, поэтому я предположил, что таблица ответов имеет внешний ключ обратно к запросам IDQuestion.

+0

Спасибо за ваш ответ. Как я описал, у одного вопроса есть много ответов, поэтому я считаю, что ваше решение может повторить один и тот же опрос много раз. Обратите внимание, что это вводит проблему «и», как я могу это сделать с помощью одного «IN»? Кажется невозможным. –

+0

Если каждый вопрос присоединяется через внешний ключ, возвращается к одному опросу, и каждый ответ соединяется, используя внешний ключ, обратно к одному вопросу, тогда SQL должен дать вам правильный результат. Я не уверен, что ваша модель связывает каждый ответ с одним _question_, это необходимое условие для работы трех столов. –

+0

Проблема в том, что многие ответы объединены с одним вопросом. И таким образом, один и тот же опрос и один и тот же вопрос повторяются над N строками. Это отношение «1 x 0..n». Кроме того, как сделать «1 и 2» вместо «1 или 2»? (ваше решение для «1 или 2», оператор IN) –

0
Select ... 
From Survey As 
Where Exists (
       Select 1 
       From Questions As Q1 
        Join Answers As A1 
         On A1.IdQuestion = Q1.Id 
       Where Q1.IdSurvey = S.Id 
        And Q1.Id = 3 
        And A1.Id In(1,2) 
       Having Count(*) = 2 
       ) 
+0

Что делать, если я хочу, чтобы ответы были «1 И 2» вместо «1 ИЛИ 2». Обратите внимание, что ваше решение предназначено для оператора «1 ИЛИ 2», оператора IN. –

+0

@WoF_Angel - Хорошо. Простое исправление. Просто добавьте условие наличия. Обновил мой пост. – Thomas

+0

@WoF_Angel - Кстати, мое замешательство относительно того, что вы хотели, вытекало из этого утверждения: 'выберите только опросы, в которых есть ответы 1 и/или 2 для Вопроса3. Ясно, что вы имели в виду «ответы 1 и 2». Я воспринял это как «1 или 2». В другом примечании, что означает '/' в 'и/или'? ;> – Thomas