在一个结果集中返回两个关系

时间:2018-08-09 05:44:33

标签: sql sql-server

下面是我的生产模式中过于简化的灵感。

enter image description here

因此,我想在一个结果集中返回所有这些信息。

我想要的结果集 Desired result

我尝试过此查询,但返回错误结果。

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

编辑:这是上述查询的结果。 enter image description here

有人可以建议我,我真的需要返回想要的结果。

3 个答案:

答案 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中找到vehicleidfarmvehicle的组合。这是执行此操作的一种方法:

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;

上个月的演示:http://rextester.com/DNKSU25931