SQL 两个 JOINS 相同 table 不同的值
SQL Two JOINS same table different values
我正在制作多个内部 join:s 以便从数据库中获取数据。
根据我选择使用的关系类型,结果会发生变化。
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasLocation'
和
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasOrganization'
我想要的上述两个 JOIN 的值都在 BMEt.Name。
我曾尝试将第二个名称的名称 BMEt 更改为 BMEt2,将 RT 更改为 RT2,并希望能做到这一点。但后来我没有得到任何数据。 (没有错误只是没有数据)
我也试过这样使用 IN:
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
然后我得到了两个值,但显然在同一列中。是否可以将其分成两列,或者我应该如何检索数据?
完整查询
DECLARE @OSBuild AS VARCHAR(100)='10.0.19042'
SELECT VRS.[ResourceID] AS 'ResourceID'
,VRS.[Name0] AS 'Computername'
,VRS.[Resource_Domain_OR_Workgr0] AS 'Domain'
,BIOS.SerialNumber0 AS 'Serialnumber'
,BMEt.Name AS 'Location'
FROM [SERVER02].[dbo].[v_R_System] as VRS
INNER JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS on vGSOS.[ResourceID] = VRS.[ResourceID]
INNER JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS ON BIOS.[ResourceID] = VRS.[ResourceID]
INNER JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel ON rel.SourceEntityId = HWA.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%' AND
vGSOS.[Version0] = @OSBuild
ORDER BY BIOS.SerialNumber0 ASC
第二次尝试
DECLARE @OSBuild AS VARCHAR(100)='10.0.19042';
with a as (
SELECT
VRS.[ResourceID] AS [ResourceID]
, VRS.[Name0] AS [Computername]
, VRS.[Resource_Domain_OR_Workgr0] AS [Domain]
, BIOS.SerialNumber0 AS [Serialnumber]
, case RT.RelationshipTypeName
when 'Cireson.AssetManagement.HardwareAssetHasOrganization'
then 'Organization'
when 'Cireson.AssetManagement.HardwareAssetHasLocation'
then 'Location'
end as RelTypeName
, BMEt.Name
FROM [SERVER02].[dbo].[v_R_System] as VRS
JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS
ON vGSOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS
ON BIOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA
ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel
ON rel.SourceEntityId = HWA.BaseManagedEntityId
JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%'
AND vGSOS.[Version0] = @OSBuild
)
select *
from a
pivot (
max(Name) for RelTypeName in (
[Location],
[Organization]
)
) as q
ORDER BY [Serialnumber] ASC
给出错误:
Msg 319, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Completion time: 2021-06-24T13:37:17.2405171+02:00
新错误
Msg 207, Level 16, State 1, Line 40
Invalid column name 'Name'.
Completion time: 2021-06-24T13:58:13.3559097+02:00
如果我没理解错的话,你想要两组连接:
INNER JOIN
[SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId INNER JOIN
[SERVER01].[ServiceManager].[dbo].[RelationshipType] RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId AND
RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasOrganization' INNER JOIN
[SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] BMEt2
ON rel2.TargetEntityId = BMEt2.BaseManagedEntityId INNER JOIN
[SERVER01].[ServiceManager].[dbo].[RelationshipType] RT2
ON rel.RelationshipTypeId = RT2.RelationshipTypeId AND
RT2.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasLocation';
请注意:通常这是使用 LEFT JOIN
而不是 INNER JOIN
完成的。没有样本数据、期望的结果和对查询逻辑的清晰解释,这很难说,但我很确定你需要这里的外部连接。
您也可以使用 pivot 将行转换为列,如果一个 RelationshipType
可能只有一个值:
with a as (
SELECT
VRS.[ResourceID] AS [ResourceID]
, VRS.[Name0] AS [Computername]
, VRS.[Resource_Domain_OR_Workgr0] AS [Domain]
, BIOS.SerialNumber0 AS [Serialnumber]
, case RT.RelationshipTypeName
when 'Cireson.AssetManagement.HardwareAssetHasOrganization'
then 'Organization'
when 'Cireson.AssetManagement.HardwareAssetHasLocation'
then 'Location'
end as RelTypeName
, BMEt.Name
FROM [SERVER02].[dbo].[v_R_System] as VRS
JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS
on vGSOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS
ON BIOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA
ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel
ON rel.SourceEntityId = HWA.BaseManagedEntityId
JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%'
AND vGSOS.[Version0] = @OSBuild
)
select *
from a
pivot (
max(Name) for RelTypeName in (
[Location],
[Organization]
)
) as q
ORDER BY [Serialnumber] ASC
db<>fiddle 一些简化的例子 is here
我正在制作多个内部 join:s 以便从数据库中获取数据。 根据我选择使用的关系类型,结果会发生变化。
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasLocation'
和
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasOrganization'
我想要的上述两个 JOIN 的值都在 BMEt.Name。
我曾尝试将第二个名称的名称 BMEt 更改为 BMEt2,将 RT 更改为 RT2,并希望能做到这一点。但后来我没有得到任何数据。 (没有错误只是没有数据)
我也试过这样使用 IN:
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
然后我得到了两个值,但显然在同一列中。是否可以将其分成两列,或者我应该如何检索数据?
完整查询
DECLARE @OSBuild AS VARCHAR(100)='10.0.19042'
SELECT VRS.[ResourceID] AS 'ResourceID'
,VRS.[Name0] AS 'Computername'
,VRS.[Resource_Domain_OR_Workgr0] AS 'Domain'
,BIOS.SerialNumber0 AS 'Serialnumber'
,BMEt.Name AS 'Location'
FROM [SERVER02].[dbo].[v_R_System] as VRS
INNER JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS on vGSOS.[ResourceID] = VRS.[ResourceID]
INNER JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS ON BIOS.[ResourceID] = VRS.[ResourceID]
INNER JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel ON rel.SourceEntityId = HWA.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt ON rel.TargetEntityId = BMEt.BaseManagedEntityId
INNER JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%' AND
vGSOS.[Version0] = @OSBuild
ORDER BY BIOS.SerialNumber0 ASC
第二次尝试
DECLARE @OSBuild AS VARCHAR(100)='10.0.19042';
with a as (
SELECT
VRS.[ResourceID] AS [ResourceID]
, VRS.[Name0] AS [Computername]
, VRS.[Resource_Domain_OR_Workgr0] AS [Domain]
, BIOS.SerialNumber0 AS [Serialnumber]
, case RT.RelationshipTypeName
when 'Cireson.AssetManagement.HardwareAssetHasOrganization'
then 'Organization'
when 'Cireson.AssetManagement.HardwareAssetHasLocation'
then 'Location'
end as RelTypeName
, BMEt.Name
FROM [SERVER02].[dbo].[v_R_System] as VRS
JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS
ON vGSOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS
ON BIOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA
ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel
ON rel.SourceEntityId = HWA.BaseManagedEntityId
JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%'
AND vGSOS.[Version0] = @OSBuild
)
select *
from a
pivot (
max(Name) for RelTypeName in (
[Location],
[Organization]
)
) as q
ORDER BY [Serialnumber] ASC
给出错误:
Msg 319, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Completion time: 2021-06-24T13:37:17.2405171+02:00
新错误
Msg 207, Level 16, State 1, Line 40
Invalid column name 'Name'.
Completion time: 2021-06-24T13:58:13.3559097+02:00
如果我没理解错的话,你想要两组连接:
INNER JOIN
[SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId INNER JOIN
[SERVER01].[ServiceManager].[dbo].[RelationshipType] RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId AND
RT.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasOrganization' INNER JOIN
[SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] BMEt2
ON rel2.TargetEntityId = BMEt2.BaseManagedEntityId INNER JOIN
[SERVER01].[ServiceManager].[dbo].[RelationshipType] RT2
ON rel.RelationshipTypeId = RT2.RelationshipTypeId AND
RT2.RelationshipTypeName = 'Cireson.AssetManagement.HardwareAssetHasLocation';
请注意:通常这是使用 LEFT JOIN
而不是 INNER JOIN
完成的。没有样本数据、期望的结果和对查询逻辑的清晰解释,这很难说,但我很确定你需要这里的外部连接。
您也可以使用 pivot 将行转换为列,如果一个 RelationshipType
可能只有一个值:
with a as (
SELECT
VRS.[ResourceID] AS [ResourceID]
, VRS.[Name0] AS [Computername]
, VRS.[Resource_Domain_OR_Workgr0] AS [Domain]
, BIOS.SerialNumber0 AS [Serialnumber]
, case RT.RelationshipTypeName
when 'Cireson.AssetManagement.HardwareAssetHasOrganization'
then 'Organization'
when 'Cireson.AssetManagement.HardwareAssetHasLocation'
then 'Location'
end as RelTypeName
, BMEt.Name
FROM [SERVER02].[dbo].[v_R_System] as VRS
JOIN [SERVER02].[dbo].[v_GS_OPERATING_SYSTEM] AS vGSOS
on vGSOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER02].[dbo].v_GS_PC_BIOS AS BIOS
ON BIOS.[ResourceID] = VRS.[ResourceID]
JOIN [SERVER01].[ServiceManager].[dbo].[MT_Cireson$AssetManagement$HardwareAsset] AS HWA
ON BIOS.SerialNumber0 = HWA.SerialNumber_C8CF2E89_7A83_1C26_0AD0_887DF9140D5A COLLATE SQL_Latin1_General_CP1_CI_AS
JOIN [SERVER01].[ServiceManager].[dbo].relationship AS rel
ON rel.SourceEntityId = HWA.BaseManagedEntityId
JOIN [SERVER01].[ServiceManager].[dbo].[RelationshipType] AS RT
ON rel.RelationshipTypeId = RT.RelationshipTypeId
AND RT.RelationshipTypeName IN ('Cireson.AssetManagement.HardwareAssetHasOrganization','Cireson.AssetManagement.HardwareAssetHasLocation')
JOIN [SERVER01].[ServiceManager].[dbo].[BaseManagedEntity] AS BMEt
ON rel.TargetEntityId = BMEt.BaseManagedEntityId
WHERE VRS.Operating_System_Name_and0 NOT LIKE '%Server%'
AND vGSOS.[Version0] = @OSBuild
)
select *
from a
pivot (
max(Name) for RelTypeName in (
[Location],
[Organization]
)
) as q
ORDER BY [Serialnumber] ASC
db<>fiddle 一些简化的例子 is here