为什么这些子查询方法之一有效,而另一方法无效?有什么更有效的方法来构造此数据?
我有一个实体表,然后有一个时间序列表,对应于具有不同类型生产数据的那些实体。我正在尝试获取每个生产流的最初日期。
我首先尝试查询A,但3个小时后仍在处理。查询B几乎立即生效。
实体表中有255行,时间序列表中有〜150000行。运行SQL Server2014。
查询A :(无效)
select
main.PROPNUM
,min(sub_fluid.d_date) as [first_fluid]
,min(sub_hc.d_date) as [first_hydrocarbon]
,min(sub_oil.d_date) as [first_oil]
,min(sub_gas.d_date) as [first_gas]
from daily_production as main
left join
(
select
PROPNUM
,D_DATE
,(oil+gas+water) as fluid
from daily_production
where (oil+gas+water) > 0
) as sub_fluid
on main.PROPNUM = sub_fluid.PROPNUM
left join
(
select
PROPNUM
,D_DATE
,(oil+gas) as hydrocarbon
from daily_production
where (oil+gas) > 0
) as sub_hc
on main.PROPNUM = sub_hc.PROPNUM
left join
(
select
PROPNUM
,D_DATE
,oil
from daily_production
where (oil) > 0
) as sub_oil
on main.PROPNUM = sub_oil.PROPNUM
left join
(
select
PROPNUM
,D_DATE
,gas
from daily_production
where (gas) > 0
) as sub_gas
on main.PROPNUM = sub_gas.PROPNUM
group by main.PROPNUM
查询B :(效果很好)
select
daily_production.propnum
,first_fluid.first_fluid
,first_hydrocarbon.first_hydrocarbon
,first_oil.first_oil
,first_gas.first_gas
from daily_production
left join
(select
sub_fluid.PROPNUM
,min(sub_fluid.d_date) as [first_fluid]
from
(
select
PROPNUM
,D_DATE
,(oil+gas+water) as fluid
from daily_production
where (oil+gas+water) > 0
) as sub_fluid
group by PROPNUM) as first_fluid
on daily_production.PROPNUM = first_fluid.PROPNUM
left join
(select
sub_hc.PROPNUM
,min(sub_hc.d_date) as [first_hydrocarbon]
from
(
select
PROPNUM
,D_DATE
,(oil+gas) as hydrocarbon
from daily_production
where (oil+gas) > 0
) as sub_hc
group by PROPNUM) as first_hydrocarbon
on daily_production.PROPNUM = first_hydrocarbon.PROPNUM
left join
(select
sub_oil.PROPNUM
,min(sub_oil.d_date) as [first_oil]
from
(
select
PROPNUM
,D_DATE
,(oil)
from daily_production
where (oil) > 0
) as sub_oil
group by PROPNUM) as first_oil
on daily_production.PROPNUM = first_oil.PROPNUM
left join
(select
sub_gas.PROPNUM
,min(sub_gas.d_date) as [first_gas]
from
(
select
PROPNUM
,D_DATE
,(gas)
from daily_production
where (gas) > 0
) as sub_gas
group by PROPNUM) as first_gas
on daily_production.PROPNUM = first_gas.PROPNUM
group by daily_production.PROPNUM, first_fluid.first_fluid, first_hydrocarbon.first_hydrocarbon, first_oil.first_oil, first_gas.first_gas
答案 0 :(得分:3)
您的第一个查询会导致多对多连接:将表#1中具有PROPNUM n的每一行连接到表#2中具有相同PROPNUM n的每一行,依此类推。
但是当您使用不同的WHERE条件多次连接同一张表时,可以将其替换为条件聚合:
select
PROPNUM
,min(case when (oil+gas+water) > 0 then d_date end) as [first_fluid]
,min(case when (oil+gas) > 0 then d_date end) as [first_hydrocarbon]
,min(case when (oil) > 0 then d_date end) as [first_oil]
,min(case when (gas) > 0 then d_date end) as [first_gas]
from daily_production
group by PROPNUM