如何使用IN关键字?

时间:2014-08-26 07:46:40

标签: sql sql-server

我有一个名为PropertyFeatures的表,它有三列。第一个 - PropertyFeatureId是一个自动递增的列,第二个 - PropertyidProperty表的外键,最后一个 - Featureid是外来的Feature表的密钥。

+------------------------------------------+
| PropertyFeatureId  PropertyId  FeatureId |
+------------------------------------------+
| 1                   1             1      |
| 2                   1             2      |
| 3                   2             2      |
| 4                   2             3      |
| 5                   2             4      |
+------------------------------------------+

SELECT propertyFeatures.PropertyId       
FROM PropertyFeatures propertyFeatures INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures.[FeatureId] IN (1,2)
GROUP BY propertyFeatures.PropertyId

以上查询给出以下结果:

PropertyId 
1
2

我想获得以下结果:

PropertyId
1

因为Featureid 1和2仅适用于PropertyId 1。

如果我将查询更改为以下内容:

SELECT propertyFeatures.PropertyId       
FROM PropertyFeatures propertyFeatures INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures .[FeatureId] IN (2,3,4)
GROUP BY propertyFeatures.PropertyId

它只会显示:

PropertyId 
2 

因为Featureid 2,3和4仅适用于PropertyId 2。

如何达到预期效果?

6 个答案:

答案 0 :(得分:2)

请注意,WHERE a IN (1, 2)实际上是WHERE a = 1 OR a = 2的快捷方式。这不会给出两组的交集,只有第一个过滤器有效的集合与第二个过滤器有效的集合的组合。在您的情况下,EXISTS的支票可能是您要搜索的内容 - 或INTERSECT

INTERSECT的示例:

SELECT   propertyFeatures.PropertyId       
FROM     PropertyFeatures AS propertyFeatures
INNER JOIN Feature AS feature ON feature.id = propertyFeatures.FeatureId
WHERE    propertyFeatures.[FeatureId] = 1
GROUP BY propertyFeatures.PropertyId
INTERSECT
SELECT   propertyFeatures.PropertyId       
FROM     PropertyFeatures AS propertyFeatures
INNER JOIN Feature AS feature ON feature.id = propertyFeatures.FeatureId
WHERE    propertyFeatures.[FeatureId] = 2
GROUP BY propertyFeatures.PropertyId;

EXISTS的示例:

SELECT   propertyFeatures.PropertyId       
FROM     PropertyFeatures AS propertyFeatures
INNER JOIN Feature AS feature ON feature.id = propertyFeatures.FeatureId
WHERE    EXISTS (SELECT TOP 1 * FROM PropertyFeatures AS P
                 INNER JOIN Feature AS F ON F.id = P.FeatureId
                 WHERE P.FeatureId = 1)
         AND
         EXISTS (SELECT TOP 1 * FROM PropertyFeatures AS P
                 INNER JOIN Feature AS F ON F.id = P.FeatureId
                 WHERE P.FeatureId = 2);

(代码未经过测试,所以如果有效,请自行检查!)

答案 1 :(得分:0)

试试这个

SELECT propertyFeatures.PropertyId, 
FROM PropertyFeatures propertyFeatures 
INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures .[FeatureId] IN (1,2)
GROUP BY propertyFeatures.PropertyId
HAVING SUM(CASE WHEN propertyFeatures .[FeatureId] IN (1,2) THEN 1 ELSE 0 END)=2

答案 2 :(得分:0)

您可以使用EXISTS子句代替IN caluse:

Demo Sql Fiddle

创建脚本:

CREATE TABLE PropertyFeatures
    ([PropertyFeatureId] int, [PropertyId] int, [FeatureId] int)
;

INSERT INTO PropertyFeatures
    ([PropertyFeatureId], [PropertyId], [FeatureId])
VALUES
    (1, 1, 1),
    (2, 1, 2),
    (3, 2, 2),
    (4, 2, 3),
    (5, 2, 4)
;

SQL声明:

select distinct PropertyId
from   PropertyFeatures pf1 
where  exists (select PropertyId 
               from PropertyFeatures pf2 
               where FeatureID = 1 and pf1.PropertyId = pf2.PropertyId)
   and exists (select PropertyId 
               from PropertyFeatures pf2 
               where FeatureID = 2 and pf1.PropertyId = pf2.PropertyId)

因此exists语句中的每个子查询都返回PropertyId,您可以and将它们放在一起。

我可以看到的问题是,每次要查询更多EXISTS值时,您都必须添加另一个FeatureId子句。

答案 3 :(得分:0)

请您查看功能ID是否为1,2:

SELECT count(propertyFeatures.PropertyId) as cnt, propertyFeatures.PropertyId    
FROM PropertyFeatures propertyFeatures 
INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures.[FeatureId] IN (1,2)
GROUP BY propertyFeatures.PropertyId
having COUNT(1)>1

2,3,4:

SELECT count(propertyFeatures.PropertyId)as cnt, propertyFeatures.PropertyId    
FROM PropertyFeatures propertyFeatures 
INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures.[FeatureId] IN (2,3,4)
GROUP BY propertyFeatures.PropertyId
having COUNT(1)>1

答案 4 :(得分:0)

select propertyFeatures.PropertyId     from (
SELECT count(propertyFeatures.PropertyId),   propertyFeatures.PropertyId    
FROM PropertyFeatures propertyFeatures INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures.[FeatureId] IN (1,2)
GROUP BY propertyFeatures.PropertyId
having COUNT(1)>1) a

select propertyFeatures.PropertyId     from
SELECT count(propertyFeatures.PropertyId),   propertyFeatures.PropertyId    
FROM PropertyFeatures propertyFeatures INNER JOIN Feature feature ON feature.id = propertyFeatures.FeatureId
WHERE propertyFeatures.[FeatureId] IN (2,3,4)
GROUP BY propertyFeatures.PropertyId
having COUNT(1)>1) a

答案 5 :(得分:-1)

您的查询要求FeatureID为1或2的那些propertyID,您想要的是获取FeatureID为1 AND 2的ID。为了做到这一点,请将您的查询更改为:

SELECT pf.PropertyId
FROM PropertyFeatures pf INNER JOIN Feature f ON f.id=pf.FeatureID
WHERE pf.FeatureId in (1,2)
GROUP BY pf.PropertyId
HAVING COUNT(pf.PropertyId)=2