можно ли обойтись без курсора - связка трех таблиц

nerv
Дата: 01.02.2013 00:37:49
Первая таблица - справочник:
iss iss_id (int, pk), iss_text (varchar(50))

Вторая таблица - тоже справочник:
vi c полями vi_id (int), iss_id (int), zv (bit)
pk из двух полей vi_id, iss_id


Здесь iss - некий справочник услуг (в отдельной таблице есть прайс этих услуг).
vi - справочник мероприятий. Каждое мероприятие может состоять из нескольких услуг (iss_id), причем эти услуги могут быть обязательными (zv = false) или не обязательными (zv = true)

И наконец, таблица потребителей этих мероприятий:
lst c полями: lst_id (int, pk), vi_id (int)

То есть потребитель мероприятий может иметь несколько мероприятий, которые в свою очередь состоят из нескольких услуг.
Надо сделать SELECT к таблице lst, выдав lst_id, iss_id, iss_text, zv

то есть для каждого потребителя выдать список необходимых ему услуг.
Если одна и та же услуга встречается несколько раз (в рамках нескольких мероприятий), то отобразить ее только один раз. Если в одном мероприятии услуга обязательная, а в другом - нет, то считать ее обязательной. Она будет не обязательной (zv = true) только в том случае, если эта услуга встречается во всех мероприятиях как не обязательная.
invm
Дата: 01.02.2013 01:03:02
select
 l.lst_id, i.iss_id, i.iss_text, cast(count(nullif(i.zv, 0)) / count(*) as bit) as zv
from
 lst l join
 vi v on v.vi_id = l.vi_id join
 iss i on i.iss_id = v.iss_id
group by
 l.lst_id, i.iss_id, i.iss_text;
Cygapb-007
Дата: 01.02.2013 01:14:55
nerv
И наконец, таблица потребителей этих мероприятий:
lst c полями: lst_id (int, pk), vi_id (int)
pk не даст создать несколько мероприятий для одного потребителя:)
Cygapb-007
Дата: 01.02.2013 01:24:58
если без pk:
SELECT l.lst_id, i.iss_id, i.iss_text, min(cast(v.zv as tinyint)) as zv
FROM lst l
join vi v on v.vi_id=l.vi_id
join iss i on i.iss_id=v.iss_id
group by l.lst_id, i.iss_id, i.iss_text
order by l.lst_id, i.iss_id, i.iss_text
nerv
Дата: 03.02.2013 20:38:07
invm, а ваш скрипт рабочий или нет?
Во первых, поле zv в таблице vi, а не iss
В скрипте заменил, при запуске выдает предупреждение:
Warning: Null value is eliminated by an aggregate or other SET operation.

Но в целом работает не верно. Если услуга в одном случае с zv = True, а в другом zv = False, в результирующую выборку должна попасть одна строчка, где zv = False.
Ваш скрипт выдает обе строки и zv=False и zv=True
nerv
Дата: 03.02.2013 20:53:00
Cygapb-007,
Не, насчет pk видимо вы не верно поняли, там pk по одному полю, а не по двум.
То есть таблица lst
lst_id int (pk)
vi_id int

Или вы предлагаете у lst вовсе убрать pk?

Ваш вариант проверил, он так же если одна услуга встречается в двух мероприятиях, причем в одном случае zv=True, а в другом zv=False, то в выборку опять же попадает обе строки.

zv = True - услуга на выбор потребителя
zv=False - услуга обязательная, выбора у потребителя нет

То есть если в обоих мероприятиях услуга на выбор потребителя, то в результате должна попасть одна такая услуга с zv = True - услуга на выбор потребителя;
Если же из нескольких мероприятий хотя бы в одном данная услуга обязательна zv=False, то в выботке должна быть эта услуга также обязательной (zv=False)
Сергей Мишин
Дата: 03.02.2013 22:33:44
nerv
Cygapb-007,
Не, насчет pk видимо вы не верно поняли, там pk по одному полю, а не по двум.
То есть таблица lst
lst_id int (pk)
vi_id int

Если lst_id это идентификатор потребителя, то как возможно вот это:
nerv
То есть потребитель мероприятий может иметь несколько мероприятий
???
Приведите пример данных для всех трёх таблиц.
nerv
Дата: 03.02.2013 22:41:11
Все спасибо всем, разобрался.
Оба описанных выше способа работают, надо просто из выборки исключить l.lst_id
(заменив его на другое, более подходящее поле).
Вопрос закрыт, спасибо за присланные решения, а я бы курсор бы написал бы на целую страницу, а тут все гениально и просто...
nerv
Дата: 03.02.2013 22:44:32
Сергей Мишин, вообще не верно выразился. lst-это не справочник потребителей, потребители вынесены в отдельный справочник.
а lst - таблица связка "потребитель-мероприятие". Один и тот же потребитель может иметь несколько мероприятий и этот справочник lst это и отражает.