一对多 SQL SELECT 到单行
Posted
技术标签:
【中文标题】一对多 SQL SELECT 到单行【英文标题】:One-to-Many SQL SELECT into single row 【发布时间】:2012-07-11 13:57:43 【问题描述】:我有两个表中的数据。
第一个表有一个名为 PKID 的主键
PKID DATA
0 myData0
1 myData1
2 myData2
第二个表将表 1 中的 PKID 列作为外键
PKID_FROM_TABLE_1 U_DATA
0 unique0
0 unique1
0 unique2
1 unique3
1 unique4
1 unique5
2 unique6
2 unique7
2 unique8
我现在做的基本 SELECT 语句是
SELECT a.PKID, a.DATA, b.U_DATA
FROM table1 as a
INNER JOIN table2 as b
ON a.PKID = b.PKID_FROM_TABLE_1
这会产生一个像这样的表格:
PKID DATA U_DATA
0 myData0 unique0
0 myData0 unique1
0 myData0 unique2
1 myData1 unique3
1 myData1 unique4
1 myData1 unique5
2 myData2 unique6
2 myData2 unique7
2 myData2 unique8
我想要的是下表:
PKID DATA U_DATA1 U_DATA2 U_DATA3
0 myData0 unique0 unidque1 unique2
1 myData1 unique3 unidque4 unique5
2 myData2 unique6 unidque7 unique8
如果有帮助,每个 PKID 将在 table2 中恰好有 3 个条目。
这样的事情在 mysql 中是否可行?
【问题讨论】:
见***.com/questions/7674786/mysql-pivot-table Join two tables (with a 1-M relationship) where the second table needs to be 'flattened' into one row的可能重复 【参考方案1】:这是获得结果的一种方式。
此方法使用相关子查询。每个子查询使用ORDER BY
子句对table2 中的相关行进行排序,并使用LIMIT
子句检索第一、第二和第三行。
SELECT a.PKID
, a.DATA
, (SELECT b1.U_DATA FROM table2 b1
WHERE b1.PKID_FROM_TABLE_1 = a.PKID
ORDER BY b1.U_DATA LIMIT 0,1
) AS U_DATA1
, (SELECT b2.U_DATA FROM table2 b2
WHERE b2.PKID_FROM_TABLE_1 = a.PKID
ORDER BY b2.U_DATA LIMIT 1,1
) AS U_DATA2
, (SELECT b3.U_DATA FROM table2 b3
WHERE b3.PKID_FROM_TABLE_1 = a.PKID
ORDER BY b3.U_DATA LIMIT 2,1
) AS U_DATA3
FROM table1 a
ORDER BY a.PKID
跟进
@gliese581g 指出这种方法可能存在性能问题,外部查询返回大量行,因为 SELECT 列表中的每个子查询都会针对外部查询中返回的每一行执行。
不用说,这种方法需要索引:
ON table2 (PKID_FROM_TABLE_1, U_DATA)
-或者,至少-
ON table2 (PKID_FROM_TABLE_1)
如果定义了外键,则很可能后一个索引已经存在。前一个索引将允许完全从索引页面满足查询(“使用索引”),而不需要排序操作(“使用文件排序”)。
@glies581g 非常正确地指出,这种方法的性能在“大型”集合上可能会出现问题。
【讨论】:
是否可以对动态数量的 U_DATA 执行此操作...例如,我的基本(高级)想法是这样的... b(x).U_data LIMIT x,1 如果有大量记录会不会太慢? @gliese581g:这个查询是否“太慢”真的取决于需求。您正确地指出 table1 中的“大量”行将意味着选择列表中的子查询将执行“大量”次(对于从 table1 返回的每一行执行一次)。我提供的查询不是唯一的方法,也不一定是最有效的。但是这个查询的性能是否被衡量为“太慢”,这实际上取决于性能要求。太【参考方案2】:根据您的 MySQL 版本,您可以查看 GROUP_CONCAT
【讨论】:
这实际上是最干净的解决方案,因为它不需要您知道在“多”方面您将拥有多少列表成员。用法:SELECT a.PKID ,GROUP_CONCAT(b.U_DATA) FROM a join b on a.PKID_FROM_TABLE_1 = a.PKID GROUP BY a.PKID;
SELECT requests.id,GROUP_CONCAT(membership_types.name_af) 根据需要 FROM requests join request_membership_types_pivot on request_membership_types_pivot.request_id = requests.id join members_types on request_membership_types_pivot.membership_type_id = members_types.id GROUP BY requests.id;
以上是关于一对多 SQL SELECT 到单行的主要内容,如果未能解决你的问题,请参考以下文章