【问题标题】:Is this a valid correlated sub query with joins?这是一个有效的关联子查询吗?
【发布时间】:2019-12-01 10:02:49
【问题描述】:

所以我有一个表Car(Car_id, Value, Make),另一个表Person(Person_id, Name) 和第三个表将两者连接在一起PerCar(Car_id, Person_id)

所以我有这个相关的子查询:

SELECT MAKE, VALUE 
FROM CAR WHERE VALUE > (SELECT AVG(VALUE) FROM CAR C WHERE C.CAR_ID = CAR_ID);

如果我还想显示人名,这是否也是有效的相关子查询:

SELECT Car.Make, Car.Value, Person.Name 
FROM PerCar NATURAL JOIN Car 
NATURAL JOIN Person where Car.Value > (SELECT AVG(VALUE) FROM Car);

【问题讨论】:

  • 你的两个查询返回不同的结果,#1 是一个 Correlated Subquery,返回的行的值大于相关 CAR_ID 的平均值但是 2# 返回的行的值大于 所有汽车,它不相关,它是标量
  • 其实你的第一个Select不是Correlated Subquery,因为内表和外表没有关联,WHERE C.CAR_ID = CAR_ID1=1一样,应该是FROM CAR C WHERE VALUE > (SELECT AVG(VALUE) FROM CAR C2 WHERE C.CAR_ID = C2.CAR_ID)
  • 避免像瘟疫一样的自然连接。
  • @TheImpaler:在识别为“The Impaler”的同时,竭尽全力告诉某人避免一种罕见且易于治疗的疾病 - 您目前正在采取哪些措施来避免真正的瘟疫?是这样想的。
  • @onedaywhen LOL

标签: sql postgresql correlated-subquery


【解决方案1】:

您的查询应该如下-

您可以查看DEMO HERE

SELECT Car.Make, 
Car.Value, 
Person.Name 
from Car
INNER JOIN CarPer 
    ON Car.Car_id = CarPer.Car_id 
INNER JOIN Person
    ON Person.Person_id = CarPer.Person_ID        
WHERE Car.Value > (SELECT AVG(VALUE) FROM Car);

请记住,根据您的要求和数据结构,这里的连接可以是 INNER、OUTER、LEFT 或其他连接。

【讨论】:

  • 嗨,谢谢,我得到了一个额外的表,名为PerCar(Car_id, Person_id) which links the Car table and Person table together. So can I not do 3 joins, one like Car Inner Join PerCar Inner Join Person```?这仍然是一个相关的子查询吗?
  • 这仍然是一个有效的相关子查询吗?
  • 是的,这是有效的。
  • 非常感谢,我在 :stackoverflow.com/questions/59120948/… 中被告知相关查询不能有连接。
  • 嗯,没有 Correlated 子查询,它是一个 Scalar 子查询
【解决方案2】:

这不是相关子查询:

SELECT MAKE, VALUE 
FROM CAR
WHERE VALUE > (SELECT AVG(VALUE) FROM CAR C WHERE C.CAR_ID = CAR_ID);

始终限定查询中的所有列引用。

认为WHERE 子句是:

WHERE CAR.VALUE > (SELECT AVG(VALUE) FROM CAR C WHERE C.CAR_ID = CAR.CAR_ID);

但确实如此:

WHERE CAR.VALUE > (SELECT AVG(C.VALUE) FROM CAR C WHERE C.CAR_ID = C.CAR_ID);

没有对外部查询的引用,因此这不相关。我会这样写:

SELECT C.MAKE, C.VALUE 
FROM CAR C
WHERE C.VALUE > (SELECT AVG(C2.VALUE) FROM CAR C2 WHERE C2.CAR_ID = C2.CAR_ID);

但是,这不太可能返回任何行。鉴于您没有问题陈述和表中的值,一个明智的查询将返回“所有价值高于其品牌平均值的汽车”

SELECT C.MAKE, C.VALUE 
FROM CAR C
WHERE C.VALUE > (SELECT AVG(C2.VALUE) FROM CAR C2 WHERE C2.MAKE = C.MAKE);

因为您的问题的其余部分是基于第一个查询是“相关子查询”,所以问题的其余部分没有意义。

【讨论】:

  • 我猜WHERE C2.CAR_ID = C2.CAR_ID 应该是WHERE C2.CAR_ID = C.CAR_ID ??
  • 你所谓的“列引用”实际上是范围变量,代表行,即错误的心态。请注意,使用 NATURAL JOIN 不需要范围变量,例如OP 的第二个查询可以写成 SELECT Make, Value, Name... WHERE Value... 吗?即删除多余的范围变量。
  • @onedaywhen 。 . . NATURAL JOIN 是可憎的,因为它没有考虑正确声明的外键关系。
  • @GordonLinoff:跟我重复一遍:SQL DML(包括连接)不依赖于 SQL DDL(包括 fks)按设计
猜你喜欢
  • 2012-11-17
  • 1970-01-01
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
相关资源
最近更新 更多