繁体   English   中英

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

[英]Linking multiple rows from table B to one row in table A in 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中的数据进行选择?

一种方法是条件聚合:

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。

使用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

鉴于您无法更改表结构,一种方法是在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

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

这将做你想要的:

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"));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM