将每个数据集的 SQL 查询重写为 return 行
Rewrite SQL query to return rows for each dataset
我有以下table学生费用支付
[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
如有任何帮助,我们将不胜感激
使用 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
处理
因此,如果不完全将您的查询重组为更高效的查询,例如 ,您可以 UNION
每个结果,而不是将它们分别用作子查询:
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)
您的代码似乎每年不止一行。似乎最后一行信息量最大,所以我在想这样的事情:
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;
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
我有以下table学生费用支付
[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
如有任何帮助,我们将不胜感激
使用 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
处理
因此,如果不完全将您的查询重组为更高效的查询,例如 UNION
每个结果,而不是将它们分别用作子查询:
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)
您的代码似乎每年不止一行。似乎最后一行信息量最大,所以我在想这样的事情:
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;
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