将表B中的多行链接到MySQL中的表A中的一行

时间:2015-11-21 03:25:31

标签: php mysql

为了简单起见,我有两张桌子,表A和表格B(注意,我没有权限改变这些表格的结构,所以我问这个问题是为了解决这个问题数据库设计)。

表A有两列:

"id"          - is the unique identifier.
"customer_id" - is the customer's ID.

因此,表A包含客户ID列表。

表B包含有关客户的属性。但它以一种奇怪的方式做到了(再次,我没有设置它,我无法改变它)。表B有[NUMBER]列:

"id"          - is the unique identifier.
"customer_id" - is the customer's ID.
"key"         - is the name of the key/value pair
"value"       - is the value of the key/value pair

因此,表B包含通过其ID链接到客户的键/值对。

我可以加入这两个表来得到这样的结果:

+----+-------------+------------+-------+
| id | customer_id | key        | value |
+----+-------------+------------+-------+
| 0  | 5           | first_name | Bob   |
| 1  | 5           | last_name  | Jones |
| 2  | 6           | first_name | Sally |
| 3  | 6           | last_name  | Sue   |
+----+-------------+------------+-------+

但正如您所看到的,这可能很难管理,因为有关一个客户的信息位于两个不同的行上。理想的是这样的事情:

+----+-------------+------------+-----------+
| id | customer_id | first_name | last_name |
+----+-------------+------------+-----------+
| 0  | 5           | Bob        | Jones     |
| 1  | 6           | Sally      | Sue       |
+----+-------------+------------+-----------+

将所有客户的数据放在一行。

有没有办法在SQL查询中执行此操作,以便我不必在PHP中混淆结果?或者我是否必须在PHP中选择数据?

4 个答案:

答案 0 :(得分:0)

一种方法是条件聚合:

select (@rn := @rn + 1) as id, customer_id,
       max(case when `key` = 'first_name' then value end) as first_name,
       max(case when `key` = 'last_name' then value end) as last_name
from b cross join
     (select @rn := 0) params
group by customer_id;

我不确定将使用哪个表a,可能用于过滤客户ID。

答案 1 :(得分:0)

使用Group_concat或Group by

Select *,Group_concat(value) as full_name
From b left join a on b.customer_id=a.customer_id
Group by customer_id

答案 2 :(得分:0)

鉴于您无法改变表结构,一种方法是使用customer_idkey上的子选择:

SELECT
  tableA.id,
  tableA.customer_id,
  (
     SELECT 
        tableB.`value`
     FROM tableB 
     WHERE tableB.customer_id = tableA.customer_id 
       AND tableB.`key` = 'first_name'
  ) AS first_name,
  (
     SELECT 
        tableB.`value`
     FROM tableB 
     WHERE tableB.customer_id = tableA.customer_id 
       AND tableB.`key` = 'last_name'
   ) AS last_name
FROM tableA

注意:此查询的性能方面可能很糟糕。但是,如果你没有选择,那么缓慢的查询可能会驱使做出决定的人允许更改结构。

答案 3 :(得分:0)

这将做你想要的:

SELECT A.customer_id, B.value, B_1.value
FROM (A INNER JOIN B ON A.customer_id = B.customer_id) 
INNER JOIN B AS B_1 ON B.customer_id = B_1.customer_id
WHERE (((B.key)="first_name") AND ((B_1.key)="last_name"));