简单重构SQL查询

3

我有一个带行的表格:

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)

我获取所有状态值不等于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
            )

1和2是唯一的状态吗?还是还有其他状态,MIN/MAX应用程序可能会失败... - DRapp
4个回答

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)

最起码,您有正确的想法:如果您只想要与状态= 2不对应(在任何记录上)的CountryCodes,则需要获取所有具有状态1的内容,然后排除任何已存在的具有与状态2匹配的行。


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

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

我已经更新了我的答案,使用一个避免显式嵌套查询和连接的查询。 - Kim Burgaard
这样做是不行的,因为 T-SQL 要求分组列必须在聚合函数中使用或在 GROUP BY 子句中列出。你是想用 MySQL 吗? - Johan
太好了,团队合作!虽然我没有SQL Server 2005可以测试,但是一点点协作可以走很远 :-) - Kim Burgaard

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接