2011-11-03 54 views
2

我有如下表:加入到同一个表中的SQL - SQL Server 2008中

ID Type Description IDOfSystem 
-------------------------------- 
1000 Company Company Item NULL 
1010 System System Item NULL 
1020 Company NULL   1010 

我有系统和公司项目。我需要编写一个选择查询来获取所有公司项目和系统项目,除非公司项目的值为IDOfSystem我需要排除该系统项目并从系统项目获取描述。

因此,鉴于上表,SQL select应该返回行1000,1020(带有“系统项”)作为描述。

如果1020不存在,我只是得到1000和1010

我想我可以打破这种成多个查询,并做了UNION。我试图在同一张表上做左外连接,但无法从系统行获取描述。

任何帮助?

回答

0

该方法使用自连接来查找相应系统的描述。一个单独的子查询会过滤掉被引用的系统。

select yt1.Id 
,  yt1.Type 
,  coalesce(yt2.Description, yt1.Description) as Description 
from YourTable yt1 
left join 
     YourTable yt2 
on  yt1.type = 'Company' 
     and yt2.type = 'System' 
     and yt2.ID = yt1.IDOfSystem 
where yt1.type in ('System', 'Company') 
     and not exists 
     (
     select * 
     from YourTable yt3 
     where yt1.type = 'System' 
       and yt3.type = 'Company' 
       and yt1.ID = yt3.IDOfSystem 
     ) 

Working example at SE Data.

+0

他也想用系统描述(而不是公司)替换引用系统的行描述 –

+0

@Dylan Smith:你说得对,我会编辑答案,谢谢 – Andomar

+0

这不会给我系统项目的描述。这是一个空字符串:( – Nick

1
SELECT 
    Companies.ID 
    ,Companies.Type 
    ,COALESCE(Systems.Description, Companies.Description) as Description 
FROM YourTable Companies 
LEFT OUTER JOIN YourTable Systems on Systems.ID = Companies.IDOfSystem 
WHERE NOT EXISTS 
(
    SELECT * FROM YourTable T3 WHERE T3.IDOfSystem = Companies.ID 
) 

Here它在SEDE上运行。

+0

,因为我没有得到系统的描述这不起作用 – Nick

+0

您可以检查出的这一个工作示例[这里](http://data.stackexchange.com/stackoverflow/q/116529/)。感谢@Andomar为我提供了有关SEDE是多么有用的启发。 – kevev22

1
SELECT ID, Type, Description 
FROM MyTable AS A 
WHERE IDOfSystem IS NULL AND NOT EXISTS (SELECT * 
             FROM MyTable AS B 
             WHERE B.IDOfSystem = A.ID) 
UNION ALL 
SELECT A.ID, A.Type, B.Description 
FROM MyTable AS A INNER JOIN MyTable AS B ON A.IDOfSystem = B.ID 
WHERE IDOfSystem IS NOT NULL 

我在做什么,首先选择的是没有一个参考的系统,而不能用作其他一些行系统中的所有行。

然后我正在做另一个查询的联合,查找所有具有引用系统的行,并加入到系统中以获取它的描述。

+0

如果可能的话,我想尽量避免使用“union”,因为真正的查询非常庞大而且很难复制它。 – Nick

+0

是的,我试图想到一种没有UNION的方法,我不能想出一个简单的方法。如果没有人以非工会的方式跳进去,我可能稍后会写些东西。 –

0

我敢肯定有这样做的更好的方法,但尝试:

SELECT A.Id, A.Type, ISNULL(A.Description,B.Description) Description, A.IDOfsystem 
FROM YourTable A 
LEFT JOIN YourTable B 
ON A.IDOFSystem = B.ID 
WHERE A.ID NOT IN (SELECT IDOfsystem FROM YourTable WHERE IDOfsystem IS NOT NULL)