我有一个公用事业账单表如下:
table: table_bill
-----------------------------------------------------------------------------
id | bill_type | month | year | lastdate | amount | latedate1 | lateamount1 | latedate2 | lateamount2|
------------------------------------------------------------------------------
1 | Electricity | Jan | 2015 | 2015-02-01 | 500 | 2015-03-01 | 550 | 2015-04-01 | 600
------------------------------------------------------------------------------
2 | Water | Jan | 2015 | 2015-03-01 | 200 | 2015-04-01 | 250 | 2015-05-01 | 300
-------------------------------------------------------------------------------
3 | Gas | Jan | 2015 | 2015-02-01 | 800 | 0000-00-00 | NULL | 0000-00-00 | NULL
--------------------------------------------------------------------------------
表描述:
电费和水费账单适用于逾期付款,因此这些栏目中填写了数据,另一方面,燃气账单没有罚款延迟付款。因此,Gas bill的数据是日期的EA或金额的Null。
现在,当我想在2015-03-01查看未付账单时,我希望未付账单如下表所示:
table: html table
--------------------------------------------------------------
Bill Type | Month | Year | Next Payment Date | Payable Amount
--------------------------------------------------------------
Electricity | Jan | 2015 | 2015-03-01 | 550
--------------------------------------------------------------
Water | Jan | 2015 | 2015-03-01 | 200
--------------------------------------------------------------
Gas | Jan | 2015 | 2015-02-01 | 800
--------------------------------------------------------------
说明:由于电费账单适用于延迟付款且我在2015-03-01查看账单,因此下一个付款日期为2015-03-01,应付金额为550,滞纳金。另一方面,水费账单也适用于延迟付款,但由于没有滞纳金的最后日期是2015-03-01,所以下一个付款日期是2015-03-01,金额是200.因为天然气账单没有延迟费用,所以下次付款日期是2015-02-01,虽然我在2015-03-01查看账单,应付金额为800.
问题:如何进行SELECT查询以从数据库表中提取数据以输出上述未付费的账单表?
我想使用CASE语句但不熟悉CASE STATEMENT。我尝试过以下查询:
$today = gmdate('Y-m-d', time()+21600);
SELECT bill_type, month, year,
CASE bill_type WHEN Electricity AND $today<=lastdate THEN lastdate
WHEN Electricity AND $today<=lastdate1 THEN latedate1
WHEN Electricity AND $today<=lastdate2 THEN lastdate2
WHEN Electricity AND $today<=lastdate3 THEN lastdate3
WHEN Water AND $today<=lastdate1 THEN latedate1
WHEN Water AND $today<=lastdate2 THEN lastdate2
WHEN Water AND $today<=lastdate3 THEN lastdate3
ELSE lastdate END) as ldate,
CASE bill_type WHEN Electricity AND $today<=lastdate THEN amount
WHEN Electricity AND $today<=lastdate1 THEN lateamount1
WHEN Electricity AND $today<=lastdate2 THEN lateamount2
WHEN Electricity AND $today<=lastdate3 THEN lateamount3
WHEN Water AND $today<=lastdate1 THEN lateamount1
WHEN Water AND $today<=lastdate2 THEN lateamount2
WHEN Water AND $today<=lastdate3 THEN lateamount3
ELSE amount END) as amount FROM table_bill
但上面的查询不起作用,如果有更多的bill_type,如卫生,互联网,虚拟主机等等,它也太大了。对于每个bill_type,我必须制作两个CASE语句,并且在每个CASE语句中我必须使用什么时候.....很多次。
如何使查询尽可能简单易用?
答案 0 :(得分:0)
我认为这里需要进行一些规范化。您的问题是由账单表格中的冗余引起的,您应该将账单表中的延迟付款费用分开 - 达到具体的支付水平的附加费用不包括账单金额*。这样你就可以:
SELECT
bill.type,
bill.month,
bill.year,
(bill.amount + SUM(IFNULL(latecharge.amount, 0))) AS amount
FROM bill
LEFT JOIN latecharge
ON latecharge.bill_type = bill.type // might be assigned to concrete bill (id)
AND latecharge.afterdate <= DATE(NOW()) //or some :date parameter
WHERE ...
GROUP BY bill.id
*)基于电力示例的新latecharge
表的一部分:
id|..bill_type|.afterdate|amount
.1|Electricity|2015-03-01|....50 // additional 50 to Electricity bill's amount after 2015-03-01
.2|Electricity|2015-04-01|....50 // and another 50 after 2015-04-01