2016-11-01 2 views
0

Вот мой запрос, как он стоит, и она работает:SQL фильтра на сумму

SELECT EXPENDITURES.CNTRT, 
EXPENDITURES.L_CNTRT, 
EXPENDITURES.BE, 
EXPENDITURES.L_BE, 
EXPENDITURES.SPGM_STD, 
EXPENDITURES.L_SPGM, 
EXPENDITURES.CAT, 
EXPENDITURES.L_CAT, 
EXPENDITURES.OCA, 
EXPENDITURES.L_OCA, 
EXPENDITURES.L2, 
EXPENDITURES.L1L5, 
EXPENDITURES.L_L1L5, 
EXPENDITURES.OBJ, 
EXPENDITURES.L_OBJ, 
EXPENDITURES.STFY, 
EXPENDITURES.CF, 
EXPENDITURES.TRNS_AMT, 
EXPENDITURES.MGDT, 
EXPENDITURES.VENDOR_ID_NO, 
EXPENDITURES.VENDOR_LONG_NAME, 
EXPENDITURES.DESCRIPTION, 
EXPENDITURES.INVOICE_NO, 
EXPENDITURES.DN, 
EXPENDITURES.OTHER_DOC_NO, 
EXPENDITURES.PRIM_DOC_NO, 
EXPENDITURES.SECOND_DOC_NO, 
EXPENDITURES.TR 
FROM IDS.EXPENDITURES EXPENDITURES 
WHERE ((EXPENDITURES.BE<>'70212349')) 
AND (EXPENDITURES.OCA LIKE '%C') 
AND (EXPENDITURES.STFY='2017') 
AND (EXPENDITURES.CF<>'C') 
AND ((EXPENDITURES.MGDT<={ts '2016-07-31 00:00:00'}) AND (EXPENDITURES.MGDT>={ts '2016-07-01 00:00:00'})) 

Что меня попросили сделать, это сделать так, чтобы, если только группа полями до CF, сумма на основе TRNS_AMT и сумму TRNS_AMT <> 0, тогда возвратите все остальные данные по этим транзакциям.

Я не являюсь человеком SQL и должен был сделать все это вручную и был бы признателен за любую помощь в том, что мне нужно сделать. Я пробовал делать HAVING и GROUP BY, но он не позволял мне пропускать все поля после TRNS_AMT из GROUP BY, и все эти поля после GROUP BY вызывают проблему, потому что они не идентичны для любой транзакции, что приводит к без фильтрации на TRNS_AMT.


Так, на английском языке, мне нужно сначала найти, какие сделки, чьи суммы сгруппированных вместе первые 17 полей, не равны нулю, и вернуть все 28 полей на ненулевых результатов с их TRNS_AMT unsummed , пользователю.

+0

Пожалуйста, добавьте тег для RDBMS, который вы используете, включая версию, если это возможно. – DeanOC

+0

@DeanOC Я знаю, что это Oracle, потому что мне нужно было искать драйверы, чтобы подключиться к нему, но это все. Я просто пользователь и спорадический пользователь. – Fixer

ответ

0

Эта версия sum(), называется «аналитический вариант», позволяет еще показать все строки из базовой таблицы, и вычислить сумму «как если бы» вы группировки всех этих столбцов - сумма будет одинаковой для всех строк, входящих в группу. Затем вы отфильтровываете строки, где сумма равна нулю. (Вам нужно сделать это с аналитическими функциями - нет аналога с условием HAVING, которое существует только для «агрегатной версии»).

Когда вы выбираете все из одной базовой таблицы, нет необходимости префикс имени столбца с именем таблицы (и если да, то дайте таблице однобуквенный псевдоним, например FROM IDS.EXPENDITURES E, и напишите столбцы, как E.CNTRT, облегчите глаза).

+0

@Phicksur - пожалуйста, продолжайте следить, если вы проверите результаты и почувствуете, что запрос работает не так. Возможно, я неправильно понял одно или несколько ваших требований или что вы что-то не поняли в том, что я написал. (Возможно также, что у вычислений вручную есть ошибки!) Удачи! – mathguy

