Как я могу ВЫБРАТЬ, основываясь на запросах NOT EQUAL и NOT EXISTS в Oracle со сложными таблицами FROM - PullRequest
0 голосов
/ 08 февраля 2019

Я хочу объединить ОБА этих запросов в ОДИН запрос, который возвращает ВСЕ результаты из EITHER


Запрос A:

SELECT prsn.prsn_id, person_points.points
  FROM persons prsn,
       (SELECT prsn_id prsn_id, sum(points) points
          FROM (SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       invoices inv,
                       transaction_details tdet,
                       orders ord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id     = pnts.tdet_id
                   AND tdet.inv_id      = inv.inv_id
                   AND inv.ord_id       = ord.ord_id
                   AND ord.prsn_id_byr  = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       reward_order_details rdet,
                       reward_orders rord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND rdet.rdet_id     = pnts.rdet_id
                   AND rord.rord_id     = rdet.rord_id
                   AND rord.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       miscellaneous_points misp,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND pnts.mpts_id     = misp.mpts_id
                   AND misp.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                   UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       transaction_details tdet,
                       returns rtn,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id    = pnts.tdet_id
                   AND tdet.rtn_id     = rtn.rtn_id
                   AND rtn.prsn_id_byr = prsn.prsn_id
              GROUP BY prsn.prsn_id)
        GROUP BY prsn_id) person_points
 WHERE person_points.points > 0
   AND person_points.prsn_id = prsn.prsn_id
   AND (NOT EXISTS (SELECT 1
                      FROM point_summaries x
                     WHERE x.prsn_id = prsn.prsn_id))

Запрос B

SELECT prsn.prsn_id, person_points.points, psum.psum_points_available
  FROM persons prsn,
       point_summaries psum,
       (SELECT prsn_id prsn_id, sum(points) points
          FROM (SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       invoices inv,
                       transaction_details tdet,
                       orders ord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id     = pnts.tdet_id
                   AND tdet.inv_id      = inv.inv_id
                   AND inv.ord_id       = ord.ord_id
                   AND ord.prsn_id_byr  = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       reward_order_details rdet,
                       reward_orders rord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND rdet.rdet_id     = pnts.rdet_id
                   AND rord.rord_id     = rdet.rord_id
                   AND rord.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       miscellaneous_points misp,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND pnts.mpts_id     = misp.mpts_id
                   AND misp.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                   UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       transaction_details tdet,
                       returns rtn,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id    = pnts.tdet_id
                   AND tdet.rtn_id     = rtn.rtn_id
                   AND rtn.prsn_id_byr = prsn.prsn_id
              GROUP BY prsn.prsn_id)
        GROUP BY prsn_id) person_points
 WHERE person_points.points > 0
   AND prsn.prsn_id = psum.prsn_id
   AND person_points.prsn_id = prsn.prsn_id
   AND NOT psum.psum_points_available = person_points.points

Основная часть этих утверждений Объединяет все различные области. Можно рассчитать бонусные баллы в нашей системе, привязать эти суммы к идентификатору человека, а затем вывести текущие итоговые баллы, о которых сообщается, икакими они должны быть через расчет.

Смысл в том, чтобы найти всех людей в нашей системе и исправить все неправильно рассчитанные призовые очки.

Это может быть неверно двумя способами:

  1. Суммарные рассчитанные бонусные баллы отличаются от points_summary.psum_points_available
  2. Суммарные рассчитанные бонусные баллы существуют, ноСтрока point_summary с корреляцией prsn_id пока не существует.

Основные различия в двух запросах заключаются в следующем:

Запрос A

WHERE person_points.points > 0
  AND person_points.prsn_id = prsn.prsn_id
  AND (NOT EXISTS (SELECT 1
                     FROM point_summaries x
                    WHERE x.prsn_id = prsn.prsn_id))

ЗапросB

WHERE person_points.points > 0
  AND prsn.prsn_id = psum.prsn_id
  AND person_points.prsn_id = prsn.prsn_id
  AND NOT psum.psum_points_available = person_points.points

Запрос A Возвраты:

| prsn_id | points       |
|------------------------|
|111111   | 169          |
|111112   | 104          |
|111113   | 116          |
|111114   | 219          |
|111114   | 88           |
|111115   | 395          |
|111115   | 35           |

Запрос B Возвраты:

