我们有几个表,需要根据 user_id 从中提取数据。一切都很好,除了现在我们已经将地址分开,并且每个用户可以有多个物理地址位置(最多 3 个)。我们需要将这些地址中的每一个标识为a1、a2、a3,知道a2和a3是可选的并且可能为空。
这是地址表架构:
$sql[] = "CREATE TABLE {$modules->tables->members_addresses} (
id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id bigint(20) NOT NULL,
mailing tinyint(1) DEFAULT 0 NOT NULL,
public tinyint(1) DEFAULT 0 NOT NULL,
address varchar(255) NOT NULL,
city varchar(255) NOT NULL,
region_id bigint(20) NOT NULL,
country_id bigint(20) NOT NULL,
postalcode varchar(200) NOT NULL,
date_created datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
date_updated datetime DEFAULT '0000-00-00 00:00:00' NOT NULL
) {$modules->tables->charset_collate};";
这是我到目前为止的查询 SQL。它的问题是我为每个位置得到一个单独的结果(即,它不是将 a1-a3 包装到一个查询结果中,而是给我单独的查询结果):
SELECT p.*, concat( u1.meta_value, ' ', u2.meta_value ) as fullname, u1.meta_value as first_name, u2.meta_value as last_name, a.address, a.city, a.postalcode, case when p.certifications = '' then roles.name else concat( roles.name, ',', p.certifications ) end as certification, case when r.name is null then c.name else concat( r.name, ', ', c.name ) end as location, case when r.name is null then '' else r.name end as region, case when c.name is null then '' else c.name end as country
FROM modules_profiles p
LEFT JOIN moonlight_usermeta u1 ON p.user_id = u1.user_id AND u1.meta_key = 'first_name'
LEFT JOIN moonlight_usermeta u2 ON p.user_id = u2.user_id AND u2.meta_key = 'last_name'
LEFT JOIN modules_members_addresses a ON p.user_id = a.user_id LEFT JOIN modules_roles roles ON roles.slug = p.certification
LEFT JOIN modules_regions r ON r.id = a.region_id LEFT JOIN modules_countries c ON c.id = a.country_id
WHERE p.user_id IN ( 1 )
ORDER BY p.user_id
分离a1、a2、a3的SQL是什么?顺便说一句,我需要 a1.address、a1.city、a1.region、a1.country、a1.postalcode(并重复 a2 和 a3)。
最佳答案
您可以在查询中多次连接同一个表
SELECT u.id, u.name, a1.*, a2.*, a3.*
FROM users AS u
LEFT OUTER JOIN addresses AS a1 ON a1.userId = u.id
LEFT OUTER JOIN addresses AS a2 ON a2.userId = u.id AND a2.id < a1.id
LEFT OUTER JOIN addresses AS a3 ON a3.userId = u.id AND a3.id < a2.id
WHERE u.id = 1 AND a1.id = (SELECT MIN(id) FROM addresses WHERE userId = 1)
a1.id = (SELECT MIN(id) FROM ports WHERE userId = 1)
是为了让您首先获得“第一个”地址。使用 ids 进行排序通常是一个坏主意,因此您可能需要在地址中实现“序列”或“偏好”字段。
关于MySQL - 如何将多个表行分离成一个类似的查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27513476/