SQL 包含 4 个子查询的查询
SQL Query with 4 subqueries
为什么这些子查询方法中的一种有效而另一种无效?构建这些数据的更有效方法是什么?
我有一个实体 table,然后是一个时间序列 table,对应于那些具有不同类型生产数据的实体。我正在尝试获取每个生产流的第一个日期。
我首先尝试了查询 A,3 小时后它仍在运行。查询 B 几乎立即生效。
实体 table 中有 255 行,时间序列 table 中有约 150000 行。 运行 SQL 服务器 2014。
查询 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
您的第一个查询导致多对多连接:您将 table #1 中具有 PROPNUM n 的每一行连接到 table #2 中具有相同 PROPNUM n 的每一行,并且等等。
但是当您使用不同的 WHERE 条件多次加入相同的 table 时,您可以将其替换为 条件聚合:
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
为什么这些子查询方法中的一种有效而另一种无效?构建这些数据的更有效方法是什么?
我有一个实体 table,然后是一个时间序列 table,对应于那些具有不同类型生产数据的实体。我正在尝试获取每个生产流的第一个日期。
我首先尝试了查询 A,3 小时后它仍在运行。查询 B 几乎立即生效。
实体 table 中有 255 行,时间序列 table 中有约 150000 行。 运行 SQL 服务器 2014。
查询 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
您的第一个查询导致多对多连接:您将 table #1 中具有 PROPNUM n 的每一行连接到 table #2 中具有相同 PROPNUM n 的每一行,并且等等。
但是当您使用不同的 WHERE 条件多次加入相同的 table 时,您可以将其替换为 条件聚合:
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