我有三张桌子:
1:Station_Details(主数据表)
2:RF_Details
3:WL_Details
如下图所示。 我需要一个从所有三个表中的数据到输出表 来自Station_details的主数据和来自RF和WL表的其他数据。 如果RF_Details和WL_Details表具有相同的站ID且具有相同的DateTime,则在输出表中,两行详细信息将显示在一行中。 如果DateTime不同,那么它将出现在不同的行中。
我尝试过这个sql查询,但是我没有像OUTPUT Table那样获得相同的输出。
select rf.StationID, st.stationname, st.state,rf.rf,rf.cum-rf,wl.wl,DataTime
from [RF_Details] rf
join [WL_Details] wl
join Station_Details st
on rf.StationID = wl.StationId and
rf.DataRecieved=wl.DataRecieved and
st.stationid =rf.stationid and
st.stationid = wl.stationid;
但它没有给出正确的行数和输出。 请帮助我。
答案 0 :(得分:2)
您应始终将连接条件与连接本身一起放置。此外,添加INNER
是我遵循的做法,以确保不会返回额外的记录。
SELECT rf.StationID, st.stationname, st.state, wl.DataRecieved, wl.waterlevel1,
rf.dailyrainfall, rf.cumrainfall
FROM [RF_Details] rf
INNER JOIN [WL_Details] wl
ON rf.StationID = wl.StationId AND
rf.DataRecieved=wl.DataRecieved
INNER JOIN Station_Details st
ON st.stationid =rf.stationid AND
st.stationid = wl.stationid;
答案 1 :(得分:1)
declare @station_details table(id int, station_id varchar(10),station_name varchar(10),state varchar(10))
declare @rf_details table (id int, station_id varchar(10),rf int, cum_rf int, dt dateTIME)
declare @wl_details table (id int, station_id varchar(10),wl int,dt datetime)
insert into @station_details values
(1,'DEL-NDL','NDL','DEL'),
(2,'UP-LKO','LKO','UP'),
(3,'MP-BHP','BHP','MP'),
(4,'MHR-MUM','MUM','MHR')
INSERT INTO @RF_DETAILS VALUES
(1,'DEL-NDL',42,435,'2016-06-13 05:15:00'),
(2,'UP-LKO',0,501,'2016-06-13 05:15:00'),
(3,'MP-BHP',20,350,'2016-06-13 05:15:00'),
(4,'MHR-MUM',30,200,'2016-06-13 05:15:00'),
(5,'MHR-MUM',15,100,'2016-06-14 05:15:00'),
(6,'UP-LKO',50,350,'2016-06-13 05:15:00')
INSERT INTO @WL_DETAILS VALUES
(1,'DEL-NDL',25,'2016-06-13 05:15:00'),
(2,'UP-LKO',35,'2016-06-13 05:30:00'),
(3,'MP-BHP',46,'2016-06-13 05:45:00'),
(4,'MHR-MUM',20,'2016-06-13 05:15:00'),
(5,'MHR-MUM',15,'2016-06-14 05:15:00'),
(6,'UP-LKO',60,'2016-06-13 05:15:00')
;with cte as
(
SELECT case
when rf.dt = wl.dt then 'Y'
else 'N'
end as matched,
rf.id as id,rf.station_id as stationid,rf.rf as rf , rf.cum_rf as cumrf , rf.dt as rfdt,
wl.id as wlid, wl.station_id ,wl.wl ,wl.dt as wldte,
rf.station_id as station,rf.dt as rfdte
FROM @RF_DETAILS RF
JOIN @WL_DETAILS WL ON rf.id = wl.id and RF.STATION_ID = WL.STATION_ID
)
select row_number() over (order by s.id) newid,
s.id,s.station_id,sd.station_name,sd.state,s.rf,s.cumrf,s.wl,
case
when s.srce = 'L' then s.rfdte
else s.wldte
end as 'Date'
from
(
select 'L' as srce,cte.id,cte.station_id,cte.rf,cte.cumrf, cte.wl as wl, cte.rfdte,cte.wldte from cte where cte.matched = 'Y'
union
select 'L' as srce,cte.id,cte.station_id,cte.rf,cte.cumrf, null as wl, cte.rfdte,cte.wldte from cte where cte.matched = 'N'
union all
select 'R' as srce,cte.id * 10,cte.station_id,null,null, cte.wl as wl, cte.rfdte,cte.wldte from cte where cte.matched = 'N'
) s
join @station_details sd on sd.station_id = s.station_id
order by s.id
答案 2 :(得分:0)
您应该重新设计数据库:现在您在RF_Details和WL_Details - DateTime中有一个辅助密钥。它们在它们之间起着外键的作用。哪个不好,每次你需要加入这些表或收集相应的数据时都会让你感到困惑。
应该有另一个像Station_Records
这样的表,它会为该站的每条记录存储一行:(id, station_id, record_date_time)
。 RF
和WL
行(如果有的话)应引用此表格,而不是Station_Details
与station_id
相互引用,而datetime
引用{。}}。
使用当前结构,您需要完全加入RF
和WL
以获得两者:按日期时间匹配 - 在同一行中,不匹配 - 在单独的行中。
select sd.station_name, Station_Records.*
from Station_Details sd
inner join
(
select
IsNull(rf.station_id, wl.station_id) station_id,
IsNull(rf.DataRecieved, wl.DataRecieved) DataRecieved,
rf.rf, rf.cum-rf, wl.wl
from [RF_Details] rf
full join [WL_Details] wl
on wl.station_id = rf.station_id
and wl.DataRecieved = rf.DataRecieved
) Station_Records
on Station_Records.station_ud = sd.station_id
具体实现可能包含OUTER APPLY
,甚至没有任何子查询 - 目前并不重要。
修改表格结构,您将始终知道所有匹配的记录:
select
sd.station_id, sd.station_name,
sr.DataRecieved
rf.rf, rf.cum-rf,
wl.wl
from Station_Details sd
inner join Station_Records sr
on sr.station_id = sd.station_id
left join RF_Details rf
on rf.record_id = sr.record_id
left join WL_Details wl
on wl.record_id = sr.record_id