试图从 2 个正在连接的子查询中获取一列并且分组不起作用

Trying to grab a column from 2 subqueries being joined and grouping not working

我的桌子是什么样子的:

mysql> select * from customer limit 3;
+-------------+---------------+-----------------------+------+--------+-------------+-------+
| customer_id | customer_name | profession            | age  | salary | town        | state |
+-------------+---------------+-----------------------+------+--------+-------------+-------+
|           1 | Julio Sperski | Architect             |   70 |  52016 | Conroe      | TX    |
|           2 | Micah Inchley | Biological  scientist |   86 |  45355 | Omaha       | NE    |
|           3 | Brigg Denny   | Chemist               |   80 |  21754 | Bakersfield | CA    |
+-------------+---------------+-----------------------+------+--------+-------------+-------+
3 rows in set (0.00 sec)

mysql> select * from vehicle limit 3;
+------------+---------------+--------------------+--------+--------+---------+----------------+--------------------+-----------------------+
| vehicle_id | vehicle_plate | registration_state | color  | make   | model   | vehicle_type   | per_day_rental_fee | per_day_insurance_fee |
+------------+---------------+--------------------+--------+--------+---------+----------------+--------------------+-----------------------+
|          1 | W9FLYC7       | TX                 | black  | toyota | cruiser | mid size sedan |                 44 |                    27 |
|          2 | CA1CJIZ       | NE                 | silver | ford   | se      | suv            |                 96 |                    71 |
|          3 | HB5YI9A       | CA                 | silver | dodge  | mpv     | truck          |                 26 |                    28 |
+------------+---------------+--------------------+--------+--------+---------+----------------+--------------------+-----------------------+
3 rows in set (0.00 sec)

mysql> select * from rental limit 3;
+-----------+-------------+------------+-------------------+--------------------+-------------------------+----------------------------+
| rental_id | customer_id | vehicle_id | start_rental_date | return_rental_date | per_day_rental_fee_paid | per_day_insurance_fee_paid |
+-----------+-------------+------------+-------------------+--------------------+-------------------------+----------------------------+
|         1 |          32 |          4 | 3/4/2019          | 3/6/2019           | no                      | no                         |
|         2 |          42 |         39 | 3/23/2019         | 3/24/2019          | yes                     | yes                        |
|         3 |          33 |         14 | 10/18/2020        | 10/24/2020         | no                      | no                         |
+-----------+-------------+------------+-------------------+--------------------+-------------------------+----------------------------+
3 rows in set (0.00 sec)

customer_id、vehicle_id 和 rental_id 是主键。

customer_id和vehicle_id分别是指向客户和车辆table的外键。

所以我正在尝试获取第 3 列并显示它。 查询是这样的:

对于租车公司运营的每个注册州,return 来自特定客户州的客户数量最多。就像如果有 5 个来自 TX 的客户但在 CA 租车,而只有 2 个来自 NY 的客户在 CA 注册租车,我会 return 来自 TX 的 5 个在 CA 租车,依此类推,直到我完成了所有的注册状态。

第一个查询, 我得到的最接近的是这个查询:

SELECT registration_state, 
       Max(count) AS count 
FROM   (SELECT registration_state, 
               Count(a.state) AS count, 
               a.state 
        FROM   rental c 
               LEFT JOIN customer a 
                      ON a.customer_id = c.customer_id 
               LEFT JOIN vehicle b 
                      ON c.vehicle_id = b.vehicle_id 
        GROUP  BY registration_state, 
                  a.state)Z 
GROUP  BY registration_state 
ORDER  BY registration_state, 
          count DESC; 

+--------------------+-------+
| registration_state | count |
+--------------------+-------+
| AL                 |     1 |
| CA                 |     5 |
| DC                 |     1 |
| DE                 |     2 |
| FL                 |     3 |
| IL                 |     2 |
| IN                 |     1 |
| MD                 |     2 |
| MI                 |     1 |
| MN                 |     1 |
| MO                 |     1 |
| NE                 |     1 |
| NV                 |     2 |
| NY                 |     3 |
| OH                 |     2 |
| OR                 |     1 |
| PA                 |     1 |
| SC                 |     1 |
| TN                 |     3 |
| TX                 |     7 |
| WA                 |     1 |
+--------------------+-------+
21 rows in set (0.01 sec)