+0

Первое место, где я буду искать причины несоответствия, - округление. Если «ручная» проверка обнаруживает дополнительные записи, которые могут быть удалены, возможно, фактическая сумма (плюсы и минусы) не равна нулю, а может быть 0,01, и вы смотрите на результаты, округленные до доллара. Это можно решить в запросе, предложение 'WHERE' может быть записано для проверки на' abs (tot_trns_amt)> 0.01' и т. Д. – mathguy

0

Вы не упомянули, какую СУБД вы запрашиваете. Я думаю, что он будет работать на SQL Server 2012 или новее и, возможно, оракуле, но я не уверен.

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

Вы также можете использовать обычную сумму в КТР и присоединиться к нему обратно с ключевыми значениями, но я не был уверен, что это будет.

 WITH NonZeroTransactions AS(

      SELECT  TotalTRNSAMT =SUM(TRNS_AMT)OVER(PARTITION BY   
                  EXPENDITURES.CNTRT, 
                  EXPENDITURES.L_CNTRT, 
                  EXPENDITURES.BE, 
                  EXPENDITURES.L_BE, 
                  EXPENDITURES.SPGM_STD, 
                  EXPENDITURES.L_SPGM, 
                  EXPENDITURES.CAT, 
                  EXPENDITURES.L_CAT, 
                  EXPENDITURES.OCA, 
                  EXPENDITURES.L_OCA, 
                  EXPENDITURES.L2, 
                  EXPENDITURES.L1L5, 
                  EXPENDITURES.L_L1L5, 
                  EXPENDITURES.OBJ, 
                  EXPENDITURES.L_OBJ, 
                  EXPENDITURES.STFY, 
                  EXPENDITURES.CF 
                 ORDER BY 
                  EXPENDITURES.CNTRT 
                 ), 
    EXPENDITURES.CNTRT, 
    EXPENDITURES.L_CNTRT, 
    EXPENDITURES.BE, 
    EXPENDITURES.L_BE, 
    EXPENDITURES.SPGM_STD, 
    EXPENDITURES.L_SPGM, 
    EXPENDITURES.CAT, 
    EXPENDITURES.L_CAT, 
    EXPENDITURES.OCA, 
    EXPENDITURES.L_OCA, 
    EXPENDITURES.L2, 
    EXPENDITURES.L1L5, 
    EXPENDITURES.L_L1L5, 
    EXPENDITURES.OBJ, 
    EXPENDITURES.L_OBJ, 
    EXPENDITURES.STFY, 
    EXPENDITURES.CF, 
    EXPENDITURES.TRNS_AMT, 
    EXPENDITURES.MGDT, 
    EXPENDITURES.VENDOR_ID_NO, 
    EXPENDITURES.VENDOR_LONG_NAME, 
    EXPENDITURES.DESCRIPTION, 
    EXPENDITURES.INVOICE_NO, 
    EXPENDITURES.DN, 
    EXPENDITURES.OTHER_DOC_NO, 
    EXPENDITURES.PRIM_DOC_NO, 
    EXPENDITURES.SECOND_DOC_NO, 
    EXPENDITURES.TR 
    FROM IDS.EXPENDITURES EXPENDITURES 
    WHERE ((EXPENDITURES.BE<>'70212349')) 
    AND (EXPENDITURES.OCA LIKE '%C') 
    AND (EXPENDITURES.STFY='2017') 
    AND (EXPENDITURES.CF<>'C') 
    AND ((EXPENDITURES.MGDT<={ts '2016-07-31 00:00:00'}) AND (EXPENDITURES.MGDT>={ts '2016-07-01 00:00:00'})) 
    ) 
SELECT * FROM nonZeroTransactions 
WHERE TotalTRNSAMT >0 
+0

@Phicksur - чтобы узнать версию Oracle, запустите этот оператор: 'select * from v $ version;'. Версия Oracle находится в линейке Oracle Database. – mathguy