Изолировать счетчик, который приходит из LEFT JOIN независимо от фильтров предложения WHERE - PullRequest
0 голосов
/ 12 декабря 2018

В основном я хочу перечислить все имена профилей (Таблица профилей), каждый профиль имеет связку связанных с ним сущностей (Profile_Entity) и типы сущностей (Profile_EntityType).Итак, для каждого профиля я хочу подсчитать, сколько сущностей на каждом.

Это (количество) работает нормально, если я не фильтрую результаты.Но затем, если я пытаюсь отфильтровать по сущности (посмотреть, относится ли такая сущность к профилю), это испортит мой счетчик сущностей.Это происходит потому, что, когда таблица фильтруется, строки, в которых EntityIDBP (служит EntityIDBP) не отображаются, исчезают, и счетчик подсчитывает строки отфильтрованной таблицы, где я хотел бы, чтобы она придерживалась исходной.

Итак, я попытался изолировать счет с помощью LEFT JOIN, но без успеха.

Это то, что у меня сейчас есть

SELECT  {Profile}.[Id],
            {Profile}.[Name],
            Count (ProfileCount.IDBP)
     FROM {Profile}
     LEFT JOIN
      ((
     /* Get all the entities that belong to a profile, trough the entity type */
        SELECT  P2.[Id] as Id,
                P2.[Name] as ProfileName,
                {Entity}.[EntityIDBP] as IDBP

         FROM    {Profile} as P2
         LEFT JOIN {Profile_EntityType} ON ({Profile_EntityType}.[ProfileId] = P2.[Id])
         LEFT JOIN    {Entity} ON ({Entity}.[EntityType_IDBP] = {Profile_EntityType}.[EntityType_IDBP] )

          UNION

        /* Get all the entities that belong to a profile directly, trough the Profile_Entity.isToInclude = 1  */
        SELECT   P2.[Id] as Id,
                    P2.[Name] as ProfileName,
                    {Entity}.[EntityIDBP] as IDBP             
         FROM    {Profile} as P2
         LEFT JOIN   {Profile_Entity} ON ({Profile_Entity}.[ProfileId] = P2.[Id] AND {Profile_Entity}.[IsToInclude] = 1)
         LEFT JOIN    {Entity} ON ({Entity}.[EntityIDBP] = {Profile_Entity}.[EntityIDBP] 

          )EXCEPT(

         /* The subquery that gets all the entities that shouldn't be accounted for the Count (Profile_Entity.isToInclude = 0)  */
         SELECT   P2.[Id] as Id,
                  P2.[Name] as ProfileName,
                  {Entity}.[EntityIDBP] as IDBP

          FROM    {Profile} as P2
          JOIN   {Profile_Entity} ON ({Profile_Entity}.[ProfileId] = P2.[Id] AND {Profile_Entity}.[IsToInclude] = 0)
          JOIN    {Entity} ON ({Entity}.[EntityIDBP] = {Profile_Entity}.[EntityIDBP] ))) as ProfileCount ON ({Profile}.[Id] = ProfileCount.Id)

WHERE ProfileCount.IDBP IN (301000044)  
/* The Filter used to know if a profile has a entity or not ; Right now it's a fixed value just to demonstrate*/ 
/*The 301000044 represents the Entity IDBP */

GROUP BY {Profile}.[Name],{Profile}.[Id])

Для примера вот данныемодельные столы. Таблица профилей:

|---------------------|------------------|
|Id  |    Name        |     (...)        |
|---------------------|------------------|
|10  | Profile1       |        (...)     |
|---------------------|------------------|

Таблица Profile_Entity:

|---------------------|------------------|-----------------------------|
|      ProfileId      |     EntityIDBP   |isToInclude                  |
|                     |serves as the     |/*this representes wheter the| 
|                     |unique id         | entity should be considered | 
|                     |                  |  for the count (=1) or not  |
|                     |                  |   (=0) */                   |
|---------------------|------------------|-----------------------------|
|     10              |       301000044  | 1                           |
|---------------------|------------------|-----------------------------|
|                     |                  |                             |
|     10              |       301000045  | 1                           |
----------------------|------------------|-----------------------------| 
|     10              |       301000043  | 0 /* goes into the EXCEPT   |
|                     |                  |         clause */           |
|---------------------|------------------|   /*thus the EXCEPT clause*/|

Таблица Profile-EntityType:

|---------------------|------------------|
|Id  |EntityType_IDBP |     (...)        |
|---------------------|------------------|
|10  | ProfileType    |          -----   |
|---------------------|------------------|

/*Then on the EntityTable  I would have all the Entities that belong to this 
type and aggregate them all together. Let's imagine it's 10 */

Таблица сущностей

|---------------------|------------------|
|Id  |    EntityIDBP  | EntityType_IDBP  | /* 10 entities (records) with this 
|                     |                  |   TypeCod */
|---------------------|------------------|
|10  | IDBP           |      ProfileType | 
|---------------------|------------------|

Ожидаемый результат:

|---------------------|------------------|
|Id  |    ProfileName |     EntityCount  |
|---------------------|------------------|
|10  | Profile1       |        11        |
|---------------------|------------------|

Количество равно 11, потому что есть два(2) сущности с isToInclude = 1 в таблице Profile_Entity минус 1 сущность из Profile_Entity с isToInclude = 0 (предложение Except) плюс 10 штук с этим типом.

Obs.Синтаксис может немного отличаться от того, к которому вы привыкли, потому что это делается на платформе Outsystems.

1 Ответ

0 голосов
/ 14 декабря 2018

Завершено использованием временной таблицы, которую я получаю, чтобы получить все сущности из профиля (объединение и исключение) в качестве условия для этого же запроса, где единственное отличие состоит в том, что я передаю эту вторую IDBP сущностиЯ хочу отфильтровать.Итак, у меня есть что-то вроде этого

SELECT A.ProfileName, A.ProfileId, Count(A.IDBP)
 FROM (
       SELECT 'all entities IDBP associated with a profile, as well as its Id and Name' as A
       WHERE A.IDBP IN (A WHERE Entity.IDBP = 'xxxx')
      )

Это сохраняет количество и выполняет фильтрацию

...