запрос postgresql с AND / OR / UNION - PullRequest
1 голос
/ 19 января 2012

У меня проблемы с «расширенным» (по моим стандартам) запросом в Postgresql, и я не уверен, как мне искать ответ (ключевые слова и т. Д.).Я просмотрел примеры из справочника Postgresql и искал stackOverflow для поиска похожих потоков, но безрезультатно ...

У меня есть две таблицы: одна с векселями и одна с транзакциями, и таблица, которую я хотел бывыходные данные содержат только те транзакции, которые 1) более поздние, чем счет, 2) меньше или равны счету 3) на конкретном счете ИЛИ оплачены наличными.

Этот запрос делает именно это, но я полагаюего можно оптимизировать:

((SELECT * FROM transactions 
WHERE amount = to_number('$bill_amount','99999999D99')
AND acc_int = 'cash'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
UNION
(SELECT * FROM transactions 
WHERE amount = to_number('$bill_amount','99999999D99')
AND acc_int = 'xxx-xxxxxxx-xx'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
ORDER BY date DESC)
UNION
((SELECT * FROM transactions 
WHERE amount < to_number('$bill_amount','99999999D99')
AND acc_int = 'cash'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
UNION
(SELECT * FROM transactions 
WHERE amount < to_number('$bill_amount','99999999D99')
AND acc_int = 'xxx-xxxxxxx-xx'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
ORDER BY date DESC)

Первые два выбора можно объединить, если бы я мог просто добавить OR к условию acc_int, не нарушая другие условия.Я думал, что это должно быть сделано с помощью скобок, но это, похоже, не сработало.

Кроме того, я хотел бы отсортировать результат так, чтобы сначала все транзакции равнялись сумме в счете, а затем по датеменьшие суммы - вот почему я комбинирую первые два выбора с последними двумя выборами, но использование UNION, кажется, нарушает порядок.

THX для любого понимания (ответы или ссылки на хорошие ресурсы приветствуются!)

Ответы [ 2 ]

1 голос
/ 20 января 2012

Полный запрос может выглядеть так:

SELECT *
FROM   transactions 
WHERE  amount <= to_number('$bill_amount','99999999D99')
AND    acc_int IN ('cash', 'xxx-xxxxxxx-xx')
AND    date > to_date('$bill_date', 'YYYY-MM-DD')
ORDER  BY
      (amount <> to_number('$bill_amount','99999999D99'))
     , date DESC
  • FALSE сортирует до TRUE, поэтому у меня есть оператор <> в выражении ORDER BY.

  • Учтите, что в исходном запросе UNION удаляет повторяющиеся строки. Если у вас нет полных дубликатов в вашей таблице, результат будет таким же (и UNION ALL был бы лучшим выбором для начала). Если это так, добавьте предложение DISTINCT:

    SELECT DISTINCT * ...
    
  • Вы пишете, что OR, похоже, не работает для вас. Но это должно быть. Это ..

    AND    acc_int IN ('cash', 'xxx-xxxxxxx-xx')
    

    .. в точности соответствует:

    AND   (acc_int = 'cash' OR acc_int = 'xxx-xxxxxxx-xx')
    

Фактически планировщик запросов переписывает первую форму во вторую.

1 голос
/ 19 января 2012

Что-то вроде этого возможно:

SELECT * FROM transactions 
WHERE amount <= to_number('$bill_amount','99999999D99')
AND acc_int IN ('cash', 'xxx-xxxxxxx-xx')
AND date = to_date('$bill_date', 'YYYY-MM-DD')
ORDER BY date DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...