Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.220.1.239] |
|
Данный раздел предназначается для обсуждения вопросов использования баз данных, за исключением составления запросов на SQL. Для этого выделен специальный раздел. Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Доброго времени суток!
Есть небольшая БД, порядка трех тысяч записей. Написал запрос. Выполняется достаточно быстро. Написал запрос и задумался, БД будет расти, на сколько запрос начнет притормаживать в будущем. Взял и переписал запрос по-другому. Оба запроса выполняются раз-через раз с приблизительно сопоставимым временем выполнения (результаты естественно идентичные). Посмотрите, пожалуйста, какой из них в потенциале будет тормознее, что-то я теряюсь в оценке. Запрос 1 (который написал первым) SELECT x."Id", CASE WHEN (( SELECT COUNT(*) FROM "Family" AS f WHERE (f."ClientOne" = x."Id" AND f."Relation" IN (15,16,19,20)) OR (f."ClientTwo" = x."Id" AND f."Relation" IN (10,21,22,30)) ) = 0) AND (x."YearOfBirth" < 18 OR (EXTRACT(YEAR FROM NOW()) - x."YearOfBirth") < 18) THEN 1 ELSE 0 END AS "IsChild" FROM "Clients" AS x WHERE x."FamilyId" = 205 ORDER BY x."Id" Его эксплайн: Скрытый текст Sort (cost=316.18..316.20 rows=8 width=8) Sort Key: x."Id" -> Bitmap Heap Scan on "Clients" x (cost=4.31..316.06 rows=8 width=8) Recheck Cond: ("FamilyId" = 205) -> Bitmap Index Scan on "Clients_idx3" (cost=0.00..4.31 rows=8 width=0) Index Cond: ("FamilyId" = 205) SubPlan 1 -> Aggregate (cost=36.48..36.49 rows=1 width=0) -> Seq Scan on "Family" f (cost=0.00..36.48 rows=1 width=0) Filter: ((("ClientOne" = x."Id") AND ("Relation" = ANY ('{15,16,19,20}'::integer[]))) OR (("ClientTwo" = x."Id") AND ("Relation" = ANY ('{10,21,22,30}'::integer[])))) Time: 0.040s Запрос 2 (который надеялся написать лучше) SELECT x."Id", CASE WHEN SUM(x."IsChild")>0 THEN 1 ELSE 0 END AS "IsChild" FROM ( SELECT cl."Id", cl."YearOfBirth", CASE WHEN ((COALESCE(fa1."Relation",0) > 0) OR (COALESCE(fa4."Relation",0) > 0)) AND ((COALESCE(fa2."Relation",0) = 0) AND (COALESCE(fa3."Relation",0) = 0)) AND ((cl."YearOfBirth" < 18) OR (EXTRACT(YEAR FROM NOW()) - cl."YearOfBirth" < 18)) THEN 1 ELSE 0 END AS "IsChild" FROM "Clients" AS cl LEFT JOIN "Family" AS fa1 ON (fa1."ClientOne" = cl."Id") AND (fa1."Relation" IN (10,21,22,30)) LEFT JOIN "Family" AS fa2 ON (fa2."ClientOne" = cl."Id") AND (fa2."Relation" IN (15,16,19,20)) LEFT JOIN "Family" AS fa3 ON (fa3."ClientTwo" = cl."Id") AND (fa3."Relation" IN (10,21,22,30)) LEFT JOIN "Family" AS fa4 ON (fa4."ClientTwo" = cl."Id") AND (fa4."Relation" IN (15,16,19,20)) WHERE cl."FamilyId" = 205 ) AS x GROUP BY x."Id" ORDER BY x."Id" Его эксплайн: Скрытый текст GroupAggregate (cost=128.05..128.41 rows=8 width=24) -> Sort (cost=128.05..128.07 rows=8 width=24) Sort Key: cl."Id" -> Hash Right Join (cost=100.86..127.93 rows=8 width=24) Hash Cond: (fa3."ClientTwo" = cl."Id") -> Seq Scan on "Family" fa3 (cost=0.00..24.29 rows=735 width=8) Filter: ("Relation" = ANY ('{10,21,22,30}'::integer[])) -> Hash (cost=100.76..100.76 rows=8 width=20) -> Hash Right Join (cost=73.69..100.76 rows=8 width=20) Hash Cond: (fa1."ClientOne" = cl."Id") -> Seq Scan on "Family" fa1 (cost=0.00..24.29 rows=735 width=8) Filter: ("Relation" = ANY ('{10,21,22,30}'::integer[])) -> Hash (cost=73.59..73.59 rows=8 width=16) -> Hash Right Join (cost=48.90..73.59 rows=8 width=16) Hash Cond: (fa4."ClientTwo" = cl."Id") -> Seq Scan on "Family" fa4 (cost=0.00..24.29 rows=104 width=8) Filter: ("Relation" = ANY ('{15,16,19,20}'::integer[])) -> Hash (cost=48.80..48.80 rows=8 width=12) -> Hash Right Join (cost=24.12..48.80 rows=8 width=12) Hash Cond: (fa2."ClientOne" = cl."Id") -> Seq Scan on "Family" fa2 (cost=0.00..24.29 rows=104 width=8) Filter: ("Relation" = ANY ('{15,16,19,20}'::integer[])) -> Hash (cost=24.02..24.02 rows=8 width=8) -> Bitmap Heap Scan on "Clients" cl (cost=4.31..24.02 rows=8 width=8) Recheck Cond: ("FamilyId" = 205) -> Bitmap Index Scan on "Clients_idx3" (cost=0.00..4.31 rows=8 width=0) Index Cond: ("FamilyId" = 205) Time: 0.082s Вообщем, чет кажется, что не лучшее ... а наоборот регресс |
Сообщ.
#2
,
|
|
|
JoeUser
Гораздо разумнее было бы привести DDL таблиц с комментариями по полям и чётко поставить задачу. А пытаться понять, что за хрень происходит в опубликованной лапше - это увольте... |
Сообщ.
#3
,
|
|||||||||||||||||||||||||
|
Цитата Akina @ Гораздо разумнее было бы привести DDL таблиц с комментариями по полям и чётко поставить задачу. Ок, попробую. Таблиц и полей дофига, попробую сделать экстракт существенного: Таблица "Клиенты" (Clients)
Таблица "Семейные отношения" (Family)
Используемые типы отношений: В таблице отношений - отношения могут быть как односторонние, так и двусторонние. В случае двусторонних, они согласованы. Пример: ClientOne=123,ClientTwo=777,Relation=10 Клиент 123 относится к клиенту 777 как "Дочь" Задача Вывести в порядке возрастания идентификаторов клиентов - всех клиентов определенной семьи, с указанием является ли клиент ребенком. Правило определения "Является ли ребенком" Нет собственных детей и возраст < 18 (если есть дети или возраст > 18, то не ребенок) |
Сообщ.
#4
,
|
|
|
Цитата JoeUser @ отношения могут быть как односторонние, так и двусторонние. В случае двусторонних, они согласованы. Я правильно понимаю, что совокупность отношений может быть неполной? то есть при существовании записи, что А - сын/дочь Б, может НЕ существовать записи, что Б - отец/мать А? Цитата JoeUser @ Используемые типы отношений: Я правильно понимаю, что речь идёт о документальной, а не биологической, связи? |
Сообщ.
#5
,
|
|
|
Блин, во втором варианте похоже два лишних джойна
Добавлено Цитата Akina @ Я правильно понимаю, что совокупность отношений может быть неполной? то есть при существовании записи, что А - сын/дочь Б, может НЕ существовать записи, что Б - отец/мать А? Ага. Цитата Akina @ Я правильно понимаю, что речь идёт о документальной, а не биологической, связи? Документальной. Отчим == Отцу |
Сообщ.
#6
,
|
|
|
В любом случае, я бы, наверное, пошёл по пути объединения двух быстрых запросов.
Первый - получение списка всех членов семьи. Второй - получение списка только членов семьи, имеющих статус "ребёнок". Затем второй запрос включил бы как подзапрос в источник данных (т.е. именно в секции FROM, а никак не в SELECT) первого запроса для формирования статуса. Здесь следует добиться, чтобы оптимизатор понял, что подзапрос и основной запрос независимы - вплоть до оформления подзапроса в параметрический вьюв. |
Сообщ.
#7
,
|
|
|
Второй запрос немного сократил, убрал лишние проверки:
SELECT x."Id", CASE WHEN SUM(x."IsChild")>0 THEN 1 ELSE 0 END AS "IsChild" FROM ( SELECT cl."Id", cl."YearOfBirth", CASE WHEN ((COALESCE(fa1."Relation",0) > 0) OR (COALESCE(fa2."Relation",0) > 0)) OR (((cl."YearOfBirth" > 18) AND (cl."YearOfBirth" < 150)) OR (EXTRACT(YEAR FROM NOW()) - cl."YearOfBirth" > 18)) THEN 0 ELSE 1 END AS "IsChild" FROM "Clients" AS cl LEFT JOIN "Family" AS fa1 ON (fa1."ClientOne" = cl."Id") AND (fa1."Relation" IN (15,16,19,20)) LEFT JOIN "Family" AS fa2 ON (fa2."ClientTwo" = cl."Id") AND (fa2."Relation" IN (10,21,22,30)) WHERE cl."FamilyId" = 205 ) AS x GROUP BY x."Id" ORDER BY x."Id" Мне кажется это оптимальнее первого запроса? В первом варианте вложенный селект смущает. Добавлено Тройное склеивание. В первом джойне проверка наличия "есть и свои дети", во втором "являюсь ли я родителем", любое из них -> не ребенок, или не ребенок по возрасту. Добавлено Вот что значит хорошо поставленный вопрос ))) Пол ответа ))) Добавлено Цитата Akina @ Второй - получение списка только членов семьи, имеющих статус "ребёнок". Важный момент, который я упускал, сперва - "ребенок в семье может не иметь родителей" (типа опекуны, приемные семьи), главное чтобы он сам не имел детей и не был старше 18 лет. |
Сообщ.
#8
,
Сообщение отклонено: vot -
|
Сообщ.
#9
,
Сообщение отклонено: Bas -
|
Сообщ.
#10
,
|
|
|
M commercial coder пишите по существу а не на "свободную тему о всем и не о чем" |
Сообщ.
#11
,
|
|
|
Цитата JoeUser @ Важный момент, который я упускал, сперва - "ребенок в семье может не иметь родителей" Это полностью соответствует озвученным ранее признакам. Избыточное уточнение. |
Сообщ.
#12
,
|
|
|
Цитата Akina @ Это полностью соответствует озвученным ранее признакам. Избыточное уточнение. Согласен. Akina, есть еще небольшой вопрос. Код писать уже сил нет, вырубает. Но часов через шесть таки надо сделать. Задача подобного рода - найти "родителей". По требованию заказчика Родитель - это клиент, имеющий ребенка, у которого нет своего ребенка. Иными словами отсекаются бабушки и дедушки. В моей структуре БД все связи необязательны, и если отношение "Бабушка-внук/внучка" отсутствует в интерфейсе оно подменяется на "Родственник", посему нужеа цепочка сравнений. Как считаешь, если я к клиенту прицеплю 4 джойна (2 проверю ребенка, 2 проверю отсутствие у него своих детей) - это будет нормальный подход? Другого пока на ум не приходит. Запрос и так вырос, но пока мысль не теряю. Так, для примера недоделанный запрос, должно быть всего 34 вычисляемых поля и еще одна группировка с подсчетами по всем полям: SELECT ff."FamilyId", -- человек в семье COUNT(ff."X01") AS "Cnt", -- 1 SUM(ff."X02") AS "Y01", -- 2 SUM(ff."X03") AS "Y02", -- 3 CASE WHEN SUM(ff."X03") > 2 THEN 1 ELSE 0 END AS "Y03", -- 4 CASE WHEN SUM(ff."X05") > 0 THEN 1 ELSE 0 END AS "Y04", -- 5 CASE WHEN SUM(ff."X06") > 0 THEN 1 ELSE 0 END AS "Y05", -- 6 CASE WHEN (SUM(ff."X06") > 0) AND (SUM(ff."X03")>0) THEN 1 ELSE 0 END AS "Y06", -- 7 CASE WHEN (SUM(ff."X07") > 0) THEN 1 ELSE 0 END AS "Y07", -- 8 CASE WHEN (SUM(ff."X08") > 0) THEN 1 ELSE 0 END AS "Y08", -- 9 CASE WHEN (SUM(ff."X09") > 0) THEN 1 ELSE 0 END AS "Y09", -- 10 CASE WHEN (SUM(ff."X10") > 0) AND (SUM(ff."X03")>0) THEN 1 ELSE 0 END AS "Y10", -- 11 CASE WHEN (SUM(ff."X11") > 0) AND (SUM(ff."IsParent")=1) THEN 1 ELSE 0 END AS "Y11", -- 12 CASE WHEN (SUM(ff."X12") > 0) AND (COUNT(ff."X01")=1) THEN 1 ELSE 0 END AS "Y12", -- 13 CASE WHEN (SUM(ff."X13") > 0) THEN 1 ELSE 0 END AS "Y13", -- 14 CASE WHEN (SUM(ff."X14") > 0) AND (COUNT(ff."X01")=1) THEN 1 ELSE 0 END AS "Y14", -- 15 CASE WHEN (SUM(ff."X15") > 0) THEN 1 ELSE 0 END AS "Y15", -- 16 CASE WHEN (SUM(ff."X16") > 0) THEN 1 ELSE 0 END AS "Y16", -- 17 CASE WHEN (SUM(ff."X17") > 0) AND (SUM(ff."X17")=COUNT(ff."X01")) THEN 1 ELSE 0 END AS "Y17", -- 18 CASE WHEN (SUM(ff."X03") > 1) AND (SUM(ff."X03")<3) THEN 1 ELSE 0 END AS "Y18" FROM ( SELECT y."Id", y."FamilyId", y."IsParent", -- это человек семьи (для просчета количества людей в семье) 1 AS "X01", -- это ребенок до 14 лет CASE WHEN y."IsChild">0 AND y."Age"<14 THEN 1 ELSE 0 END AS "X02", -- это ребенок до 18 лет CASE WHEN y."IsChild">0 THEN 1 ELSE 0 END AS "X03", -- это родитель, для подсчета родителей CASE WHEN y."IsParent">0 THEN 1 ELSE 0 END AS "X04", -- это молодая семья CASE WHEN y."R10">0 THEN 1 ELSE 0 END AS "X05", -- это вдова или вдовец CASE WHEN y."R01" = 694 THEN 1 ELSE 0 END AS "X06", -- это женщина-мать, родившая вне брака CASE WHEN (y."R01" NOT IN (692,693,694)) AND (y."Gender">0) AND (y."IsParent">0) THEN 1 ELSE 0 END AS "X07", -- это несовершеннолетняя одинокая мать CASE WHEN (y."R01" NOT IN (692,697)) AND (y."Gender">0) AND (y."IsParent">0) AND (y."Age"<18) THEN 1 ELSE 0 END AS "X08", -- это несовершеннолетняя одинокая мать, получающая пособие CASE WHEN (y."R01" NOT IN (692,697)) AND (y."Gender">0) AND (y."IsParent">0) AND (y."Age"<18) AND (y."R11">0) THEN 1 ELSE 0 END AS "X09", -- это разведенный родитель CASE WHEN (y."R01" = 693) AND (y."IsParent">0) THEN 1 ELSE 0 END AS "X10", -- это семья усыновителей + родитель CASE WHEN (y."R12" > 0) AND (y."IsParent">0) THEN 1 ELSE 0 END AS "X11", -- это гражданин пожилого возраста CASE WHEN (y."Age" > 60) THEN 1 ELSE 0 END AS "X12", -- это одиноко-проживающий гражданин пожилого возраста CASE WHEN (y."Age" > 60) AND (y."R03" > 0) THEN 1 ELSE 0 END AS "X13", -- это инвалид I-II группы CASE WHEN (y."R02" IN (863,864)) THEN 1 ELSE 0 END AS "X14", -- это одиноко-проживающий инвалид I-II группы CASE WHEN (y."R02" IN (863,864)) AND (y."R03" > 0) THEN 1 ELSE 0 END AS "X15", -- это выпускник-родитель CASE WHEN (y."IsParent" > 0) AND (y."R04" > 0) THEN 1 ELSE 0 END AS "X16", -- это пенсионер CASE WHEN (y."R05" > 0) OR (y."R08" = 858) THEN 1 ELSE 0 END AS "X17", -- несовершеннолетний родитель CASE WHEN (y."IsParent" > 0) AND (y."Age" < 18) THEN 1 ELSE 0 END AS "X19", -- несовершеннолетний родитель из числа детей-сирот CASE WHEN (y."IsParent" > 0) AND (y."Age" < 18) AND (y."R09" > 0) THEN 1 ELSE 0 END AS "X20", -- родитель-инвалид I-II группы CASE WHEN (y."IsParent" > 0) AND (y."R02" IN (863,864)) THEN 1 ELSE 0 END AS "X21", -- ребенок в социально-опасном положении CASE WHEN (y."IsChild" > 0) AND (y."R06" > 0) THEN 1 ELSE 0 END AS "X23", -- ребенок-инвалид с детства CASE WHEN (y."IsChild" > 0) AND (y."R02" = 1235) THEN 1 ELSE 0 END AS "X24", -- ребенок из числа детей сирот CASE WHEN (y."IsChild" > 0) AND (y."R09" > 0) THEN 1 ELSE 0 END AS "X25", -- ребенок выпускник интернат CASE WHEN (y."IsChild" > 0) AND (y."R04" > 0) THEN 1 ELSE 0 END AS "X26", -- ребенок c болезнями CASE WHEN (y."IsChild" > 0) AND (y."R07" > 0) THEN 1 ELSE 0 END AS "X27", -- из семьи беженцев CASE WHEN (y."R14" > 0) THEN 1 ELSE 0 END AS "X29", -- из семьи опекунов CASE WHEN (y."R13" > 0) THEN 1 ELSE 0 END AS "X30", -- из семьи приемной CASE WHEN (y."R15" > 0) THEN 1 ELSE 0 END AS "X31", -- из семьи отселенной CASE WHEN (y."R16" > 0) THEN 1 ELSE 0 END AS "X32", -- из семьи, получающей пособие CASE WHEN (y."R11" > 0) THEN 1 ELSE 0 END AS "X33" FROM ( SELECT x."Id", x."FamilyId", -- это ребенок CASE WHEN (( SELECT COUNT(*) FROM "Family" AS f WHERE (f."ClientOne" = x."Id" AND f."Relation" IN (15,16,19,20)) OR (f."ClientTwo" = x."Id" AND f."Relation" IN (10,21,22,30)) ) = 0) AND (x."YearOfBirth"<18 OR (EXTRACT(YEAR FROM CURRENT_DATE) - x."YearOfBirth")<18) THEN 1 ELSE 0 END AS "IsChild", -- это родитель CASE WHEN (( SELECT COUNT(*) FROM "Family" AS f WHERE (f."ClientOne" = x."Id" AND f."Relation" IN (15,16,19,20)) OR (f."ClientTwo" = x."Id" AND f."Relation" IN (10,21,22,30))) > 0 ) THEN 1 ELSE 0 END AS "IsParent", CASE WHEN(x."Gender") THEN 1 ELSE 0 END AS "Gender", CASE WHEN (EXTRACT(year FROM now()) - x."YearOfBirth" < 150) THEN EXTRACT(year FROM now()) - x."YearOfBirth" ELSE x."YearOfBirth" END AS "Age", COALESCE(pr01."Rubrica",0) AS "R01", -- Семейное положение COALESCE(pr02."Rubrica",0) AS "R02", -- Инвалидность COALESCE(pr03."Rubrica",0) AS "R03", -- Одинокое проживание COALESCE(pr04."Rubrica",0) AS "R04", -- Выпускник интернатных учреждений COALESCE(pr05."Rubrica",0) AS "R05", -- Пенсионер COALESCE(pr06."Rubrica",0) AS "R06", -- Социально опасное положение COALESCE(pr07."Rubrica",0) AS "R07", -- Наличие заболеваний COALESCE(pr08."Rubrica",0) AS "R08", -- Социальный статус COALESCE(pr09."Rubrica",0) AS "R09", -- Из числа детей-сирот COALESCE(pr10."Rubrica",0) AS "R10", -- Молодая семья COALESCE(pr11."Rubrica",0) AS "R11", -- Получение пособий COALESCE(pr12."Rubrica",0) AS "R12", -- Семья усыновителей COALESCE(pr13."Rubrica",0) AS "R13", -- Опекунская семья COALESCE(pr14."Rubrica",0) AS "R14", -- Семья беженцев COALESCE(pr15."Rubrica",0) AS "R15", -- Приемная семья COALESCE(pr16."Rubrica",0) AS "R16" -- Отселенная семья FROM ( SELECT c."Id", c."FamilyId", c."Gender", c."YearOfBirth" FROM "Clients" AS c WHERE c."FamilyId" IN ( SELECT DISTINCT c."FamilyId" FROM "Service" AS s, "Service2Clients" AS sc, "Clients" AS c WHERE s."Date" BETWEEN '2015-01-01' AND '2015-12-31' AND s."Id" = sc."Service" AND c."Id" = sc."Client" AND s."State" > 0 AND sc."Present" ) ) AS x LEFT JOIN "Points2Rubrica" AS pr01 ON pr01."Point" = x."Id" AND pr01."System" & 2 = 2 AND pr01."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 111) LEFT JOIN "Points2Rubrica" AS pr02 ON pr02."Point" = x."Id" AND pr02."System" & 2 = 2 AND pr02."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 100) LEFT JOIN "Points2Rubrica" AS pr03 ON pr03."Point" = x."Id" AND pr03."System" & 2 = 2 AND pr03."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 104) LEFT JOIN "Points2Rubrica" AS pr04 ON pr04."Point" = x."Id" AND pr04."System" & 2 = 2 AND pr04."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 156) LEFT JOIN "Points2Rubrica" AS pr05 ON pr05."Point" = x."Id" AND pr05."System" & 2 = 2 AND pr05."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 106) LEFT JOIN "Points2Rubrica" AS pr06 ON pr06."Point" = x."Id" AND pr06."System" & 2 = 2 AND pr06."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 130) LEFT JOIN "Points2Rubrica" AS pr07 ON pr07."Point" = x."Id" AND pr07."System" & 2 = 2 AND pr07."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 153) LEFT JOIN "Points2Rubrica" AS pr08 ON pr08."Point" = x."FamilyId" AND pr08."System" & 2 = 2 AND pr08."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 114) LEFT JOIN "Points2Rubrica" AS pr09 ON pr09."Point" = x."FamilyId" AND pr09."System" & 2 = 2 AND pr09."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 112) LEFT JOIN "Points2Rubrica" AS pr10 ON pr10."Point" = x."FamilyId" AND pr10."System" & 4 = 4 AND pr10."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 125) LEFT JOIN "Points2Rubrica" AS pr11 ON pr11."Point" = x."FamilyId" AND pr11."System" & 4 = 4 AND pr11."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 128) LEFT JOIN "Points2Rubrica" AS pr12 ON pr12."Point" = x."FamilyId" AND pr12."System" & 4 = 4 AND pr12."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 155) LEFT JOIN "Points2Rubrica" AS pr13 ON pr13."Point" = x."FamilyId" AND pr13."System" & 4 = 4 AND pr13."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 126) LEFT JOIN "Points2Rubrica" AS pr14 ON pr14."Point" = x."FamilyId" AND pr14."System" & 4 = 4 AND pr14."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 154) LEFT JOIN "Points2Rubrica" AS pr15 ON pr15."Point" = x."FamilyId" AND pr15."System" & 4 = 4 AND pr15."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 152) LEFT JOIN "Points2Rubrica" AS pr16 ON pr16."Point" = x."FamilyId" AND pr16."System" & 4 = 4 AND pr16."Rubrica" IN (SELECT r."Id" FROM "Rubricator" AS r WHERE r."GroupId" = 127) ) AS y ) AS ff GROUP BY ff."FamilyId" Вот в нем пытаюсь соптимизировать эти поиски детей и родителей. Остальное - хоть и полотно, но считает по скорости приемлемо. Добавлено Цитата JoeUser @ Родитель - это клиент, имеющий ребенка, у которого нет своего ребенка Блин. Сложнее. Родитель - это клиент, имеющий детей, у которых нет своих детей. |
Сообщ.
#13
,
|
|
|
Цитата JoeUser @ у которых нет своих детей not exists не поможет? |
Сообщ.
#14
,
|
|
|
Цитата Bas @ not exists не поможет? Навряд ли. Если инвертировать "не дети", получаться все "взрослые" - а они не все родители. Хотя ... ты же не о том) Посмотрю. |
Сообщ.
#15
,
|
|
|
Я вообще считаю, что следует начать с нормализации. Это не дело, когда данные не проходят формального контроля целостности и потенциально противоречивы.
|