但是它只显示 registration_state 和租车公司在该州租车最多但没有显示客户状态的客户状态的计数,我希望显示客户状态.

第二个查询,以下查询生成 returns 对每个注册状态的每个客户状态的租金计数:

SELECT registration_state, 
       Count(d.state) AS count, 
       d.state 
FROM   rental f 
       LEFT JOIN customer d 
              ON d.customer_id = f.customer_id 
       LEFT JOIN vehicle e 
              ON f.vehicle_id = e.vehicle_id 
GROUP  BY registration_state, 
          d.state 
ORDER  BY registration_state, 
          count DESC; 

+--------------------+-------+-------+
| registration_state | count | state |
+--------------------+-------+-------+
| AL                 |     1 | NY    |
| CA                 |     5 | CA    |
| CA                 |     4 | MO    |
| CA                 |     2 | IN    |
| CA                 |     2 | TN    |
| CA                 |     2 | TX    |
| CA                 |     2 | OH    |
| CA                 |     1 | FL    |
| CA                 |     1 | AL    |
| CA                 |     1 | MI    |
| CA                 |     1 | NE    |
| CA                 |     1 | WA    |
| DC                 |     1 | CA    |
| DC                 |     1 | IL    |
| DC                 |     1 | TX    |
| DE                 |     2 | NY    |
| DE                 |     1 | FL    |
| FL                 |     3 | NY    |
| FL                 |     1 | AL    |
| FL                 |     1 | OH    |
| FL                 |     1 | CA    |
| FL                 |     1 | FL    |
| FL                 |     1 | MI    |
| FL                 |     1 | TX    |
| IL                 |     2 | OR    |
| IL                 |     1 | TX    |
| IL                 |     1 | CA    |
| IN                 |     1 | NV    |
| IN                 |     1 | CA    |
| MD                 |     2 | WA    |
| MD                 |     1 | OH    |
| MD                 |     1 | MD    |
| MI                 |     1 | PA    |
| MN                 |     1 | PA    |
| MN                 |     1 | TN    |
| MN                 |     1 | FL    |
| MO                 |     1 | NY    |
| MO                 |     1 | SC    |
| MO                 |     1 | OH    |
| MO                 |     1 | OR    |
| MO                 |     1 | CA    |
| MO                 |     1 | FL    |
| MO                 |     1 | TX    |
| NE                 |     1 | CA    |
| NV                 |     2 | FL    |
| NY                 |     3 | TX    |
| NY                 |     1 | CA    |
| NY                 |     1 | FL    |
| NY                 |     1 | MO    |
| NY                 |     1 | NY    |
| OH                 |     2 | OH    |
| OH                 |     1 | TN    |
| OH                 |     1 | NE    |
| OH                 |     1 | PA    |
| OH                 |     1 | DC    |
| OH                 |     1 | NY    |
| OR                 |     1 | IN    |
| OR                 |     1 | CA    |
| PA                 |     1 | MO    |
| PA                 |     1 | DC    |
| SC                 |     1 | FL    |
| SC                 |     1 | NY    |
| TN                 |     3 | TX    |
| TN                 |     2 | CA    |
| TN                 |     1 | FL    |
| TN                 |     1 | PA    |
| TN                 |     1 | MI    |
| TN                 |     1 | OH    |
| TN                 |     1 | OR    |
| TN                 |     1 | MO    |
| TX                 |     7 | NY    |
| TX                 |     4 | TX    |
| TX                 |     3 | FL    |
| TX                 |     2 | MO    |
| TX                 |     2 | MD    |
| TX                 |     2 | DC    |
| TX                 |     1 | IN    |
| TX                 |     1 | OH    |
| TX                 |     1 | CA    |
| TX                 |     1 | NV    |
| TX                 |     1 | OR    |
| TX                 |     1 | IL    |
| WA                 |     1 | TN    |
| WA                 |     1 | MI    |
+--------------------+-------+-------+
84 rows in set (0.00 sec)

