下面是我的生产模式中过于简化的灵感。
因此,我想在一个结果集中返回所有这些信息。
我尝试过此查询,但返回错误结果。
SELECT u.*
,f.*
,uv.*
,v.*
FROM User u
LEFT JOIN UserFarm uf ON uf.UserID = u.ID
LEFT JOIN Farm f ON f.ID = uf.FarmID
LEFT JOIN FarmVehicle fv ON f.ID = fv.FarmID
LEFT JOIN UserVehicle uv ON u.ID = uv.UserID
LEFT JOIN Vehicle v ON fv.VehicleID = v.ID
WHERE u.ID = 1
有人可以建议我,我真的需要返回想要的结果。
答案 0 :(得分:1)
您可以构建查询以在第一行中返回所需的数据,并在该行中不需要的列中返回null
。然后为第二行创建另一个查询,并使用union all
将数据组合在一起:
declare @UserVehicle table (UserID int, VehicleID int, IsService bit)
declare @User table (ID int, Name varchar(10))
declare @UserFarm table (UserID int, FarmID int)
declare @Farm table (ID int, Name varchar(10))
declare @FarmVehicle table (FarmID int, VehicleID int)
declare @Vehicle table (ID int, [Type] varchar(10), Name varchar(10))
insert into @UserVehicle values (1, 2, 1)
insert into @User values (1, 'Sam')
insert into @UserFarm values (1, 1)
insert into @Farm values (1, 'Flora')
insert into @FarmVehicle values (1, 1)
insert into @Vehicle values (1, 'Larry', 'Scania'), (2, 'Unknown', 'Civic')
select [User.ID] = u.ID
,[User.Name] = u.Name
,[Farm.ID] = f.ID
,[Farm.Name] = f.Name
,[UserVehicle.UserID] = null
,[UserVehicle.VehicleID] = null
,[UserVehicle.IsService] = null
,[Vehicle.ID] = v.ID
,[Vehicle.Name] = v.Name
from @User u
left join @UserFarm uf on u.ID = uf.UserID
left join @Farm f on uf.FarmID = f.ID
left join @FarmVehicle fv on f.ID = fv.VehicleID
left join @Vehicle v on fv.VehicleID = v.ID
union all
select [User.ID] = u.ID
,[User.Name] = u.Name
,[Farm.ID] = null
,[Farm.Name] = null
,[UserVehicle.UserID] = uv.UserID
,[UserVehicle.VehicleID] = uv.VehicleID
,[UserVehicle.IsService] = case when uv.IsService = 0 then 'No' else 'Yes' end
,[Vehicle.ID] = v.ID
,[Vehicle.Name] = v.Name
from @User u
left join @UserFarm uf on u.ID = uf.UserID
left join @UserVehicle uv on u.ID = uv.UserID
left join @Vehicle v on uv.VehicleID = v.ID
此查询返回以下数据集:
User.ID User.Name Farm.ID Farm.Name UserVehicle.UserID UserVehicle.VehicleID UserVehicle.IsService Vehicle.ID Vehicle.Name
----------- ---------- ----------- ---------- ------------------ --------------------- --------------------- ----------- ------------
1 Sam 1 Flora NULL NULL NULL 1 Scania
1 Sam NULL NULL 1 2 Yes 2 Civic
如果您不不想看到未分配车辆或农场的用户,则将所有left join
更改为inner join
。
答案 1 :(得分:0)
尝试以下查询
SELECT U.*,T.* FROM (
SELECT F.FARMID,F.NAME AS NAM
,UV.*
,V.*
FROM VEHICLE V
LEFT JOIN FARMVEHICLE FV ON FV.VEHICLEID = V.ID
LEFT JOIN USERVEHICLE UV ON UV.VEHICLEID = V.ID
LEFT JOIN FARM F ON F.FARMID = FV.FARMID
LEFT JOIN USERFARM UF ON UF.FARMID = F.FARMID)T, USER U
让我知道查询中是否有任何问题。
答案 2 :(得分:0)
您要显示用户的农场和车辆。但是,可以将农场和车辆关联起来,在这种情况下,您希望将它们一起显示而不是分开显示。
示例:User1与Farm1,Farm2和Farm3以及Vehicle1,Vehicle2和Vehicle3相关。而且,Farm1与Vehicle1和Vehicle2有关,Farm2也与Vehicle1有关。
然后您要:
user | farm | vehicle ------+-------+--------- User1 | Farm1 | Vehicle1 User1 | Farm1 | Vehicle2 User1 | Farm2 | Vehicle1 User1 | Farm3 | - User1 | - | Vehicle3
因此,第二和第三列显示了农场与车辆的关系。您可以通过完全外部联接获得这些。联接的ON
子句有点棘手。您希望userid
匹配,并且在桥接表farmid
中找到vehicleid
和farmvehicle
的组合。这是执行此操作的一种方法:
with rel as
(
select coalesce(uf.userid, uv.userid) as userid, uf.farmid, uv.vehicleid
from userfarm uf
full outer join uservehicle uv
on uf.userid = uv.userid
and exists (select * from farmvehicle fv where fv.farmid = uf.farmid
and fv.vehicleid = uv.vehicleid)
)
select u.name as user_name, f.name as farm_name, v.name as vehicle_name
from usr u
left join rel on u.id = rel.userid
left join farm f on f.id = rel.farmid
left join vehicle v on v.id = rel.vehicleid
order by user_name, farm_name, vehicle_name;