【问题标题】:Join three tables and count加入三个表并计数
【发布时间】:2014-12-12 22:23:07
【问题描述】:

这个真的很复杂,那我就举个例子方便一下。

假设我们有 4 张桌子:车库、汽车、证券、场所。

garages 是您可以找到cars 的地方,securities 是确保汽车在车库内安全的安全措施,places 是您可以找到与该车库类似的车库的地方。然后我们就有了一张这样的桌子。

车库桌:

-----------------------------------
|garage_id|garage_name|garage_size|
-----------------------------------
|        1|   Garage 1|        200|
-----------------------------------
|        2|   Garage 2|        400|
-----------------------------------

汽车表:

---------------------------
|car_id|car_name|garage_id|
---------------------------
|     1|   Car 1|        1|
---------------------------
|     2|   Car 2|        1|
---------------------------
|     3|   Car 3|        2|
---------------------------

证券表:

----------------------------------
|security_id|security_name|car_id|
----------------------------------
|          1|  Security 1|      1|
----------------------------------
|          2|  Security 2|      1|
----------------------------------
|          3|  Security 3|      2|
----------------------------------
|          4|  Security 4|      3|
----------------------------------

放置表:

-------------------------------
|place_id|place_name|garage_id|
-------------------------------
|       1|   place 1|        1|
-------------------------------
|       2|   place 2|        1|
-------------------------------
|       3|   place 3|        1|
-------------------------------
|       4|   place 4|        2|
-------------------------------
|       5|   place 5|        2|
-------------------------------

我想要的是列出车库并加入三个表,即汽车、证券和地点,如下所示:

车库 1 有 2 辆有 3 个证券的汽车,还有 3 个类似的车库

车库 2 有 1 辆有 1 证券的汽车,还有 2 个类似的车库

现在你可能会问,为什么Garage 1 有 3 个证券?因为Garage 1Car 1Car 2Car 1 有两个证券Security 1Security 2Car 2 有1 个是Security 3

这里的问题是:如何连接表并在一个查询中计数并返回结果,就像您在上面看到的那样?

【问题讨论】:

    标签: php mysql laravel eloquent


    【解决方案1】:

    只需加入所有表,按车库分组并计算不同的匹配项:

    select 
      g.garage_name, 
      count(distinct c.car_id) as count_cars,
      count(distinct s.security_id) as count_securities,
      count(distinct p.place_id) as count_places
    from garages g
    left join cars c on c.garage_id = g.garage_id
    left join securities s on s.car_id = c.car_id
    left join places p on p.garage_id = g.garage_id
    group by g.garage_name
    order by g.garage_name;
    

    至于所需的输出字符串,连接你的结果:

    g.garage_name || ' has ' || count(distinct c.car_id) || ' cars with ' || ...
    

    【讨论】:

      【解决方案2】:
      SELECT
       gb.garage_name,
       (
        SELECT COUNT(*) FROM cars_table ct WHERE ct.garage_id = db.garage_id
       ) as car_count,
       (
        SELECT COUNT(*) FROM security_table st JOIN cars_table ct ON ct.car_id = st.car_id WHERE ct.garage_id = db.garage_id
       ) as security_count,
      FROM
      garages_table gb
      ORDER BY gb.garage_id
      

      这是未经测试的,但这是一个想法。

      【讨论】:

        【解决方案3】:

        这个查询应该可以完成这项工作:

        SELECT g.garage_id, g.garage_name, COUNT(c.car_id) AS nb_cars,
            COUNT(s.security_id) AS nb_securities, COUNT(p.place_id) AS nb_places
        FROM garages g
            LEFT JOIN cars c ON g.garage_id = c.garage_id
            LEFT JOIN securities c.car_id = s.car_id
            LEFT JOIN places.p ON g.garage_id = p.garage_id
        GROUP BY g.garage_id
        

        您将获得所有车库的列表,包括那些周围没有汽车或地方的车库。如果您想过滤掉没有汽车的车库,请使用INNER JOIN cars ...。要过滤掉没有地方的车库,请使用INNER JOIN places ...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-22
          • 2019-01-04
          • 1970-01-01
          相关资源
          最近更新 更多