Сложный SQL-запрос с группировкой и наличием - PullRequest
0 голосов
/ 17 декабря 2009

У меня есть стол заказов

orders (
id  int unsigned not null,
fcr_date  TIMESTAMP,
completion_date TIMESTAMP,
factory_no  varchar(255),
vendor_no  varchar(255))

Пожалуйста, игнорируйте опечатки типа данных, если таковые имеются.

Я хочу написать SQL-запрос, который поможет мне отфильтровать данные по фабрике поставщиков. Данные для выборки включают количество заказов на фабрику поставщика (уникальная группа vendor_no, factory_no), vendor_no, factory_no и процент заказов, для которых fcr_date больше, чем sequence_date (так, процент = количество заказов, где fcr_date больше, чем завершение дата / количество заказов). После этого мне нужно отфильтровать данные, где процент больше, чем, скажем, 20%.

Я написал следующий запрос:

SELECT  vendor_no As vendor,
        factory_no As factory,
        COUNT(1) as count,
        SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) as filter_orders,
    ROUND(filter_orders / count * 100, 4) as  percent  
FROM    @orders
GROUP BY vendor_no,
        factory_no
HAVING percent>20

но postgresql жалуется на то, что для фильтрации результатов на основе этого необходимо иметь столбец с именем процентов в таблице. Любая помощь приветствуется.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 17 декабря 2009

Измените его на:

HAVING ROUND(filter_orders / count * 100, 4) > 20

Поскольку percent не является действительным столбцом, вам необходимо дать ему вычисление для выполнения фильтра.

Редактировать

Хорошо, если посмотреть дальше, у вас есть как минимум два способа написать это: первый, который я бы порекомендовал, - это завершение в подзапрос (как уже предлагали):

Вариант 1

SELECT  vendor As vendor,
        factory As factory,
        [count],
        ROUND(filter_orders / count * 100, 4) as  [percent]
FROM
(
    SELECT  vendor_no As vendor,
            factory_no As factory,
            COUNT(1) as count,
            SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) as filter_orders
    FROM    @orders
    GROUP BY vendor_no,
            factory_no
) AS a
WHERE ROUND(filter_orders / count * 100, 4) > 20

Вариант 2

SELECT  vendor_no As vendor,
        factory_no As factory,
        COUNT(1) as count,
        SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) as filter_orders,
        ROUND(SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) / count(1) * 100, 4) as  [percent]
FROM    @orders
GROUP BY vendor_no,
        factory_no
HAVING ROUND(SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) / count(1) * 100, 4) > 20
1 голос
/ 18 декабря 2009

Оберните ваш запрос внешним фильтрующим запросом:

SELECT * FROM (
    SELECT  vendor_no As vendor,
            factory_no As factory,
            COUNT(1) as count,
            SUM(CASE WHEN fcr_date > completion_date THEN 1 ELSE 0 END) as filter_orders,
        ROUND(filter_orders / count * 100, 4) as  percent  
    FROM    @orders
    GROUP BY vendor_no,
            factory_no
) x
WHERE percent>20
0 голосов
/ 17 декабря 2009

Я почти уверен, что вы не можете использовать псевдонимы (например, проценты) при наличии предложений или групп по предложениям. И под "симпатичным" я подразумеваю, что Oracle не позволит мне использовать псевдонимы в предложениях / group by ... не уверен насчет других поставщиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...