将多个行连接为具有许多where和having子句的列

时间:2016-03-14 21:45:10

标签: mysql join

我正在努力解决(一个复杂的?)问题,我无法自己解决这个问题。

我得到了以下表格:(坐标是dummys)

表A:

ID | Name    |Attribute 1 | Attribute 2 | Lat | Lon | Car Country
1  | Test 1  | Blue       | BMW         | 6.4 | 6.2 | German
2  | Hallo   | Red        |Porsche      | 6.4 |6.2  | German
3  | Miau    | Silver     |Ferrari      | 2.5 | 1.4 | Italy

表B

ID |ID Car|  Slot |  Path
1  |  1   |  1    |jsjf.jpg
2  |  2   |  1    | hkfu.jpg
3  |  2   |  2   | eqfwg.png

用户可以上传具有属性和坐标以及无限图片的汽车。然后使用路径Slot(第一张图像,第二张图像......)和它所属的汽车将图片保存在表B中。

所以现在我想让我的半径范围内的每辆车和前3张图片。作为坐标6.4和6.2的结果,我需要:

ID | Name   | Attribute 1 | Attribute 2 | image1   | image2    |image3
1  | Test 1 | Blue        | BMW         | jsjf.jpg | Null      | Null
2  | Hallo  | Red         | Porsche     | hkfu.jpg | eqfwg.png | Null

我的查询目前是:

SELECT
   a.id,
   a.name,
   a.attribute1,
   a.attribute2,
   MAX(CASE WHEN b.slot= 1 THEN b.path ELSE NULL END) image1,
   MAX(CASE WHEN b.slot= 2 THEN b.path ELSE NULL END) image2,
   MAX(CASE WHEN b.slot= 3 THEN b.path ELSE NULL END) image3,
(
    6371 * acos(
        cos(
            radians( 6.4 )
        ) * cos(
            radians( lat )
        ) * cos(
            radians( lon ) - radians( 6.2 )
        ) + sin(
            radians( 6.4 )
        ) * sin(
            radians( lat )
        )
    )
) AS distance

FROM
a
 left join bon a.id=b.idcar


WHERE carcountry= 'German'
HAVING
  distance <= 50

ORDER BY
   distance asc LIMIT 0, 10

没有Max()并加入一切正常......

1 个答案:

答案 0 :(得分:0)

您无法通过聚合解决此问题。您可以为每个图像执行多个左连接,包括连接的slot = n中的ON子句,所以:

SELECT (...), image1.file as image1, image2.file as image2, (...)
FROM 
    a 
    LEFT JOIN image image1 ON slot=1 AND a.id=image1.idcar
    LEFT JOIN image image2 ON slot=2 AND a.id=image2.idcar

当然,将slot与外键一起包含在索引中会很有帮助。此外,简单地查询所有图像并在应用程序逻辑中重构数据可能更有效; LEFT JOINS往往很贵。我建议花些时间来衡量一下。

我认为通过子查询加入子查询也可能是可以解决的,但是我不会这样做,因为它往往不会更有效,而且会花费你的易读性。