2012-07-22 101 views
0

我有一個表GrowDaysLocation。在該表中,可以有關於DistrictIdRegionId使用Case語句爲SQL Server 2008的where語句賦值NULL值

的兩條記錄,

  • RegionId=1DistrictId = NULL
  • RegionId=1DistrictId = 1

我有一個條件,如果該行不爲RegionId = 1 and DistrictId = 1存在,則得到的行RegionId = 1 and DistrictId = NULL

如何使用單個查詢完成此操作?

以下是我試過的查詢。

在這個查詢中,我在Where子句中使用CASE並使用子查詢來查找行的存在,但是問題是當我從大小寫返回NULL時它不會返回任何行。

============================================== ====

SET ANSI_NULLS OFF 

Select * From GrowDaysLocations 
Where DistrictId = 
(CASE WHEN (Select Count(*) From GrowDaysLocations 
       Where RegionId = '38D95A68-4A92-4D11-9A88-464CF1492880' AND DistrictId = 'F4B67A07-1BF7-42F5-9F19-77329A215D8B' AND 
       GrowDaysProfileId = '79F8BDBF-67D3-44A7-A790-1C10EE8B2AD0') > 0 THEN DistrictId 
      ELSE 
       NULL 
      END 
) 
AND RegionId = '38D95A68-4A92-4D11-9A88-464CF1492880' AND GrowDaysProfileId = '79F8BDBF-67D3-44A7-A790-1C10EE8B2AD0' 

======================================= ====

+0

我不明白,你說'如果該行不存在RegionId = 1和DistrictId = 1',但你的例子意味着該行不存在給定的值'x'和'y' - - 這是真的? – Hogan 2012-07-22 14:25:06

回答

1

RANK功能可以給你你正在尋找的結果:

SELECT RegionId, DistrictId, GrowDaysProfileId 
FROM 
    (SELECT RegionId 
     ,DistrictId 
     ,GrowDaysProfileId 
     ,RANK() OVER(PARTITION BY RegionId, GrowDaysProfileId 
        ORDER BY DistrictId DESC) AS rankVal 
    From GrowDaysLocation) sub 
WHERE rankVal = 1 

該查詢會給你一個行設置爲每個不同的RegionIdGrowDaysProfileId結果。如果組合表中有多個行,則查詢將根據DistrictId的值選擇一個結果。具有最高DistrictId值的行將被首先使用,而具有最低DistrictIdNULL最低)的行最後被使用。

+0

好的解決方案,你不能把OVER語句放在WHERE中,並拿出子查詢嗎? – Hogan 2012-07-22 15:31:27

+0

@Hogan不幸的是「窗口函數只能出現在SELECT或ORDER BY子句中」。 – 2012-07-22 15:50:38

+0

謝謝,凱文。有什麼方法可以使用CASE語句將列設置爲NULL。 - – 2012-07-25 18:45:01

0

這是因爲評估條件

WHERE ColumnName = NULL 

當所有的行會被過濾掉,因爲平等檢查時,如果任何一方是NULL,該行立即濾出,無論條件的( see Data Manipulation Language section)。你必須使用

WHERE ColumnName IS NULL 

在這種情況下,你可以使用

WHERE ISNULL(DistrictID, 'Empty') = ... 

而在case語句使用「空」的字符串,而不是空的。

+0

DistrictID是一個UNIQUEIDENTIFIER,所以我不能使用ISNULL() – 2012-07-25 18:46:06