我必须设计一个优化的MySQL查询,以便根据2个表生成报告。
我有2个表用于服务,另一个用于付款。我接受用户特定的服务标准,并根据我必须报告服务和相应的付款。来自2个不同表格的这些交易将按服务日期和付款日期顺序的相应付款顺序排列。除此之外,我还必须报告任何支付的预付款(在数据库中支付的款项与任何特定服务无关)
目前,我根据给定的标准运行一个查询,根据2个表的UNION选择服务和取消关联的付款。然后,我通过循环为每个与服务相关的付款运行单独的查询。
有什么方法可以通过单个查询得到所有这些交易,而且也是按照预期的顺序。
以下是2个表的相关列。
服务表
id (PK)
account_no
date
service_amount
tran_type
付款表
id
account_no
date
pmt_amount
service_id (FK to service table nulls acceptable)
tran_type
以下是我正在尝试的查询
查询1
select account_no, id, date, service_amount, tran_type
from service where <user specified criteria like date range>
UNION
select account_no, id, date, pmt_amount, tran_type
from payment where service_id is null and
<user specified criteria like date range>
order by date
QUERY2
此查询针对上述查询结果在各个服务上运行(tran_type为服务)
select account_no, id, date, pmt_amount, tran_type
from payment where service_id= <specific id>
order by date
服务表数据
ID Item_Typ Date Amt Acct#
1 SVC 11/12/2015 10 1
2 SVC 11/20/2015 20 1
3 SVC 12/13/2015 40 1
4 SVC 4/1/2016 30 1
付款表格数据
ID Svc_ID Item_Typ Date Amt Acct#
1 1 PMT 11/15/2015 5 1
2 1 PMT 11/15/2015 5 1
3 2 PMT 11/25/2015 40 1
4 3 PMT 12/28/2015 35 1
5 2 PMT 12/30/2015 -15 1
7 NULL PMT 1/1/2016 12 2
8 NULL PMT 3/1/2016 35 3
查询1结果 t
ID Item_Typ Date Amt Acct#
1 SVC 11/12/2015 10 1
2 SVC 11/20/2015 20 1
3 SVC 12/13/2015 40 1
4 SVC 4/1/2016 30 1
7 PMT 1/1/2016 12 2
8 PMT 3/1/2016 35 3
获取所有查询结果相关服务的付款后的最终结果
tranTyp Date Amt Acct#
SVC 11/12/2015 10 1
PMT 11/15/2015 5 1
PMT 11/15/2015 5 1
SVC 11/20/2015 20 1
PMT 11/25/2015 40 1
PMT 12/30/2015 -15 1
SVC 12/13/2015 40 1
PMT 12/28/2015 35 1
答案 0 :(得分:1)
drop table if exists service;
create table service (ID int, Item_Typ varchar(3), `Date` date, Amt int, Acct int);
insert into service values
(1, 'SVC', '2015-11-12', 10 , 1),
(2, 'SVC', '2015-11-20', 20 , 1),
(3, 'SVC', '2015-12-13', 40 , 1),
(4, 'SVC', '2016-01-04', 30 , 1),
(5, 'SVC', '2015-10-04', 50 , 1)
drop table if exists payment;
create table payment(ID INT, Svc_ID INT, Item_Typ VARCHAR(3), `Date` DATE, Amt INT, Acct INT);
INSERT INTO payment values
(1, 1 , 'PMT', '2015-11-15', 5 , 1),
(2, 1 , 'PMT', '2015-11-15', 5 , 1),
(3, 2 , 'PMT', '2015-11-25', 40 , 1),
(4, 3 , 'PMT', '2015-12-28', 35 , 1),
(5, 2 , 'PMT', '2015-12-30', -15 ,1),
(7, NULL , 'PMT', '2016-01-01', 12 , 2),
(8, NULL , 'PMT', '2016-03-01', 35 , 3);
MariaDB [sandbox]> select * from
-> (
-> select 1 as typ,id,Item_typ,`date`, `date` as svc_date,amt,acct from service
-> union all
-> select 2,p.svc_id,p.Item_typ,p.`date`,
-> case when s.id is null then now()
-> else s.`date`
-> end as svc_date,
-> p.amt, p.acct from payment p
-> left join service s on p.svc_id = s.id
-> ) s
->
-> order by s.svc_date,s.acct,s.typ,s.id
-> ;