| prsn_id | points | psum_points_available |
|------------------------------------------|
| 111111  | 676    | 287                   |
| 111111  | 11672  | 1971                  |
| 111111  | 137    | 89                    |
| 111111  | 156    | 78                    |
| 111111  | 5111   | 570                   |
| 111111  | 280    | 193                   |

Я хотел бы объединить эти два запроса в один и получить вывод, который выглядит примерно так:

Что бы я хотел, чтобы запрос COMBINED вернул:

| prsn_id | points | psum_points_available |
|------------------------------------------|
| 111111  | 100    | NULL or 0             |
| 111112  | 11672  | 1971                  |
| 111113  | 137    | 89                    |
| 111114  | 156    | NULL or 0             |
| 111114  | 5111   | NULL or 0             |
| 111115  | 280    | 193                   |

Я попытался объединить оператор OR следующим образом:

Запрос COMBINED

WHERE person_points.points > 0
  AND psum.prsn_id = prsn.prsn_id
  AND ((psum.prsn_id = prsn.prsn_id
        AND NOT psum.psum_points_available = person_points.points)
       OR NOT EXISTS (SELECT 1
                        FROM ci_point_summaries x
                       WHERE x.prsn_id = prsn.prsn_id))

Однако это возвращает:

| prsn_id | points | psum_points_available |
|------------------------------------------|
| 111111  | 676    | 38                    |
| 111112  | 676    | 40                    |
| 111113  | 676    | 0                     |
| 111114  | 676    | 33                    |
| 111115  | 676    | 420                   |
| 111116  | 676    | 35                    |
| 111117  | 676    | 60                    |

Обратите внимание, какрасчетные точки (обозначенные points ) одинаковы для каждой строки.


Я слишком долго смотрел на это и могу 'не понимаю, почему.Я просто где-то допускаю простую ошибку, потому что это почти то, чего я хочу.Я новичок в SQL (~ 1 месяц работы) и не могу найти нюанс, что здесь происходит не так.

1 Ответ

0 голосов
/ 08 февраля 2019

Я понял, как решить эту проблему, используя LEFT OUTER JOIN вместо FROM нескольких таблиц.

LEFT OUTER JOIN point_summaries psum on psum.prsn_id = prsn.prsn_id
  WHERE person_points.points > 0
    AND person_points.prsn_id = prsn.prsn_id
    AND ((NOT psum.psum_points_available = person_points.points)
        OR NOT EXISTS (SELECT 1
                         FROM point_summaries x
                        WHERE x.prsn_id = prsn.prsn_id))

Это позволило мне получить желаемые результаты с (ноль) в psum.psum_points_available с предложением OR.


Полный запрос:

SELECT prsn.prsn_id, person_points.points, psum.psum_points_available
  FROM (SELECT prsn_id prsn_id, sum(points) points
          FROM (SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       invoices inv,
                       transaction_details tdet,
                       orders ord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id     = pnts.tdet_id
                   AND tdet.inv_id      = inv.inv_id
                   AND inv.ord_id       = ord.ord_id
                   AND ord.prsn_id_byr  = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       reward_order_details rdet,
                       reward_orders rord,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND rdet.rdet_id     = pnts.rdet_id
                   AND rord.rord_id     = rdet.rord_id
                   AND rord.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                       UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       miscellaneous_points misp,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND pnts.mpts_id     = misp.mpts_id
                   AND misp.prsn_id     = prsn.prsn_id
              GROUP BY prsn.prsn_id
                   UNION ALL
                SELECT prsn.prsn_id, SUM(pnts.pnts_points) points
                  FROM points pnts,
                       transaction_details tdet,
                       returns rtn,
                       persons prsn
                 WHERE pnts.pnts_status = 'R'
                   AND tdet.tdet_id    = pnts.tdet_id
                   AND tdet.rtn_id     = rtn.rtn_id
                   AND rtn.prsn_id_byr = prsn.prsn_id
              GROUP BY prsn.prsn_id)
        GROUP BY prsn_id) person_points,
        persons prsn
LEFT OUTER JOIN point_summaries psum on psum.prsn_id = prsn.prsn_id
  WHERE person_points.points > 0
    AND person_points.prsn_id = prsn.prsn_id
    AND ((NOT psum.psum_points_available = person_points.points)
        OR NOT EXISTS (SELECT 1
                         FROM point_summaries x
                        WHERE x.prsn_id = prsn.prsn_id))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...