具有多个搜索参数的内部联接意外返回空

问题描述 投票:0回答:4

汽车

身份证 名字 型号 年份
1 大众高尔夫 1121 2010
2 闪避 3234 2016
3 奥迪 5335 2394
4 宝马 6567 9090
5 丰田 1221 9090

汽车功能

身份证 特点
1 货叉厚度
2 操作员保护
3 后轮胎

汽车规格

身份证 车号 价值 汽车功能 ID
1 1 1.50 1
2 1 开放式开销 2
3 1 夏季轮胎 3
4 2 1.30 1
5 2 封闭式架空 2
6 2 冬季轮胎 3
7 3 1.20 1
8 3 封闭式架空 2
9 3 冬季轮胎 3

这将返回汽车

where Feature.Feature = 'ForkThickness' and corresponding CarSpec.Value > 1.25
--汽车 1 和 2 的 carId 和汽车名称。

SELECT DISTINCT ca.Id, ca.Name 
FROM Car AS ca
INNER JOIN CarSpec AS cs
    ON ca.id = cs.CarId    
INNER JOIN CarFeature AS cf
    ON cf.Id = cs.CarFeatureId    
WHERE cf.Feature = 'ForkThickness' AND cs.Value > 1.25

在搜索参数中包含更多功能应该只返回汽车 1,但它返回空:

WHERE Feature.Feature = 'ForkThickness' AND CarSpec.Value > 1.25
AND Feature.Feature = 'RearTires' AND CarSpec.Value = 'Summer Tires'

我做错了什么?

sql sql-server inner-join
4个回答
1
投票

您可以使用

GROUP BY ... HAVING
和条件聚合来断言多个条件。 小提琴

SELECT ca.Id,
       ca.Name 
FROM   Car AS ca
WHERE  ca.Id IN (SELECT cs.CarId
                 FROM   CarSpec AS cs
                        INNER JOIN CarFeature AS cf
                                ON cf.Id = cs.CarFeatureId
                 GROUP  BY cs.CarId
                 HAVING 1 = MAX(IIF(( cf.Feature = 'ForkThickness' AND TRY_CAST(cs.Value AS DECIMAL(10, 2)) > 1.25 ), 1, 0))
                        AND 1 = MAX(IIF(( cf.Feature = 'RearTires' AND cs.Value = 'Summer Tires' ), 1, 0))) 

0
投票

您尝试的问题是您正在添加更多连接条件,因此您正在寻找具有这两个条件的单个规范/功能。而实际上您想分别检查每个条件。有很多方法可以做到这一点,但

EXISTS
是我的选择,因为它在逻辑上代表了您想要完成的任务。

SELECT ca.Id, ca.Name 
FROM Car c
WHERE EXISTS (
    SELECT 1
    FROM CarSpec cs
    JOIN CarFeature cf on cf.Id = cs.CarFeatureid
    WHERE cs.CarId = c.Id
    AND cf.Feature = 'ForkThickness' AND cs.Value > 1.25
);

还有

SELECT ca.Id, ca.Name 
FROM Car c
WHERE EXISTS (
    SELECT 1
    FROM CarSpec cs
    JOIN CarFeature cf on cf.Id = cs.CarFeatureid
    WHERE cs.CarId = c.Id
    AND cf.Feature = 'ForkThickness' AND cs.Value > 1.25
)
AND EXISTS (
    SELECT 1
    FROM CarSpec cs
    JOIN CarFeature cf on cf.Id = cs.CarFeatureid
    WHERE cs.CarId = c.Id
    AND cf.Feature = 'RearTires' AND cs.Value = 'Summer Tires'
);

0
投票

您可以将具有不同条件的查询分开,然后将它们合并在一起

SELECT ca.Id, ca.Name 
FROM 
   Car AS ca 
   INNER JOIN CarSpec AS cs ON ca.id = cs.CarId    
   INNER JOIN CarFeature AS cf ON cf.Id = cs.CarFeatureId    
WHERE cf.Feature = 'ForkThickness' AND cs.Value > 1.25
    
UNION

SELECT ca.Id, ca.Name 
FROM 
   Car AS ca 
   INNER JOIN CarSpec AS cs ON ca.id = cs.CarId    
   INNER JOIN CarFeature AS cf ON cf.Id = cs.CarFeatureId    
WHERE cf.Feature = 'RearTires' AND cs.Value = 'Summer Tires'

UNION 默认会删除所有重复项


-1
投票

您的代码正在寻找同时具有Feature.Feature = ForkThickness AND Feature.Feature = RearTires 的东西。

WHERE Feature.Feature = 'ForkThickness' AND CarSpec.Value > 1.25
AND Feature.Feature = 'RearTires' AND CarSpec.Value = 'Summer Tires'

这可以与 OR 语句一起使用来查找选项,否则您可以删除双“Feature.Feature”参数/要求。

相反,将 AND 语句替换为 OR 语句:

WHERE (Feature.Feature = 'ForkThickness' AND CarSpec.Value > 1.25)
OR (Feature.Feature = 'RearTires' AND CarSpec.Value = 'Summer Tires')

这将导致找到 2 辆车。

或者,如果您希望获得 1 个结果,您可以使用以下内容。 但只需检查您的逻辑,具体取决于您的实际需求。

WHERE (Feature.Feature = 'ForkThickness' OR Feature.Feature = 
'RearTires') AND CarSpec.Value > 1.25 AND CarSpec.Value = 'Summer Tires'
© www.soinside.com 2019 - 2024. All rights reserved.