Необычный результат в запросе SQL - PostgreSQL - PullRequest
0 голосов
/ 22 февраля 2020

Я обнаружил это странное поведение с помощью этого запроса:

-- TP4N has stock_class = 'Bond'

select  lot.symbol
      , round(sum(lot.qty_left), 4) as "Qty"
  from  ( select  symbol
                , qty_left
--                , amount
            from trade_lot_tbl t01
            where t01.symbol not in (select symbol from stock_tbl where stock_class = 'Cash')
              and t01.qty_left > 0
              and t01.trade_date <= current_date        -- only current trades
           union 
           select  'CASH' as symbol
            , sum(qty_left) as qty_left
--            , sum(amount)   as amount
            from trade_lot_tbl t11
            where t11.symbol in (select symbol from stock_tbl where stock_class = 'Cash')
              and t11.qty_left > 0
              and t11.trade_date <= current_date        -- only current trades
            group by t11.symbol
        ) lot
  group by lot.symbol
  order by lot.symbol
;

Запускать как есть, Кол-во для TP4N равно 1804.42

Запускать без двух комментариев строки «количество», что насколько я могу судить, это НЕ должно влиять на результат, но Qty для TP4N = 1815.36. Только ОДИН из символов (TP4N) имеет измененное значение, все остальные остаются неизменными.

Выполнить со всей закомментированной инструкцией 'union' результаты в Qty для TP4N = 1827.17

Правильно Насколько я могу судить, ответ - 1827.17.

Итак, подведя итог, я могу получить три разных значения, изменив части запроса, которые, насколько я могу судить, НЕ должны влиять на ответ.

Я уверен, что я собираюсь ударить себя, когда загадка будет решена, это пахнет глупой ошибкой.

1 Ответ

3 голосов
/ 22 февраля 2020

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

Как правило: если вы не делаете для дедупликации необходимо использовать union all (что также более эффективно, поскольку базе данных не требуется искать дубликаты).

...