在sql server

时间:2015-08-23 02:47:03

标签: sql sql-server database vb.net

我将此表格命名为expenses,其中包含以下字段refnum, transdate, transtype, transcategory, amount

此表包含以下数据

refnum | transdate  | transtype | transcategory |     amount 
 1     | 10/10/2015 |  cash-out |     null      |    5000.00 
 1     | 10/10/2015 |  cash-in  |     null      |    3000.00 
 1     | 10/10/2015 |  cash-in  |     null      |    1000.00 
 2     | 10/10/2015 |  cash-out |     null      |    5000.00 
 2     | 10/10/2015 |  cash-in  |     null      |    3000.00 
 2     | 10/10/2015 |  cash-in  |     null      |    2000.00
 3     | 10/10/2015 |  cash-out |     null      |    5000.00
 3     | 10/10/2015 |  cash-in  |     null      |    5000.00

问题是:是否有可能根据transtype and refnum

获得金额余额

我有这个问题:

SELECT 
    A.refnum, A.transtype, A.amount,(A.amount-B.amount) as balance 
FROM 
    expenses AS A 
INNER JOIN
    expenses AS B ON A.refnum = B.refnum 
WHERE
    A.transtype = 'cash-in' 
    AND B.transtype = 'cash-out' 
    AND (A.amount - B.amount) > 0

我很困惑,如果cash-incash-out的数量完全相同,我认为此查询很好,但问题几乎所有cash-incash-out的数量不同{ {1}},希望你们明白我的要求。

我需要的查询只会显示refnum的{​​{1}}。

有可能吗?

1 个答案:

答案 0 :(得分:1)

就像尼克说:

使用conditional with aggregated methods

另一个example

SQL Fiddle Demo

  • group by会将您的数据分成不同的组,在这种情况下,每个引用句柄的组(1,2,3)GROUP BY
  • conditional SUM:正常的SUM(amount)会为您提供上面定义的整个群组的总和。但并非所有金额都是积极的。因此,您使用CASE语句将amount更改为-amount WHEN transtype='cash-out'

SELECT 
    refnum, 
    SUM(CASE 
            WHEN transtype='cash-out' then -amount 
            ELSE amount 
        END)  as total
FROM expenses 
GROUP BY refnum

修改

供您参考,这是一种使用CTE和Join

的方法
  • CTE或Common Table Expressions:允许您创建子查询,以便在其他查询中使用它。就像创建一个时态表一样,你可以选择或加入该结果。
  • 在这种情况下,我创建了两个表cash_outcash_in,每个表都包含每个引用句柄的总和值。
  • 在我写完之后,我意识到如果一个refnum没有cash_incash_out这不会起作用。所以我添加了另一个子查询以包含所有refnum,并以这种方式执行left join,如果不是数据,则连接仍将起作用并添加0。
  • ISNULL(variable,0):如果variable则返回variable <> null,否则返回0

SQL Fiddle Demo

WITH ref as (
    SELECT DISTINCT refnum
    FROM expenses
),
cash_out as (    
    SELECT A.refnum, SUM(A.amount) balance 
    FROM 
        expenses AS A 
        where A.transtype = 'cash-out'
    GROUP BY A.refnum
),
cash_in as (
    SELECT A.refnum, SUM(A.amount) balance 
    FROM 
        expenses AS A 
        where A.transtype = 'cash-in' 
    GROUP BY A.refnum
)
SELECT cin.refnum, (ISNULL(cin.balance,0) - ISNULL(cout.balance,0)) as total
FROM 
   ref r LEFT JOIN
   cash_in cin on r.refnum = cin.refnum LEFT JOIN
   cash_out cout on r.refnum = cout.refnum