必须两次输入mySQL标准吗?

时间:2018-03-29 03:22:01

标签: mysql left-join

说我有两张桌子:

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查找所有记录,然后执行另一个查找匹配汽车的记录)。但是,这会导致与数据库的多个连接(每个记录返回一个),并且非常繁重且效率低下。

我也知道关联子查询,但根据我的理解和经验,这是为每个客户返回一个字段(例如,卡尔花了多少钱的聚合字段)。我正在寻找类似的方法,但是一个客户可以与上面的示例输出中的多个其他记录匹配。

在您的回复中,如果您有推荐的解决此问题的查询结构,那么如果您可以编写一个明确的示例而不是仅仅描述它,那将非常有用。我非常感谢你的时间!

1 个答案:

答案 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'

查看SQL Fiddle sample