Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Запрос в SQLite


Автор: maxnoskov 14.2.2007, 10:41
Ребята, выручайте. Работаю с SQLite 3.0.
Есть таблицы: Районы, Учреждения, Здания и Справочник типов зданий
Связи такие: Районы - Учреждения (один ко многим); Учреждения - Здания (один ко многим); Справочник типов зданий - Здания (один ко многим).
Нужно создать запрос в котором нужно для каждого типа здания нужно вывести количество зданий, имеющих определенные атрибуты, прописанные в таблице Здания(для определенного района и учреждения)
Район - Первый; Учреждение - такое-тож

Типы зданий    Есть сигнализация   Есть пожарный кран             и.т.

Общежитие                  3                                1
Мастерская                   2                                0
и т.д.

В Access использовал SUM вместе с IIF(). А SQLite их не поддерживает
Чувствую, нужны подзапросы, но как реализовать - не знаю

Автор: skyboy 14.2.2007, 11:25
в таком виде, как ты хочешь, тебе надо перед запросом знать количество атрибутов. 
плиз, сообщи, есть ли в SQLLite cross join или можно ли делать inner join без указания условия связи. а то у меня yt открывается сайт SQLLite: (

Автор: maxnoskov 14.2.2007, 11:50
Количество атрибутов мне известно, CROSS JOIN и INNER JOIN без условия работают, но выдают странный результат

Автор: skyboy 14.2.2007, 12:46
ок. тогда можно сделать так:
Код

SELECT тз.название_типа_здания, count(аз1.idатрибута), count(аз2.idатрибута), count(аз2.idатрибута)...
FROM здания AS з
INNER JOIN типы_зданий AS тз
ON тз.idтипа_здания = з.idтипа_здания
LEFT JOIN аттрибуты_зданий AS аз1
ON аз1.idздания = з.idздания AND аз1.idатрибут = 1 /*определяется тобой*/
LEFT JOIN аттрибуты_зданий AS аз2
ON аз2.idздания = з.idздания AND аз2.idатрибут = 2 /*определяется тобой*/
LEFT JOIN аттрибуты_зданий AS аз3
ON аз3.idздания = з.idздания AND аз3.idатрибут = 28 /*определяется тобой*/
.....
WHERE з.idучереждения = 555 /*определяемое тобой*/
GROUP BY тз.idтипа_здания

вроде, так smile но проверить не на чем smile

Добавлено @ 12:51 
Цитата(maxnoskov @  14.2.2007,  10:50 Найти цитируемый пост)
но выдают странный результат 

да ну? может, это ты от них ожидаешь чего-то хитрого?  smile 
Если есть таблица 1:
table1
_______
id     value
_______
1        a
2        b
3        c

и таблица 2:
table2
_______
id value
_______
9        01
10      02
11      03

то  после выполнения cross join(или inner join без условия связывания, что одно и то же) ты должен получить декартово произведение: все строки из первой таблицы во всех возможных комбинациях со строками из второй таблицы:

table1.id     table1.value   table2.id    table2.value
_______________________________________
1                       a                  9                  01
1                       a                  10                02
1                       a                  11                03
2                       b                  9                  01 
2                       b                  10                02
2                       b                  11                03
3                       c                   9                  01
3                       c                   10                02
3                       c                   11                03

разве не такое у тебя получается?

Автор: maxnoskov 14.2.2007, 13:28
Спасибо, все работает, только как сюда районы и типы учреждений впихнуть, ну т.е чиобы такая таблица выдавалась для определенного района и для определенного типа ОУ

Автор: skyboy 14.2.2007, 13:32
Цитата(maxnoskov @  14.2.2007,  12:28 Найти цитируемый пост)
Спасибо, все работает

чесно говоря, не ждал, что сходу получится...  smile 
Цитата(maxnoskov @  14.2.2007,  12:28 Найти цитируемый пост)
ну т.е чиобы такая таблица выдавалась для определенного района и для определенного типа ОУ 

Что такое "ОУ"? у меня же в запросе есть 
Цитата(skyboy @  14.2.2007,  11:46 Найти цитируемый пост)
WHERE з.idучереждения = 555

так я выбираю данные только касательно одного единственного учереждения. а судя по 
Цитата(maxnoskov @  14.2.2007,  09:41 Найти цитируемый пост)
Районы - Учреждения (один ко многим); 

у тебя одно и то же учереждение не размещает свои здания в разных районах. значит, дополнительная фильтрация по району бессмысленна smile

Автор: maxnoskov 14.2.2007, 13:41
Цитата

Что такое "ОУ"? у меня же в запросе есть 

Это индекс ОУ, а мне не нужно по ОУ. Я неправильно вопрос поставил. Есть таблица типы_ОУ и она связана с таблицей ОУ один ко многим. И вот по эти типам мне нужно выводить данный запрос. Ну т.е. сколько зданий с такими-то атрибутами имеются у ОУ данного типа
Цитата

у тебя одно и то же учереждение не размещает свои здания в разных районах. значит, дополнительная фильтрация по району бессмысленна

И все это делать по районам. Т.е. для каждого района и в каждом районе свой тип ОУ и для каждого типа ОУ свой запрос.
ВОТ так. Ну блин намутил smile 

Автор: skyboy 14.2.2007, 13:55
запутал окончательно smile

Автор: maxnoskov 14.2.2007, 14:25
Попробую распутать:
Есть таблица Районы и связанная с ней таблица Образовательные учреждения (один ко многим). Т.е. к одному району относятся несколько учреждений. Каждое учреждение имеет свой тип, прописанный в таблице Типы_ОУ. Типы ОУ - ОУ (один ко многим). Одно учреждение - один тип ОУ. Один тип ОУ - много учреждений. Есть таблица Зданий, связанная с таблицей ОУ. Т.е. к одному ОУ относятся много зданий. Каждое здание имеет свой тип, прописанный в таблице Типы Зданий. Типы зданий - Здания (один ко многим). Одно здание - один тип здания. Один тип здания - много зданий. В таблице здания для каждого здания имеется набор атрибутов, имеющих определенные значения.
Что нужно:
Для конкретного района и для конкретного типа ОУ, т.е. учитывая учреждения определенного типа, относящиеся к этому району, нужно найти количество:
Такой-то район
Такой-то тип оу

Типы зданий    Есть сигнализация   Есть пожарный кран             и.т.(количество атрибутов известно)

Общежитие                  3                                1
Мастерская                   2                                0
и т.д.

Этот же район
Другой тип ОУ

Типы зданий    Есть сигнализация   Есть пожарный кран             и.т.(количество атрибутов известно)

Общежитие                  1                                4
Мастерская                   2                                4
и т.д.

Может полегче понять, а то как обычно - сам понимаешь, но объяснить не можешь что нужно smile 

Автор: skyboy 14.2.2007, 15:24
Цитата(maxnoskov @  14.2.2007,  13:25 Найти цитируемый пост)
Может полегче понять, а то как обычно - сам понимаешь, но объяснить не можешь что нужно

для этого и созданы специальные символьные языки вроде http://en.wikipedia.org/wiki/Entity-Relationship_Model и http://en.wikipedia.org/wiki/Unified_Modeling_Language  smile 
значит, так...
Код

SELECT р.название_района, тоу.название_типа_оу, тз.название_типа_зданий, COUNT(аз1.idатрибут), COUNT(аз2.idатрибут), COUNT(аз3.idатрибут)....
FROM ОУ AS оу
INNER JOIN  районы AS р
ON оу.idрайон = р.idрайон
INNER JOIN типы_ОУ AS тоу
ON тоу.idтип_оу = оу.idтип_оу
INNER JOIN здания AS з
ON з.idОУ = оу.idОУ
INNER JOIN типы_зданий AS тз
ON тз.idтип_здания = з.idтип_здания
LEFT JOIN атрибуты_зданий AS аз1
ON аз1.idздания = з.idздания AND аз1.idатрибут = 28 /*определяется тобой*/
LEFT JOIN атрибуты_зданий AS аз2
ON аз2.idздания = з.idздания AND аз2.idатрибут = 45 /*определяется тобой*/
LEFT JOIN атрибуты_зданий AS аз3
ON аз3.idздания = з.idздания AND аз3.idатрибут = 19 /*определяется тобой*/
....
WHERE р.idрайон IN (2,12,32) AND тоу.idтип_оу IN (13,28,16)
GROUP BY р.idрайона, тоу.idтипа_оу, тз.idтипа_зданий

Автор: maxnoskov 14.2.2007, 15:56
ДА, оно все находит, но я наверное обнаглею, если скажу что мне надо немножко другое:
В таблице не нужно выводить район и тип ОУ. Select должен в зависимости от значения кодов района и типа оу должен формировать такую таблицу, причем незвависимо от района и типа оу должны выводится все типы зданий, поэтому WHERE неподходит

Автор: skyboy 14.2.2007, 16:21
Код

SELECT р.название_района, тоу.название_типа_оу, тз.название_типа_зданий, COUNT(аз1.idатрибут), COUNT(аз2.idатрибут), COUNT(аз3.idатрибут)....
FROM типы_зданий AS тз
CROSS JOIN  районы AS р
CROSS JOIN типы_ОУ AS тоу
LEFT JOIN ОУ AS оу
ON оу.idрайон = р.idрайон AND тоу.idтип_оу = оу.idтип_оу
LEFT JOIN здания AS з
ON з.idОУ = оу.idОУ AND тз.idтип_здания = з.idтип_здания
LEFT JOIN атрибуты_зданий AS аз1
ON аз1.idздания = з.idздания AND аз1.idатрибут = 28 /*определяется тобой*/
LEFT JOIN атрибуты_зданий AS аз2
ON аз2.idздания = з.idздания AND аз2.idатрибут = 45 /*определяется тобой*/
LEFT JOIN атрибуты_зданий AS аз3
ON аз3.idздания = з.idздания AND аз3.idатрибут = 19 /*определяется тобой*/
....
WHERE р.idрайон = 555 AND тоу.idтип_оу = 287 
GROUP BY р.idрайона, тоу.idтипа_оу, тз.idтипа_зданий

хм. опять что-то путаться начинаю...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)