这是我的桌子:
账号
ac name
120 Tom
130 Jony
140 Jone
面包促销
ac pcs amount date
120 12 60 2018-01-03
120 10 50 2018-01-04
140 8 40 2018-01-04
130 5 25 2018-01-05
水销售
ac pcs amount date
130 2 30 2018-01-03
130 5 75 2018-01-04
140 3 45 2018-01-04
130 4 60 2018-01-05
120 5 75 2018-01-07
这是我尝试过的查询:
select account.ac,
account.name,
bread_sale.amount as BSAmount,
bread_sale.date as BSDate,
water_sale.amount as WSAmount,
water_sale.date as WSDate
from account left outer join bread_sale on account.ac = bread_sale.ac
left outer join water_sale on water_sale.ac = account.ac
order by account.ac
这是结果:
ac name BSAmount BSdate WSAmount WSdate
120 Tom 30 2018-01-03 75 2018-01-07
120 Tom 75 2018-01-04 75 2018-01-07
130 Jony 45 2018-01-05 30 2018-01-03
130 Jony 60 2018-01-05 75 2018-01-04
130 Jony 75 2018-01-05 60 2018-01-05
140 Jone 75 2018-01-04 45 2018-01-04
但我想获得这样的东西:
ac name BSAmount BSdate WSAmount WSdate
120 Tom 60 2018-01-03 75 2018-01-07
120 Tom 50 2018-01-04 0 2018-01-07
130 Jony 25 2018-01-05 30 2018-01-03
130 Jony 0 2018-01-05 75 2018-01-04
130 Jony 0 2018-01-05 60 2018-01-05
140 Jone 40 2018-01-04 45 2018-01-04
2018-01-07 汤姆没有卖水,但我得到了 75 份。 请有人帮助我
这是可以实现的,但很混乱,而且可能效率不高。面包水和ac上的账号有关系。可以建立跨越面包和水的最大行号数,然后在行号上重新连接。换句话说,面包和水是根据位置连接的(即订单行出现在表中),结果查询很糟糕,并且解析数据的频率比我个人感到满意的频率更高。
所以
select * from
(
select c.ac cac,t.name tname,d.amount bsamount, d.dt ddt,
e.amount wsamount ,e.dt edt
,
case when d.dt is not null and d.dt < e.dt then d.dt
when d.dt is not null and e.dt is null then d.dt
else e.dt
end as sortorder
from
(
select *
from
(
select bs.ac,
if(bs.ac <> @p,@rn:=1,@rn:=@rn+1) rn,
@p:=bs.ac p
from bs
cross join (select @rn:=0,@p:=0) r
order by bs.ac,bs.dt
) a
union
(
select ac2,rn1,p1
from
(
select ws.ac ac2,
if(ws.ac <> @p1,@rn1:=1,@rn1:=@rn1+1) rn1,
@p1:=ws.ac p1
from ws
cross join (select @rn1:=0,@p1:=0) r
order by ws.ac,ws.dt
) b
)
) c
left join
(
select bs.ac,pcs,amount,dt,
if(bs.ac <> @p3,@rn3:=1,@rn3:=@rn3+1) rn3,
@p3:=bs.ac p
from bs
cross join (select @rn3:=0,@p3:=0) r
order by bs.ac,bs.dt
) d
on d.ac = c.ac and d.rn3 = c.rn
left join
(
select ws.ac,pcs,amount,dt,
if(ws.ac <> @p4,@rn4:=1,@rn4:=@rn4+1) rn4,
@p4:=ws.ac p
from ws
cross join (select @rn4:=0,@p4:=0) r
order by ws.ac,ws.dt
) e
on e.ac = c.ac and e.rn4 = c.rn
join t on t.ac = c.ac
) f
order by cac , sortorder;
+------+-------+----------+------------+----------+------------+------------+
| cac | tname | bsamount | ddt | wsamount | edt | sortorder |
+------+-------+----------+------------+----------+------------+------------+
| 120 | Tom | 60 | 2018-01-03 | 75 | 2018-01-07 | 2018-01-03 |
| 120 | Tom | 50 | 2018-01-04 | NULL | NULL | 2018-01-04 |
| 130 | Jony | 25 | 2018-01-05 | 30 | 2018-01-03 | 2018-01-03 |
| 130 | Jony | NULL | NULL | 75 | 2018-01-04 | 2018-01-04 |
| 130 | Jony | NULL | NULL | 60 | 2018-01-05 | 2018-01-05 |
| 140 | Jone | 40 | 2018-01-04 | 45 | 2018-01-04 | 2018-01-04 |
+------+-------+----------+------------+----------+------------+------------+
6 rows in set (0.00 sec)
select account.ac,
account.name,
bread_sale.amount as BSAmount,
bread_sale.date as BSDate,
water_sale.amount as WSAmount,
water_sale.date as WSDate
from account left outer join bread_sale on account.ac = bread_sale.ac
left outer join water_sale on water_sale.ac = bread_sale.ac
order by account.ac
此查询将产生此结果。您的零将被正确的值替换。我希望您可能需要这个结果。
ac name BSAmount BSdate WSAmount WSdate
120 Tom 60 2018-01-03 75 2018-01-07
120 Tom 50 2018-01-04 75 2018-01-07
130 Jony 25 2018-01-05 30 2018-01-03
130 Jony 25 2018-01-05 75 2018-01-04
130 Jony 25 2018-01-05 60 2018-01-05
140 Jone 40 2018-01-04 45 2018-01-04