正如你在上面看到的table,如果你将它与第一个table进行比较,你会发现第一个table只是return在该注册状态下租金最多的客户状态。

我试图让它看起来像这样:

+--------------------+-------+-------+
| registration_state | count | state |
+--------------------+-------+-------+
| AL                 |     1 | NY    |
| CA                 |     5 | CA    |
| DC                 |     1 | CA    |
| DE                 |     2 | NY    |
| FL                 |     3 | NY    |
| IL                 |     2 | OR    |
| IN                 |     1 | NV    |
| MD                 |     2 | WA    |
| MI                 |     1 | PA    |
| MN                 |     1 | PA    |
| MO                 |     1 | NY    |
| NE                 |     1 | CA    |
| NV                 |     2 | FL    |
| NY                 |     3 | TX    |
| OH                 |     2 | OH    |
| OR                 |     1 | IN    |
| PA                 |     1 | MO    |
| SC                 |     1 | FL    |
| TN                 |     3 | TX    |
| TX                 |     7 | NY    |
| WA                 |     1 | TN    |
+--------------------+-------+-------+

我试过这样加入:

SELECT    registration_state, 
          MAX(count)
FROM      ( 
                    SELECT    registration_state, 
                              Count(d.state) AS count, 
                              d.state 
                    FROM      rental f 
                    LEFT JOIN customer d 
                    ON        d.customer_id = f.customer_id 
                    LEFT JOIN vehicle e 
                    ON        f.vehicle_id = e.vehicle_id 
                    GROUP BY  registration_state, 
                              d.state)W 
RIGHT JOIN 
          ( 
                    SELECT    registration_state AS registration_state2, 
                              count(a.state)     AS count2, 
                              a.state 
                    FROM      rental c 
                    LEFT JOIN customer a 
                    ON        a.customer_id = c.customer_id 
                    LEFT JOIN vehicle b 
                    ON        c.vehicle_id = b.vehicle_id 
                    GROUP BY  registration_state, 
                              a.state )z 
ON        z.count2=W.count 
AND      z.registration_state2=W.registration_state
GROUP BY registration_state
ORDER BY registration_state;


但它只是 return 与第一个查询相同,如果我将来自任一子查询的状态添加到第一行中的 select 语句,并且还在第一行按所述状态分组结束,我结束了第二个查询。

是否有关于如何以我想要的方式return的任何建议?

如果你是运行 MySQL 8.0,你可以使用window函数为每个注册状态带来租金最多的客户状态:

select registration_state, state, cnt
from (
    select v.registration_state, c.state, count(*) as cnt,
        rank() over(partition by v.registration_state order by count(*) desc) rn
    from rental r
    inner join customer c on c.customer_id = r.customer_id 
    inner join vehicle  v on r.vehicle_id = v.vehicle_id 
    group  by v.registration_state, c.state 
) t
where rn = 1
order  by registration_state;

在较早的版本中,它有点复杂。一种选择是在 having 子句中使用行限制相关子查询:

select v.registration_state, c.state, count(*) as cnt
from rental r
inner join customer c on c.customer_id = r.customer_id 
inner join vehicle  v on r.vehicle_id = v.vehicle_id 
group  by v.registration_state, c.state 
having count(*) = (
    select count(*)
    from rental r1
    inner join customer c1 on c1.customer_id = r1.customer_id 
    inner join vehicle  v1 on r1.vehicle_id = v1.vehicle_id 
    where c1.state = c.state and v1.registration_state = v.registration_state
    group by v1.registration_state, c1.state 
    order by count(*) desc limit 1
)

请注意,这两个查询都允许顶级联系(如果有的话)。