Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.222.184.162] |
|
Данный раздел предназначается для обсуждения вопросов использования баз данных, за исключением составления запросов на SQL. Для этого выделен специальный раздел. Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
С нормализацией все в поряде - все таблицы (кроме одной) вяжутся по простому ключу. И только одна - по составному. Но я посчитал, мне будет так "дешевле" обрабатывать. А в этом случае целостность обеспечивается бизнес-логикой приложения. Я говорю о таблице родственных отношений. Если спецом не лезть руками в БД, клиентское приложение при модификации всегда оставляет только одну связь, а она расшифровывается таблицей учитывая пол клиентов и номер отношения. Вообщем начало скрипта вымучал, все групповые вычисления вынес таки из полей, обошелся двумя джоинами и группировкой. Получил ускорение примерно в 7 раз. Получилось вот так: SELECT x."Id", x."Age", x."Sex", CASE WHEN SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) = 0 AND SUM(CASE WHEN COALESCE(fa2."Relation",0)>0 THEN 1 ELSE 0 END) = 0 AND x."Age" < 18 THEN 1 ELSE 0 END AS "IsChild", CASE WHEN SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) > 0 AND SUM(CASE WHEN COALESCE(fa2."Relation",0)>0 THEN 1 ELSE 0 END) = 0 THEN 1 ELSE 0 END AS "IsParent" FROM ( SELECT c."Id", CASE WHEN c."YearOfBirth" < 150 THEN c."YearOfBirth" ELSE (EXTRACT(year FROM now()) - c."YearOfBirth") END AS "Age", c."Gender" AS "Sex", c."Gender", CASE WHEN ((COALESCE(fa1."Relation",0)>0) AND (fa1."ClientOne" = c."Id")) THEN fa1."ClientTwo" WHEN ((COALESCE(fa1."Relation",0)>0) AND (fa1."ClientTwo" = c."Id")) THEN fa1."ClientOne" ELSE 0 END AS "Childs1" FROM "Clients" AS c LEFT JOIN "Family" AS fa1 ON (fa1."ClientOne" = c."Id" AND fa1."Relation" IN (15,16,19,20)) OR (fa1."ClientTwo" = c."Id" AND fa1."Relation" IN (10,21,22,30)) WHERE c."FamilyId" IN ( SELECT c."FamilyId" FROM "Service" AS s, "Service2Clients" AS sc, "Clients" AS c WHERE c."Id" = sc."Client" AND sc."Service" = s."Id" AND s."Date" BETWEEN '2015-01-01' AND '2015-12-31' AND s."State" > 0 AND sc."Present" ) ) AS x LEFT JOIN "Family" AS fa2 ON (fa2."ClientOne" = x."Childs1" AND fa2."Relation" IN (15,16,19,20)) OR (fa2."ClientTwo" = x."Childs1" AND fa2."Relation" IN (10,21,22,30)) GROUP BY x."Id", x."Age", x."Sex" Только вот не уверен с это конструкцией, не слишком ли параноидальная перестраховка? SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) = 0 Может хватило бы так? SUM(x."Childs1") = 0 |