Как отфильтровать результаты в запросе GROUP BY по столбцу, который не включен в результаты? - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть следующие результаты:

results without filtering

Получено с помощью этого запроса:

SELECT b.name, ISNULL(SUM(amount),0) AS 'Total', ISNULL(AVG(amount),0) AS 'Average'
FROM User_Transaction a
RIGHT OUTER JOIN Category b ON (a.category_id = b.category_id)
GROUP BY b.name

Содержит итоговые и средние значения всех финансовых транзакций, которые пользователи зарегистрировали, независимо от того, когда транзакция была зарегистрирована.

В таблице User_Transaction есть столбец datestamp, который я хотел бы отфильтровать. Поэтому я пробую следующее:

SELECT b.name, ISNULL(SUM(amount),0) AS 'Total', ISNULL(AVG(amount),0) AS 'Average'
FROM User_Transaction a
RIGHT OUTER JOIN Category b ON (a.category_id = b.category_id)
WHERE 
 a.datestamp BETWEEN @date_from AND @date_to
GROUP BY b.name
ORDER BY b.name

Это дает мне:

results with failed filtering

Записи Other и Salary отсутствуют, потому что никто никогда не совершал транзакции с этими именами и, следовательно, нет даты для фильтрации.

Однако я хотел бы включить эти имена, но все равно ноль для их значений. Как я могу это сделать?

Ответы [ 4 ]

2 голосов
/ 13 апреля 2019

Хорошо, так что, по сути, вы хотите перечислить ВСЕ категории и включить Итого и Среднее, где такие данные доступны в указанный период времени?

Если это ваше намерение, то читайте дальше!

Прежде всего я переформатировал запрос, чтобы облегчить понимание структуры.Я переименовал псевдоним таблицы для User_Tranaction с «a» на «ut», а псевдоним для категории с «b» на «cat»

SELECT 
    cat.name, 
    ISNULL(SUM(amount),0) AS 'Total', 
    ISNULL(AVG(amount),0) AS 'Average'
FROM 
    User_Transaction AS ut
    RIGHT OUTER JOIN Category AS cat 
        ON ut.category_id = cat.category_id
WHERE 
    ut.datestamp BETWEEN @date_from AND @date_to
GROUP BY 
    cat.name
ORDER BY 
    cat.name

Для достижения желаемого эффекта перечисления всех категорий итолько соответствующие пользовательские транзакции за период времени, я перевернул объединение таблиц, чтобы использовать LEFT OUTER JOIN из категории в User_Transaction.Кроме того, я переместил фильтрацию даты в предложение ON в соединении с User_Transaction.Это дает эффект предварительной фильтрации данных в User_Transactions до , результирующие данные связаны с данными категории.

SELECT 
    cat.name, 
    ISNULL(SUM(amount),0) AS 'Total', 
    ISNULL(AVG(amount),0) AS 'Average'
FROM 
    Category AS cat
    LEFT OUTER JOIN User_Transaction AS ut
        ON cat.category_id = ut.category_id
        AND ut.datestamp BETWEEN @date_from AND @date_to
GROUP BY 
    cat.name
ORDER BY 
    cat.name

Надеюсь, что это поможет.

1 голос
/ 13 апреля 2019

Вот, пожалуйста,

SELECT c.name, ISNULL(SUM(amount),0) AS 'Total', ISNULL(AVG(amount),0) AS 'Average'
FROM User_Transaction ut
RIGHT OUTER JOIN Category c ON (ut.category_id = c.category_id)
WHERE 
    (ut.datestamp BETWEEN @date_from AND @date_to) OR ut.datestamp IS NULL
GROUP BY c.name
ORDER BY c.name
1 голос
/ 13 апреля 2019

Попробуйте добавить OR a.datestamp IS NULL к условию where:

SELECT b.name, ISNULL(SUM(amount),0) AS 'Total', ISNULL(AVG(amount),0) AS 'Average'
FROM User_Transaction a
RIGHT OUTER JOIN Category b ON (a.category_id = b.category_id)
WHERE 
 a.datestamp BETWEEN @date_from AND @date_to OR a.datestamp IS NULL
GROUP BY b.name
ORDER BY b.name
0 голосов
/ 13 апреля 2019

Я думаю, что это будет работать с UNION: сначала поместите ваш запрос, а во второй части UNION выберите записи, в которых нет дат для фильтрации.Это должно работать так

...