2011-06-08 171 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