说我有两张桌子:
Table: customers
Fields: customer_id, first_name, last_name
Table: customer_cars
Fields: car_id, customer_id, car_brand, car_active
假设我正在尝试编写一个查询,显示名字为"卡尔的所有客户,"和他们拥有的**活跃**汽车的品牌。并非所有客户都拥有活跃的汽车。有些车辆处于活动状态,有些车辆处于非活动状态。
请记住,这是我刚刚编写的一个代表性示例,为了清晰和简单起见。请不要回答有关我们为什么这样做的问题,我可以使用表别名,如何使用非活动车,或者我的字段名称可以写得更好。这是一个虚假的例子,旨在说明这一点非常简单。它有一个我一直遇到的结构和问题。
看起来最好使用LEFT JOIN和子查询来完成。
SELECT
customer_id,
first_name,
last_name,
car_brand
FROM
customers
LEFT JOIN
(SELECT
customer_id,
car_brand
FROM
customer_cars
INNER JOIN customers ON customer_cars.customer_id = customers.customer_id
WHERE
first_name = 'Karl' AND
customer_cars.car_active = '1') car_query ON customers.customer_id = car_query.customer_id
WHERE
first_name = 'Karl'
结果可能如下所示:
first_name last_name car_brand
Karl Johnson Dodge
Karl Johnson Jeep
Karl Smith NULL
Karl Davis Chrysler
注意卡尔'重复。在WHERE子句中,以及子查询中的INNER JOIN是外部查询中的同一个表。我对mySQL的理解是这种复制是必要的,因为它在处理外部查询之前首先处理子查询。因此,必须正确限制子查询,以便它不扫描所有记录,然后尝试匹配生成的记录。
我知道删除car_active =' 1'条件会改变一切,但这是一项要求。
我想知道这样的查询是否可以以不同的方式完成,只会导致标准和联接输入一次。是否有建议的方法首先确定外部查询的优先级,然后匹配内部查询?
我知道可以编写两个不同的查询(使用Karl查找所有记录,然后执行另一个查找匹配汽车的记录)。但是,这会导致与数据库的多个连接(每个记录返回一个),并且非常繁重且效率低下。
我也知道关联子查询,但根据我的理解和经验,这是为每个客户返回一个字段(例如,卡尔花了多少钱的聚合字段)。我正在寻找类似的方法,但是一个客户可以与上面的示例输出中的多个其他记录匹配。
在您的回复中,如果您有推荐的解决此问题的查询结构,那么如果您可以编写一个明确的示例而不是仅仅描述它,那将非常有用。我非常感谢你的时间!
答案 0 :(得分:1)
首先,简单而直接的查询还不够?
假设我正在尝试编写一个显示所有客户的查询 "卡尔的名字,"和他们拥有的**活跃**汽车的品牌。不 所有客户都将拥有一辆活跃的汽车。有些车是活动的,有些是 不活动的。
遵循这个要求,我可以做类似的事情:
SELECT C.first_name
, C.last_name
, CC.car_brand
FROM customers C
LEFT JOIN cutomer_cars CC ON CC.customer_id = C.customer_id
AND car_active = 1
WHERE C.first_name = 'Karl'