2011-06-08 170 views
3

我有行的表:簡單的重構SQL查詢

ID   CountryCode Status 
----------- ----------- ----------- 
2   PL   1 
3   PL   2 
4   EN   1 
5   EN   1 

,並通過查詢

SELECT * 
    FROM [TestTable] 
    WHERE Status = 1 AND CountryCode NOT IN (SELECT CountryCode 
    FROM [TestTable] 
    WHERE Status != 1) 

我得到它有沒有狀態值都countrycodes = 2

ID   CountryCode Status 
----------- ----------- ----------- 
4   EN   1 
5   EN   1 

我覺得這個查詢可以更簡單,更清晰。

我怎樣才能改變呢?

問候

編輯

PL不能在結果,因爲有狀態的記錄2

編輯

腳本來創建和填充表:

USE [DatabaseName] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[TestTable](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [CountryCode] [nvarchar](2) NOT NULL, 
    [Status] [int] NOT NULL 
) ON [PRIMARY] 

INSERT INTO dbo.TestTable 
      (CountryCode, Status) 
    VALUES ('PL', -- CountryCode - nvarchar(2) 
      1 -- Status - int 
      ) 

INSERT INTO dbo.TestTable 
      (CountryCode, Status) 
    VALUES ('PL', -- CountryCode - nvarchar(2) 
      2 -- Status - int 
      ) 

INSERT INTO dbo.TestTable 
      (CountryCode, Status) 
    VALUES ('EN', -- CountryCode - nvarchar(2) 
      1 -- Status - int 
      ) 
INSERT INTO dbo.TestTable 
      (CountryCode, Status) 
    VALUES ('EN', -- CountryCode - nvarchar(2) 
      1 -- Status - int 
      ) 
+0

爲1和2的唯一狀態......或者還有沒有其他太多最小/最大應用程序,否則可能會失敗...... – DRapp 2011-06-08 18:29:52

+0

@DRapp 5是一個範圍 – user278618 2011-06-08 18:32:51

回答

7

第一:永遠不要在經常使用的代碼中使用SELECT *。特別是在生產中。叫出你的專欄。

香皂盒。

注:我沒有嘗試過這一點,我現在還沒有安裝管理工作室,所以我不能測試它。但我想你想是這樣的:

Select Id, CountryCode, Status 
From [TestTable] t 
Where Status <> 2 
And Not Exists(select status from [TestTable] t2 
          where t2.Status = 2 
          and t2.CountryCode = tt.CountryCode) 

至少,你有正確的觀念:如果你只是想這不會(對任何記錄)CountryCodes對應狀態= 2,您需要獲取狀態爲1的所有內容,然後排除具有狀態2的匹配行的任何現有行。不過,我可能具有不存在不正確的特定語法。

+0

這甚至可以在他的狀態代碼範圍1-5 – DRapp 2011-06-08 19:19:59

0
SELECT distinct(country) FROM table WHERE value <> 2 
1

如果你想去的地方Status沒有價值2中的所有條目,試試這個:

SELECT * 
    FROM [TestTable] 
WHERE Status != 2 

編輯:爲了防止發生任何明顯的條目具有不需要的值的國家代碼,請嘗試GROUP BYHAVING子句:

SELECT CountryCode 
    FROM [TestTable] 
GROUP BY CountryCode 
HAVING MAX(Status) = 1 AND MIN(Status) = 1 
+0

-1這是不正確,請參閱示例結果在問題中。 – Johan 2011-06-08 18:18:55

+0

我已經使用避免顯式嵌套查詢和連接的查詢更新了我的答案 – 2011-06-08 18:28:20

+0

這不起作用,因爲T-SQL需要按列分組以便在聚合函數中使用或在group by子句中列出。你在想MySQL嗎? – Johan 2011-06-08 18:29:21

3
select T1.* 
from TestTable as T1 
    left outer join 
    (
     select distinct CountryCode 
     from TestTable as T1 
     where Status <> 1 
    ) as T2 
    on T1.CountryCode = T2.CountryCode 
where 
    T1.Status = 1 and 
    T2.CountryCode is null