我有下表用于学生的费用支付
[fee_id] INT
[user_id] INT
[payment] DECIMAL (18, 2)
[date] DATETIME
[fee_remaining] DECIMAL (18, 2)
[year] INT
[payment_method] NVARCHAR (50)
[fee_required] DECIMAL (18, 2)
这是我目前的查询,显示已支付,尚未支付或部分支付年度费用的学生人数
SELECT DISTINCT
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining = 0)
AND (YEAR = @year)) AS Fully_Paid,
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining = fee_required)
AND (YEAR = @year)) AS Unpaid,
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining > 0)
AND (YEAR = @year)
AND (fee_remaining <> fee_required)) AS Partially_Paid
FROM fee_payments AS fee_payments_1
这是我的输出
Fully_Paid | Unpaid | Partially_Paid
-------------------------------------
8 | 1 | 5
是否可以将输出显示如下?
Status | Total
----------------------------
Fully Paid | 8
Unpaid | 1
Partially Paid | 5
非常感谢任何帮助
答案 0 :(得分:3)
使用case
表达式为每行指定所需状态,并为计算列指定group by
。
select status, count(*) as total
from (
SELECT
case when fee_remaining = 0 then 'fully_paid'
when fee_remaining <> fee_required then 'partially_paid'
when fee_remaining = fee_required then 'unpaid'
end as status
FROM fee_payments
WHERE YEAR = @year) t
group by status
另请注意,假设fee_remaining和fee_required为非空值。如果它们可以是null
,请在比较时使用coalesce
来处理它们。
答案 1 :(得分:0)
因此,如果完全将您的查询重组为更高效的内容,例如kvp's answer,您可以UNION
每个结果,而不是将它们作为子查询使用:< / p>
SELECT 'Fully Paid' AS Status, COUNT(*) AS Total
FROM fee_payments
WHERE (fee_remaining = 0) AND (YEAR = @year)
UNION
SELECT 'Unpaid', COUNT(*)
FROM fee_payments
WHERE (fee_remaining = fee_required) AND (YEAR = @year)
UNION
SELECT 'Partially Paid', COUNT(*)
FROM fee_payments
WHERE (fee_remaining > 0) AND (YEAR = @year) AND (fee_remaining <> fee_required)
答案 2 :(得分:0)
您的代码似乎每年有多行。似乎最后一行是最有用的,所以我想这样的事情:
select sum(case when fee_remaining = 0 then 1 else 0 end) as FullyPaid,
sum(case when fee_remaining < fee_required then 1 else 0 end) as PartiallyPaid,
sum(case when fee_remaining = fee_required then 1 else 0 end) as Unpaid
from (select fp.*,
row_number() over (partition by user_id order by date desc) as seqnum
from fee_payments fp
where YEAR = @year
) fp
where seqnum = 1;
答案 3 :(得分:0)
SELECT 'Fully Paid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining = 0
AND YEAR = @year
UNION ALL
SELECT 'Unpaid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining = fee_required
AND YEAR = @year
UNION ALL
SELECT 'Partially Paid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining > 0
AND YEAR = @year
AND fee_remaining <> fee_required