Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.09.2014, 13:48   #1
lump
 
Регистрация: 21.08.2014
Сообщений: 8
Вопрос прошу помощи с составлением запроса

Доброго времени суток.

Есть БД с опросными листами (анкетами) схема данных во вложении.

в таблице:
questionnaires - названия опросных листов;
questions - вопросы для опросных листов с привязкой к названию о.листа;
answers - стандартные ответы на вопросы с привязкой к вопросу;
users - имя пользователя заполняющего о.лист;
profile - собственно заполненный опросный лист, привязка пользователя и ответа.

Соответственно в системе есть несколько опросных листов.

Появилась необходимость выбирать тех пользователей у которых есть незаполненные (хотя бы один) опросные листы.

Могу получить список пользователей и заполненных опросных листов...но хз что мне это даст...
собственно я в ступоре и прошу Вашей помощи / идей.
Изображения
Тип файла: jpg схема_данных.jpg (27.4 Кб, 200 просмотров)
lump вне форума Ответить с цитированием
Старый 17.09.2014, 14:27   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
пользователей у которых есть незаполненные (хотя бы один) опросные листы.
Пользователи у которых число различных (при условии возможного заполнения анкеты одного типа два и более раз) анкет МЕНЬШЕ установленного количества (=STANDART).

Код:
select fio
from user --спсисок пользователей
left join ( select user, count(distinct anketa) as count --статистика заполнения анкет
              from list
              group by user --по пользователям
          ) as stat on stat.user =user.id
where stat.count<STANDART --заполнено меньше нужного числа
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 17.09.2014 в 14:31.
evg_m вне форума Ответить с цитированием
Старый 17.09.2014, 14:59   #3
lump
 
Регистрация: 21.08.2014
Сообщений: 8
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Пользователи у которых число различных (при условии возможного заполнения анкеты одного типа два и более раз) анкет МЕНЬШЕ установленного количества (=STANDART).

Код:
select fio
from user --спсисок пользователей
left join ( select user, count(distinct anketa) as count --статистика заполнения анкет
              from list
              group by user --по пользователям
          ) as stat on stat.user =user.id
where stat.count<STANDART --заполнено меньше нужного числа
пользователь не может заполнить анкету дважды это следует из схемы данных...а точнее из таблицы profile где внешние ключи образуют первичный
я также привел схему данных для того чтобы не было рассогласованности в ответе...
что за тбл list и anketa?
и причем тут установленное количество анкет?
количество опросных листов может увеличиваться (опционально)
lump вне форума Ответить с цитированием
Старый 17.09.2014, 15:14   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Что такое незаполненный опросный лист?

1. Нет ответа юзера хотя бы на один вопрос листа
2. Нет ответа юзера ни на один вопрос листа
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 17.09.2014, 15:19   #5
lump
 
Регистрация: 21.08.2014
Сообщений: 8
По умолчанию

2. Нет ответа юзера ни на один вопрос листа
TRUE
lump вне форума Ответить с цитированием
Старый 17.09.2014, 15:32   #6
lump
 
Регистрация: 21.08.2014
Сообщений: 8
По умолчанию

В общем сделал так:
Код:
select * from users where id in (
SELECT users.id FROM  users
left JOIN profile ON profile.users_id = users.id
left JOIN answers ON profile.answers_id = answers.id
left JOIN questions ON answers.questions_id = questions.id
left JOIN questionnaires ON questions.questionnaires_id = questionnaires.id
group by users.id
having count(distinct questionnaires.id) < (select count(*) from questionnaires) )
Работает, выдает что надо.
НО может есть какой другой, возможно более красивый, вариант?
lump вне форума Ответить с цитированием
Старый 17.09.2014, 15:32   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Что-то типа - выбрать всех юзеров, для которых существуют такие опросные листы, у которых нет ни одного ответа юзера? Типа такого
Код:
SELECT U.*
  FROM users U
  WHERE EXISTS(SELECT 1
                 FROM questionnaires R
                 WHERE NOT EXISTS(SELECT 1
                                    FROM questions Q, answers A, profile P
                                    WHERE Q.questionnaires_id=R.id AND
                                          Q.id=A.questions_id AND
                                          A.id=P.answers_Id AND
                                          P.users_id=U.id))
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 17.09.2014, 15:45   #8
lump
 
Регистрация: 21.08.2014
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Код:
(SELECT 1
пРОшу прощения, а что означает эта конструкция?
lump вне форума Ответить с цитированием
Старый 17.09.2014, 15:49   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

А что допускается в перечне Select-а? Поля, выражения, подзапросы, *. Константа разновидность выражения. По идее это быстрей, чем ту же звездочку в данном случае писать. Кстати, хоть в вашем запросе куча left join-ов, вполне возможно, что он быстрее моего варианта будет. Проверьте. Если мой вариант вообще рабочий ))
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 17.09.2014, 16:00   #10
lump
 
Регистрация: 21.08.2014
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А что допускается в перечне Select-а? Поля, выражения, подзапросы, *. Константа разновидность выражения. По идее это быстрей, чем ту же звездочку в данном случае писать. Кстати, хоть в вашем запросе куча left join-ов, вполне возможно, что он быстрее моего варианта будет. Проверьте. Если мой вариант вообще рабочий ))
Ваш рабочий, всё пашет
я вот голову ломаю как сделать без под-запросов на соединениях

Последний раз редактировалось lump; 17.09.2014 в 16:02.
lump вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
MS SQL. Подскажите с составлением запроса. Mixasik SQL, базы данных 4 13.10.2009 14:56
Прошу помощи. Brian Lee Jones Свободное общение 0 19.06.2008 00:21