2016-06-14 7 views
-1

У меня есть таблица транзакций, которая включает три столбца: transactionType, amount и transactionTimestamp. Столбец transactionType принимает значения 1 (наличные), 2 (чеки) или 3 (кредитные карты).SQL Множественный выбор из той же таблицы

Мне нужно показать общую сумму каждой транзакции. Тип в день. Я могу сделать это, используя отдельные запросы для каждого transactionType легко:

SELECT SUM(amount) AS cashTotal, dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
    FROM TransactionRecords 
    WHERE transactionType = 1 
    GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

    SELECT SUM(amount) AS checkTotal, dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
    FROM TransactionRecords 
    WHERE transactionType = 2 
    GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

    SELECT SUM(amount) AS cardTotal, dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
    FROM TransactionRecords 
    WHERE transactionType = 3 
    GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

Но что мне нужно сделать, чтобы сделать это в одном запросе. Я попытался комбинируя выше в одну, как показано ниже:

SELECT 
     (SELECT SUM(amount) FROM TransactionRecords WHERE transactionType = 1 GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp))) AS cashTotal, 
     (SELECT SUM(amount) FROM TransactionRecords WHERE transactionType = 2 GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp))) AS checkTotal, 
     (SELECT SUM(amount) FROM TransactionRecords WHERE transactionType = 3 GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp))) AS cardTotal, 
     dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
    FROM TransactionRecords 
    GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

Но это только приводит к «подзапрос возвращает более чем 1 значение» ошибка. И я чувствую, что это не так, как это должно быть сделано в любом случае. Спасибо за любой совет.

EDIT: Я хотел уточнить немного, что я пытаюсь вывода результатов, как следующее:

---------------------------------------------------- 
cashTotal | checkTotal | cardTotal | transactionDay 
---------------------------------------------------- 
1000  | 1000  | 1000  | date 
0   | 500   | 0   | date 
---------------------------------------------------- 

Каждая строка показывает общее количество каждого transactionType для этого конкретного дня.

EDIT: некоторые детали отредактированы для удаления конфиденциальной информации.

+1

Почему вы не используете 'CASE..WHEN'? – MusicLovingIndianGirl

+0

Вы ищете 'UNION'? – jleach

+1

Просьба не обманывать и не испортить ваши сообщения. –

ответ

1

Просто используйте условную агрегацию с CASE EXPRESSION:

SELECT 
     SUM(CASE WHEN paymentType = 1 THEN amount ELSE 0 END) as cashTotal, 
     SUM(CASE WHEN paymentType = 2 THEN amount ELSE 0 END) as chequeTotal, 
     SUM(CASE WHEN paymentType = 3 THEN amount ELSE 0 END) as cardTotal, 
     dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
    FROM PaymentRecords 
    GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

Хотя эта строка кажется странной

dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) 

вы имели в виду, чтобы Trunc в DateTime? Если это так, замените это на:

CAST(transactionTimestamp as DATE) 
+0

Привет, спасибо за ваш совет, но мне любопытно узнать, как добраться до ELSE 0, спасибо. – Alycus

+0

Что это значит? – sagi

+0

Извините, я имею в виду, в какой ситуации SUM использует 0 вместо суммы. Я нашел ответ здесь: http: //dba.stackexchange.com/questions/120003/what-do-then-1-else-0-mean-in-a-case-expression-used-with-an-aggregate-functio, но я хотел быть уверенным. – Alycus

1

Таким образом, вы хотите, чтобы верхняя группа просто по платежному типу?

SELECT SUM(amount) AS cashTotal 
    , paymentType 
    , dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)) AS transactionDay 
FROM PaymentRecords 
GROUP BY paymentType 
     , dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); 

Вы можете добавить ORDER BY, чтобы получить детали в нужном порядке (по типу, то дата, или наоборот)

1

Вы можете использовать условную агрегацию. Кроме того, вы можете преобразовать в date удалить временную составляющую даты:

SELECT SUM(CASE WHEN transactionType = 1 THEN amount ELSE 0 END) as cashTotal, 
     SUM(CASE WHEN transactionType = 2 THEN amount ELSE 0 END) as checkTotal, 
     SUM(CASE WHEN transactionType = 3 THEN amount ELSE 0 END) as cardTotal, 
     CAST(transactionTimestamp as DATE) as TransactionDay 
FROM TransactionRecords 
GROUP BY CAST(transactionTimestamp as DATE) 
ORDER BY CAST(transactionTimestamp as DATE); 
0

В своем подходе последняя строка "GROUP BY dateadd(DAY, 0, datediff(DAY, 0, transactionTimestamp)); не требуется, я предполагаю ..

и выглядит, как вам просто нужно группе Paymentype и передам день .. что-то вроде

Select sum(amnt),payment_type,transactionDay from PaymentRecords group by payment_type,transactionDay

Примечание: Форматирование transactionDay в соответствии с ур необходимости.

Смежные вопросы