SQL Server IN运算符与查询和IN运算符与值之间的区别

时间:2017-02-27 06:11:54

标签: sql-server

我正在写一个查询,它给了我奇怪的结果或者我做错了什么。我在 where 子句中使用 IN 运算符。我从应用程序恢复 country_id (可空), province_id (可空)和city_id(可空)。如果 city_id 不为null,则我提取 city_id 中存在的所有 centre_id 并存储在临时表中。如果 city_id 为null且省数_id不为空,则我提取 province_id 中存在的所有 centre_id ,如果 city_id,则相同 province_id 都为null然后我提取 country_id 中存在的 centre_id ,如果所有3都为null,那么我提取所有 centre_id 并存储在临时表中,如下所示:

DECLARE @serviceCenter TABLE (service_center_id INT)

    IF (@city_id IS NOT NULL)
    BEGIN
        INSERT INTO @serviceCenter
        SELECT service_centre_id
        FROM ServiceCentre
        WHERE city_id= @city_id
    END
    ELSE IF (@province_id IS NOT NULL)
    BEGIN
        INSERT INTO @serviceCenter
        SELECT service_centre_id
        FROM ServiceCentre
        INNER JOIN City ON City .city_id= ServiceCentre.city_id
        INNER JOIN Province ON Province.province_id= City.province_id
        WHERE Province.province_id= @province_id 
    END
    ELSE IF (@country_id IS NOT NULL)
    BEGIN
        INSERT INTO @serviceCenter
        SELECT service_centre_id
        FROM ServiceCentre
        INNER JOIN City ON City .city_id= ServiceCentre.city_id
        INNER JOIN Province ON Province.province_id= City.province_id
        INNER JOIN Country ON Country.country_id= City.country_id
        WHERE Country.country_id = @country_id
    END
    ELSE
    BEGIN
        INSERT INTO @serviceCenter
        SELECT service_centre_id
        FROM ServiceCentre
    END

现在,在服务中心的基础上,我需要获得如下的交易计数。

**Select Count(1)
From Tranactions
where service_centre_id IN (Select service_centre_id From @serviceCenter)**

现在问题是这个查询给出了所有center_id的所有事务。我检查了一下。如果临时表中只有一个id且值为1,则它为我提供所有事务。当我使用硬代码值在查询下运行时,它会给出正确的结果

**Select Count(1)
    From Tranactions
    where service_centre_id IN (1)**

其中service_centre_id IN(从@serviceCenter选择service_centre_id) where service_centre_id IN(1)之间有什么不同。 有什么问题?

3 个答案:

答案 0 :(得分:0)

问题是这个查询获取所有service_center_id:

@serviceCenter必须是表名。

  

其中center_id IN(从@serviceCenter选择service_centre_id)

另一个只是select只包含1个service_center_id

  

其中center_id IN(1)

答案 1 :(得分:0)

首先,您可以使用COALESCE()严格简化此查询,如下所示:

INSERT INTO @serviceCenter
SELECT COALESCE(City.service_centre_id,Provice.service_centre_id,Country.service_centre_id,ServiceCentre.service_centre_id)
FROM ServiceCentre
LEFT JOIN City 
    ON City.city_id = ServiceCentre.city_id
    AND City.City_ID = @city_id
LEFT JOIN Province 
    ON Province.province_id = City.province_id
    AND Province.province_id = @province_id 
LEFT JOIN Country 
    ON Country.country_id = City.country_id
    AND Country.country_id = @country_id
;

这里的每个JOIN都使用正确的表连接以及您想要匹配的参数条件。由于我们正在使用LEFT JOIN,因此任何未匹配的条件都会从该表中返回NULL值。

COALESCE()函数获取表达式列表并返回第一个不是NULL的表达式,因此通过将COALESCE()函数中的表达式排序给您'重新喜欢,你可以告诉它,"首先尝试将City.service_centre_id,然后是Province.service_centre_id,然后是Country.service_centre_id ..."等等。

根据您的描述判断,我想知道问题是否在参数中传递给查询的值中。如果你可以手动写出来:

SELECT COUNT(1)
FROM Tranactions
WHERE center_id IN (1)
;

这会给你正确的结果,那么问题可能在于传递的值。

原始查询的结尾:

INSERT INTO @serviceCenter
SELECT service_centre_id
FROM ServiceCentre
;

似乎将所有service_centre_id值传递到@serviceCenter变量。

参数是否可能无法正确传递,因此所有service_center_ids都被选入表变量,这会导致您收到所有服务中心所有事务的计数?

注意:要检查此问题,您可以在SELECT * FROM @serviceCenter系列的末尾运行一个简单的IF...ELSE,以查看返回的值。我怀疑你会比你想要的更多。

答案 2 :(得分:0)

最后2小时后,我发现了错误,除了法术错误外,其他错误都没有。首先,我道歉,因为有问题我使用了center_id,但它实际上是 service_centre_id 。但是我更新了这个问题。现在来解决这个问题。该表的声明如下:

**DECLARE @serviceCenter TABLE (service_center_id INT)

以及where子句如下:

Select Count(1)
From Tranactions
    where service_centre_id IN (Select service_centre_id From @serviceCenter)

问题出在 service_centre_id

交易表包含 service_centre_id 列,在IN运算符查询中,我使用 service_centre_id 而不是 service_center_id 。因为在声明表格时我将列名称设置为 service_center_id 。所以实际的错误是我使用 service_centre_id 而不是 service_center_id 而且有拼写错误。