На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается для обсуждения вопросов использования баз данных, за исключением составления запросов на SQL. Для этого выделен специальный раздел. Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Chow, Bas, MIF
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Как сравнить два запроса в плане эффективности
    Доброго времени суток!

    Есть небольшая БД, порядка трех тысяч записей. Написал запрос. Выполняется достаточно быстро. Написал запрос и задумался, БД будет расти, на сколько запрос начнет притормаживать в будущем. Взял и переписал запрос по-другому. Оба запроса выполняются раз-через раз с приблизительно сопоставимым временем выполнения (результаты естественно идентичные). Посмотрите, пожалуйста, какой из них в потенциале будет тормознее, что-то я теряюсь в оценке.

    Запрос 1 (который написал первым)

    ExpandedWrap disabled
      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"

    Его эксплайн:
    Скрытый текст
    ExpandedWrap disabled
      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 (который надеялся написать лучше)

    ExpandedWrap disabled
      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"

    Его эксплайн:
    Скрытый текст
    ExpandedWrap disabled
      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


    Вообщем, чет кажется, что не лучшее ... а наоборот регресс :-?
      JoeUser
      Гораздо разумнее было бы привести DDL таблиц с комментариями по полям и чётко поставить задачу. А пытаться понять, что за хрень происходит в опубликованной лапше - это увольте...
        Цитата Akina @
        Гораздо разумнее было бы привести DDL таблиц с комментариями по полям и чётко поставить задачу.

        Ок, попробую. Таблиц и полей дофига, попробую сделать экстракт существенного:

        Таблица "Клиенты" (Clients)

        ПолеТипКоментарий
        IdSERIALУникальный ИД клиента
        FamilyIdINTEGERНомер семьи
        YearOfBirthINTEGERВозраст в годах, или год рождения


        Таблица "Семейные отношения" (Family)

        ПолеТипКоментарий
        ClientOneINTEGERКлиент, который имеет отношение
        ClientTwoINTEGERКлиент, к которому применяется отношение
        RelationINTEGERТип отношения


        Используемые типы отношений:
        • 10 - дочь
        • 21 - падчерица
        • 22 - пасынок
        • 30 - сын
        • 15 - мать
        • 16 - мачеха
        • 19 - отец
        • 20 - отчим

        В таблице отношений - отношения могут быть как односторонние, так и двусторонние. В случае двусторонних, они согласованы.

        Пример:

        ClientOne=123,ClientTwo=777,Relation=10
        Клиент 123 относится к клиенту 777 как "Дочь"

        Задача

        Вывести в порядке возрастания идентификаторов клиентов - всех клиентов определенной семьи, с указанием является ли клиент ребенком.

        Правило определения "Является ли ребенком"

        Нет собственных детей и возраст < 18 (если есть дети или возраст > 18, то не ребенок)
          Цитата JoeUser @
          отношения могут быть как односторонние, так и двусторонние. В случае двусторонних, они согласованы.

          Я правильно понимаю, что совокупность отношений может быть неполной? то есть при существовании записи, что А - сын/дочь Б, может НЕ существовать записи, что Б - отец/мать А?

          Цитата JoeUser @
          Используемые типы отношений:

          Я правильно понимаю, что речь идёт о документальной, а не биологической, связи?
            Блин, во втором варианте похоже два лишних джойна :-?

            Добавлено
            Цитата Akina @
            Я правильно понимаю, что совокупность отношений может быть неполной? то есть при существовании записи, что А - сын/дочь Б, может НЕ существовать записи, что Б - отец/мать А?


            Ага.

            Цитата Akina @
            Я правильно понимаю, что речь идёт о документальной, а не биологической, связи?


            Документальной. Отчим == Отцу
              В любом случае, я бы, наверное, пошёл по пути объединения двух быстрых запросов.
              Первый - получение списка всех членов семьи.
              Второй - получение списка только членов семьи, имеющих статус "ребёнок".
              Затем второй запрос включил бы как подзапрос в источник данных (т.е. именно в секции FROM, а никак не в SELECT) первого запроса для формирования статуса. Здесь следует добиться, чтобы оптимизатор понял, что подзапрос и основной запрос независимы - вплоть до оформления подзапроса в параметрический вьюв.
                Второй запрос немного сократил, убрал лишние проверки:
                ExpandedWrap disabled
                  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 лет.
                      M
                      commercial coder пишите по существу а не на "свободную тему о всем и не о чем"
                      Сообщение отредактировано: Bas -
                        Цитата JoeUser @
                        Важный момент, который я упускал, сперва - "ребенок в семье может не иметь родителей"

                        Это полностью соответствует озвученным ранее признакам. Избыточное уточнение.
                          Цитата Akina @
                          Это полностью соответствует озвученным ранее признакам. Избыточное уточнение.

                          Согласен.
                          Akina, есть еще небольшой вопрос. Код писать уже сил нет, вырубает. Но часов через шесть таки надо сделать. Задача подобного рода - найти "родителей". По требованию заказчика Родитель - это клиент, имеющий ребенка, у которого нет своего ребенка. Иными словами отсекаются бабушки и дедушки. В моей структуре БД все связи необязательны, и если отношение "Бабушка-внук/внучка" отсутствует в интерфейсе оно подменяется на "Родственник", посему нужеа цепочка сравнений.

                          Как считаешь, если я к клиенту прицеплю 4 джойна (2 проверю ребенка, 2 проверю отсутствие у него своих детей) - это будет нормальный подход? Другого пока на ум не приходит. Запрос и так вырос, но пока мысль не теряю. Так, для примера недоделанный запрос, должно быть всего 34 вычисляемых поля и еще одна группировка с подсчетами по всем полям:
                          ExpandedWrap disabled
                            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 @
                          Родитель - это клиент, имеющий ребенка, у которого нет своего ребенка

                          Блин. Сложнее. Родитель - это клиент, имеющий детей, у которых нет своих детей.
                          Сообщение отредактировано: JoeUser -
                            Цитата JoeUser @
                            у которых нет своих детей

                            not exists не поможет?
                              Цитата Bas @
                              not exists не поможет?

                              Навряд ли. Если инвертировать "не дети", получаться все "взрослые" - а они не все родители.
                              Хотя ... ты же не о том) Посмотрю.
                              Сообщение отредактировано: JoeUser -
                                Я вообще считаю, что следует начать с нормализации. Это не дело, когда данные не проходят формального контроля целостности и потенциально противоречивы.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0583 ]   [ 16 queries used ]   [ Generated: 26.04.24, 06:54 GMT ]