在sql server 08中使用GROUP BY子句返回两行

时间:2011-04-08 11:21:50

标签: sql sql-server sql-server-2008

我有一张桌子:

acc_name        dr_amt     cr_amt

Cash in hand    10000     0
Share Capital   00      1000
Cash in hand    2000      0
Share Capital   0        2000.00
Vehicles        5000      0
Cash in hand    0         5000

使用以下查询

SELECT    a.acc_name, sum(j.dr_amt) AS dr_sum, sum(j.cr_amt) AS cr_sum
FROM      journal_voucher_details_mcg AS j 
INNER JOIN  acc_head_mcg AS a ON a.acc_code = j.acc_code 
INNER JOIN  journal_voucher_mcg AS jv ON jv.jv_no = j.jv_no
WHERE       jv.jv_date = '2011-04-08'
GROUP BY    a.acc_name    

我能够得到以下结果:

acc_name        dr_sum  cr_sum  

Cash in hand    3000    5000
Share Capital   0      3000
Vehicles        5000    0   

但是我想要现金的两个条目(以及任何dr_sum和cr_sum都大于0的条目),结果应该如下:

acc_name        dr_sum  cr_sum  

Cash in hand    3000    0
Cash in hand    0       5000
Share Capital   0      3000
Vehicles        5000    0

我还需要dr_sum和cr_sum的总和,在这种情况下,两者都应该是8000 ....我的最终查询是

SELECT *, SUM(dr_sum), SUM(cr_sum)
FROM (SELECT a.acc_name, sum(j.dr_amt) AS dr_sum, sum(j.cr_amt) AS cr_sum 
FROM        journal_voucher_details_mcg AS j 
INNER JOIN  acc_head_mcg AS a ON a.acc_code = j.acc_code 
INNER JOIN  journal_voucher_mcg AS jv ON jv.jv_no = j.jv_no
WHERE       jv.jv_date = '2011-04-08'
GROUP BY    j.acc_code)

但是这个人没有工作......真的很感激你们的努力!

修改

最终结果集:

acc_name        dr_sum  cr_sum  

Cash in hand    3000    0
Cash in hand    0       5000
Share Capital   0      3000
Vehicles        5000    0
Total           8000    8000

我无法在最后一个元组的第一个字段中显示“Total”(单词Total)。

4 个答案:

答案 0 :(得分:2)

您拥有的当前SQL很好,您不应该更改它。 如果您需要拆分并将两个条目分开,则可以执行以下操作:

WITH W_RESULT AS (
   -- your current query goes here....
)
SELECT acc_name, dr_sum, 0 AS cr_sum
FROM W_RESULT
WHERE dr_sum <> 0
UNION
SELECT acc_name, 0 AS dr_sum, cr_sum
FROM W_RESULT
WHERE cr_sum <> 0

遵循更新的解决方案,包括讨论表单评论

WITH W_RESULT AS (
   -- your current query goes here....
)
SELECT acc_name, dr_sum, 0 AS cr_sum
FROM W_RESULT
WHERE dr_sum <> 0
UNION
SELECT acc_name, 0 AS dr_sum, cr_sum
FROM W_RESULT
WHERE cr_sum <> 0
UNION ALL
SELECT 'Total' AS acc_name, SUM(dr_sum), SUM(cr_sum)
FROM W_RESULT


以前的讨论......

表示您可以添加到查询sum(j.dr_amt + j.cr_amt) AS t_sum中的总和,如果您还需要将此结果作为结果集中的单独条目,则可以使用WITH-clause和UNION扩展上述解决方案,并附加一列和一个额外的UNION部分。或者甚至更简单:

WITH W_RESULT AS (
   -- your current query goes here....
)
SELECT acc_name, dr_sum, 0 AS cr_sum, 0 AS t_sum
FROM W_RESULT
WHERE dr_sum <> 0
UNION
SELECT acc_name, 0 AS dr_sum, cr_sum, 0 AS t_sum
FROM W_RESULT
WHERE cr_sum <> 0
UNION
SELECT acc_name, 0 AS dr_sum, 0 AS cr_sum, dr_sum + cr_sum AS t_sum
FROM W_RESULT

重要

我所指的问题中的当前查询是第一个。
问题末尾的“最终查询”有点奇怪。

它有点像

  • “现金3000”+“车辆5000”的总和= 8000作为dr_sum
  • “现金5000”+“股本3000”的总和= 8000作为cr_sum

我假设请求的total_sum类似于

  • “现金3000”+“现金5000”的总和= t_sum
  • 的8000
  • “股本3000”的总和= 3000作为t_sum
  • “车辆5000”的总和= 5000作为t_sum

请添加评论女巫和是正确的。

答案 1 :(得分:1)

看到明确的要求后,

已编辑

WITH groups AS (
  SELECT
    a.acc_name,
    dr_sum = sum(j.dr_amt),
    cr_sum = sum(j.cr_amt)
  FROM journal_voucher_details_mcg AS j
    INNER JOIN acc_head_mcg AS a ON a.acc_code = j.acc_code 
    INNER JOIN journal_voucher_mcg AS jv ON jv.jv_no = j.jv_no
  WHERE jv.jv_date = '2011-04-08'
  GROUP BY j.acc_code, CASE WHEN dr_amt > 0 THEN 1 ELSE 2 END
)

SELECT
  acc_name,
  dr_sum,
  cr_sum
FROM groups

UNION ALL

SELECT
  'Total',
  SUM(dr_sum),
  SUM(cr_sum)
FROM groups

答案 2 :(得分:1)

;with cte as
(
  select
    a.acc_name,
    case n.n when 1 then sum(j.dr_amt) else 0 end as dr_sum,
    case n.n when 2 then sum(j.cr_amt) else 0 end as cr_sum
  from journal_voucher_details_mcg as j 
    inner join  acc_head_mcg as a
      on a.acc_code = j.acc_code 
    inner join journal_voucher_mcg as jv
      on jv.jv_no = j.jv_no
    cross join (select 1 union all select 2) as n(n)
  where jv.jv_date = '2011-04-08'
  group by a.acc_name, n.n   
)
select
  acc_name,
  dr_sum,
  cr_sum
from cte
where not (dr_sum = 0 and cr_sum = 0)
union all
select 
  'Total',
  sum(dr_sum),
  sum(cr_sum)
from cte

答案 3 :(得分:0)

在SQL Server 2008(2008年的新功能)中,您可以向WITH ROLLUP添加GROUP BY

SELECT 
        a.acc_name, sum(j.dr_amt) AS dr_sum, sum(j.cr_amt) AS cr_sum 
FROM        
        journal_voucher_details_mcg AS j 
INNER JOIN  
        acc_head_mcg AS a ON a.acc_code = j.acc_code 
INNER JOIN  
        journal_voucher_mcg AS jv ON jv.jv_no = j.jv_no
WHERE       
        jv.jv_date = '2011-04-08'
GROUP BY    
        j.acc_code WITH ROLLUP

在这种情况下,您将获得额外的行,其中acc_code为NULL - 这是您的所有帐户总计的行。

所以你的新输出应该是这样的:

acc_name        dr_sum  cr_sum  

Cash in hand    3000      0
Cash in hand    0         5000
Share Capital   0         3000
Vehicles        5000      0
NULL            8000      8000   <-- that's the line with the totals