MySql join multiple tables with different rows number

僤鯓⒐⒋嵵緔 提交于 2019-12-25 08:06:15

问题


I'm sorry for the probably confusing title but I didn't really know how to describe my problem well. I also appologize for my english as I'm not a native speaker.

Let's say I have this schema :

 _________                               _________
| Table 1 |                             | Table 2 |
|---------|          ______     ________|---------|
| id_a    |___      | join |   |        | id_b    |
| name    |   |     |------|   |        | info    |
|_________|   |_____| id_a |___|        | data    |
                    | id_b |            |_________|
                    |______|

With these informations in the database :

Table 1 :

 _____________
| id_a | name |
|------|------|
|   1  | foo  |
|______|______|

Table 2 :

 _____________________
| id_b | info | data  |
|------|------|-------|
|   1  | bar  | baz   |
|   2  | kux  | corge |
|   3  | fred | quux  |
|______|______|_______|

Join :

 _____________
| id_a | id_b |
|------|------|
|   1  |   1  |
|   1  |   2  |
|   1  |   3  |
|______|______|

In my database, I have other tables that are the same type as the "Join" one. They are used to store a "Table 1" ID and other IDs from other tables (I used only one join table in my schema to simplify the problem).

When I tried to retrive the datas that I wanted, I first used this syntax :

SELECT t1.*,
       t2.*
FROM table1 AS t1
LEFT JOIN join AS j
ON j.id_a = t1.id_a
LEFT JOIN table2 AS t2
ON t2.id_b = j.id_b
WHERE t1.id_a = ?

But as the result was an array of multiple rows while I was expecting only one single row, I tried then to use GROUP_CONCAT.

So my syntax became :

SELECT t1.*,
       GROUP_CONCAT(t2.info SEPARATOR '|') AS info,
       GROUP_CONCAT(t2.data SEPARATOR '|') AS data
FROM table1 AS t1
LEFT JOIN join AS j
ON j.id_a = t1.id_a
LEFT JOIN table2 AS t2
ON t2.id_b = j.id_b
WHERE t1.id_a = ?
GROUP BY t1.id_a

Now it works fine and it returns a single row.

The problem now is that I'm using this principle with multiple joins and each join returns multiple rows of a different number than the others. The concatenation value is then duplicated and I can have results such as :

arrray(
    [...]
    'info' => 'bar|bar|bar|bar|kux|kux|kux|kux|fred|fred|fred|fred|',
    'data' => 'baz|baz|baz|baz|corge|corge|corge|corge|corge|quux|quux|quux|quux'
)

So I would like to know if there is a way to avoid duplicated values and still retrieve the datas that I want in a single request ?


回答1:


Given your data, this query should be returning what you want:

SELECT t1.*,
       GROUP_CONCAT(t2.info SEPARATOR '|') AS info,
       GROUP_CONCAT(t2.data SEPARATOR '|') AS data
FROM table1 t1 LEFT JOIN
     join j
     ON j.id_a = t1.id_a LEFT JOIN
     table2 t2
     ON t2.id_b = j.id_b
WHERE t1.id_a = ?
GROUP BY t1.id_a;

If you want, you can remove the duplicates using DISTINCT:

SELECT t1.*,
       GROUP_CONCAT(DISTINCT t2.info SEPARATOR '|') AS info,
       GROUP_CONCAT(DISTINCT t2.data SEPARATOR '|') AS data
FROM table1 t1 LEFT JOIN
     join j
     ON j.id_a = t1.id_a LEFT JOIN
     table2 t2
     ON t2.id_b = j.id_b
WHERE t1.id_a = ?
GROUP BY t1.id_a;

Typically, though, it is better to fix the query so it doesn't generate the duplicates.



来源:https://stackoverflow.com/questions/38948593/mysql-join-multiple-tables-with-different-rows-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!