2013-08-22 4 views
2

Я пытаюсь получить сумму (docBal) для каждой компании после настройки docBal. Но когда я запускаю запрос ниже, я вынужден включать doctype и docbal в группу, которую я не хочу. Как я могу изменить этот запрос?Как агрегировать результат выражения?

select 
    DocBal = CASE d.DocType WHEN 'AD' THEN -d.DocBal 
          ELSE d.DocBal END, 
    Sum(DocBal) 
    from Vendor v 
    inner join APDoc d 
    on v.VendId = d.VendId 
    where 
     d.PerPost = 201307 
     and d.DocType in ('VO','AP','AD') 
     and d.OpenDoc = 1 
     and Acct = 210110 
    group by CpnyID 
+0

не вы хотите выставить 'CpnyID'? В противном случае - если вы группируете 'CpnyID' - откуда вы знаете, какой' SUM' принадлежит к 'CpnyID'? Можете ли вы показать некоторые примеры данных (включая все возможные случаи краев) и желаемые результаты, чтобы люди не могли угадать, что на самом деле пытается сделать ваш запрос? –

ответ

1
select sum(DocBal) FROM 
(select 
    DocBal = CASE d.DocType WHEN 'AD' THEN -d.DocBal 
          ELSE d.DocBal END, 
    CpnID 
    from Vendor v 
    inner join APDoc d 
    on v.VendId = d.VendId 
    where 
     d.PerPost = 201307 
     and d.DocType in ('VO','AP','AD') 
     and d.OpenDoc = 1 
     and Acct = 210110) a 
GROUP BY CpnID 
0
select sum(DocBal) from (
     select 
      DocBal = CASE d.DocType WHEN 'AD' THEN -d.DocBal 
            ELSE d.DocBal END, 
      CpnyID 
      from Vendor v 
      inner join APDoc d 
      on v.VendId = d.VendId 
      where 
       d.PerPost = 201307 
       and d.DocType in ('VO','AP','AD') 
       and d.OpenDoc = 1 
       and Acct = 210110 
    ) 
    group by CpnyID 
2

Вы можете использовать суб-выбора, чтобы захватить необходимую информацию.

SELECT S.CpnyID, 
      SUM(S.DocBal) 
    FROM (
      SELECT CpnyID, 
        CASE d.DocType WHEN 'AD' THEN -d.DocBal ELSE d.DocBal END AS DocBal 
      FROM Vendor v 
        INNER JOIN APDoc d ON v.VendId = d.VendId 
      WHERE  d.PerPost = 201307 
      AND d.DocType in ('VO','AP','AD') 
      AND d.OpenDoc = 1 
      AND Acct = 210110 
    ) AS S 
    GROUP BY S.CpnyID 

Это должно предоставить вам требуемые данные без необходимости добавления дополнительных столбцов в функцию агрегации.

2

Вы не говорите, какой продукт SQL (и какую версию) вы используете. Это правда, что производная таблица решение, другие предложили бы работать в любом продукте, но в случае, если вы работаете с SQL Server 2005 или более поздней версии, вы можете также использовать CROSS APPLY, как это:

SELECT 
    CpnyID, -- assuming you would like to know which SUM() belongs to which CpnyID 
    SUM(x.DocBal) 
FROM Vendor AS v 
INNER JOIN APDoc AS d ON v.VendId = d.VendId 
CROSS APPLY ( SELECT DocBal = CASE d.DocType WHEN 'AD' THEN -d.DocBal ELSE d.DocBal END ) AS x 
WHERE d.PerPost = 201307 
    AND d.DocType in ('VO','AP','AD') 
    AND d.OpenDoc = 1 
    AND Acct = 210110 
GROUP BY 
    CpnyID 
;

Там в также гораздо проще, на мой взгляд, решение: вы могли бы сделать все выражение CASE, аргументе SUM, как это:

SELECT 
    CpnyID, 
    SUM(CASE d.DocType WHEN 'AD' THEN -d.DocBal ELSE d.DocBal END) 
FROM Vendor AS v 
INNER JOIN APDoc AS d ON v.VendId = d.VendId 
WHERE d.PerPost = 201307 
    AND d.DocType in ('VO','AP','AD') 
    AND d.OpenDoc = 1 
    AND Acct = 210110 
GROUP BY 
    CpnyID 
;
Смежные вопросы