2013-10-11 184 views
1

我正在使用SQL Server 2005并试图以我似乎无法正常工作的方式构建查询。SQL左加入CASE声明

我有两个表。一个表具有ItemTypes列表,另一个表具有ItemTypes和用户之间的映射列表。

我想有一个查询,将返回这些结果:

ID | ItemType  | Enabled? 
--------------------------------- 
1 | Type1   | false 
2 | Type2   | true 

启用的列是基于是否有其他表中的条目会。我想使用某种情况下,如果LEFT JOIN项存在,然后把TRUE,否则将假。

SELECT systype.ID, systype.TypeDescription, 
'Enable' = CASE hid.ID WHEN NULL THEN 'true' ELSE 'false' END 
FROM [HardwareTestcaseManagement].[dbo].[A7_SystemItemTypes] systype 
LEFT JOIN [dbo].[A7_HiddenNewsFeedTypes] hid 
ON systype.ID = hid.SystemItemTypesID 
AND hid.UserName = @UserName 

但是,这个查询我到目前为止^没有按照我的意图工作。

任何建议如何我可以调整这个查询工作如何我想要它?

编辑:当我做一个左连接,只选择列“hid.ID”它会返回为NULL或实际的ID。我希望能够根据它是否为空来修改这个值。

+0

@Nenad实际上这是一个外表,所以可以非常以及它是NULL的情况。 (这在技术上不是WHERE子句,它是JOIN标准。) –

+0

@AaronBertrand ..我的坏,我不知道如何,但我以为我见过'WHERE'关键字。 –

+3

另请使用'[方括号]'而不是'单引号'作为列别名。后者以多种形式被弃用*和*使您的别名看起来像一个字符串。或者更好的是,不要使用关键字,也不要打扰它逃避 - 这是没有必要的。 'SELECT Enable = 1;'工作得很好,除了由于IntelliSense,SSMS中的“Enable”出现蓝色。 –

回答

2

您不能比较null值像其他值。使用is null运营商在case

'Enable' = CASE WHEN hid.ID IS NULL THEN 'true' ELSE 'false' END 
+0

正是我在找的东西。我刚刚错误地陈述了CASE声明。工作很好。谢谢。 – ImGreg

0
SELECT DISTINCT systype.ID, systype.TypeDescription, 
'Enable' = CASE 
    WHEN hid.UserName = @UserName THEN 'true' 
    ELSE 'false' 
    END 
FROM [HardwareTestcaseManagement].[dbo].[A7_SystemItemTypes] systype 
LEFT JOIN [dbo].[A7_HiddenNewsFeedTypes] hid 
ON systype.ID = hid.SystemItemTypesID 
-- no join on UserName 
+0

如果有很多用户,将删除许多行,因为加入UserName后被删除(这就是为什么不同被添加) – vasja

2

CASE有两种格式。您需要使用Searched Case而不是Simple Case检查null值;

SELECT systype.ID, systype.TypeDescription, 
     CASE WHEN hid.UserName IS NULL THEN 'false' ELSE 'true' END Enabled 
FROM [HardwareTestcaseManagement].[dbo].[A7_SystemItemTypes] systype 
LEFT JOIN [dbo].[A7_HiddenNewsFeedTypes] hid 
     ON systype.ID = hid.SystemItemTypesID 
     AND hid.UserName = @UserName 
+0

http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN – HLGEM

+0

我想,这将永远不会返回false,因为WHERE hid.UserName = @UserName – vasja

+0

为什么要将hid.UserName连接条件更改为过滤器?你刚刚从左连接更改为内连接。 –

3

一种简单而有效的方法是使用EXISTS代替连接:

SELECT systype.ID, systype.TypeDescription, 
     [Enable] = CASE WHEN EXISTS( 
        SELECT 1 FROM A7_HiddenNewsFeedTypes ft 
        WHERE ft.SystemItemTypesID = systype.ID 
        AND ft.UserName = @UserName 
       ) THEN 'true' ELSE 'false' END 
FROM [HardwareTestcaseManagement].[dbo].[A7_SystemItemTypes] systype 
+0

仍然需要一些外部查询的WHERE或否? – vasja

+0

@vasja为什么?原始查询中没有针对A7_SystemItemTypes表的过滤器。 –

+0

好吧,我现在看到了(我错误地猜测了表中没有提供样本的内容) – vasja

1
SELECT systype.ID, systype.TypeDescription, 
CASE WHEN hid.SystemItemTypesID IS NULL THEN 'true' ELSE 'false' END as Enable 
FROM [HardwareTestcaseManagement].[dbo].[A7_SystemItemTypes] systype 
LEFT JOIN [dbo].[A7_HiddenNewsFeedTypes] hid 
ON systype.ID = hid.SystemItemTypesID 
AND hid.UserName = @UserName 
0

又一个这样做的方式,而不使用CASE

'Enable' = isnull(nullif(isnull(hid.id,'false'),hid.id),'true')