我有一张名为"付款"在那里我存储了我的客户的所有付款,我需要做一个选择来计算给定月份的非付款率。
客户可以在该月支付多次付款,但我应该只计算一次:1如果付款已完成,如果付款已付款则为0。
例如:
+----+------------+--------+
| ID | DATEDUE | AMOUNT |
+----+------------+--------+
| 1 | 2016-11-01 | 0 |
| 1 | 2016-11-15 | 20.00 |
| 2 | 2016-11-10 | 0 |
+----+------------+--------+
我期望的结果来自11月的比率:
+----+------------+--------+
| ID | DATEDUE | AMOUNT |
+----+------------+--------+
| 1 | 2016-11-15 | 20.00 |
| 2 | 2016-11-10 | 0 |
+----+------------+--------+
所以费率将是50%。
但如果选择是:
SELECT * FROM payment WHERE DATEDUE BETWEEN '2016-11-01' AND '2016-11-30'
它将返回我3行,速率将是66%,女巫是错误的。想法?
PS:这是真实表的一个更简单的例子。真正的查询有很多列,子选择等。
答案 0 :(得分:1)
试试这个
SELECT
id
, SUM(AMOUNT) AS AMOUNT
FROM
Payment
GROUP BY
id;
如果您想要其他列,这可能会有所帮助。
WITH cte (
SELECT
id
, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY AMOUNT DESC ) AS RowNum
-- other row
)
SELECT *
FROM
cte
WHERE
RowNum = 1;
答案 1 :(得分:1)
听起来您需要按照客户对结果进行分区。
SELECT TOP 1 WITH TIES
ID,
DATEDUE,
AMOUNT
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY AMOUNT DESC)
WHERE DATEDUE BETWEEN '2016-11-01' AND '2016-11-30'
PS:有些人不赞成BETWEEN运营商。为清楚起见,最好避免它:
答案 2 :(得分:0)
要计算费率,您可以使用显式除法:
select 1 - count(distinct case when amount > 0 then id end) / count(*)
from payment
where . . .;
或者,或许更容易理解:
select avg(flag * 1.0)
from (select id, (case when max(amount) > 0 then 0 else 1 end) as flag
from payment
where . . .
group by id
) i