Mysql 从查询中的子表中获取连接行的更好方法是什么?
对于我的大学项目,我正在做一个学习型电子商务网站。我一直在寻找类似的问题,但我无法获得更深入的想法 我当前的表格结构:Mysql 从查询中的子表中获取连接行的更好方法是什么?,mysql,database,join,Mysql,Database,Join,对于我的大学项目,我正在做一个学习型电子商务网站。我一直在寻找类似的问题,但我无法获得更深入的想法 我当前的表格结构: 产品-sku(主键)、名称、价格、其他_列 ProductMedia-路径(唯一)、产品库存单位(来自产品表) 路径包含媒体的文件名 当我检索产品数据时,我从table:products和LEFT中选择列,然后连接productMedia和GROUP_CONCAT并获取路径 查询: SELECT p.*, // for simplicity mentioned as * (GR
SELECT
p.*, // for simplicity mentioned as *
(GROUP_CONCAT(path SEPARATOR ',') FROM productMedia WHERE product_sku = p.sku) as product_images
FROM products p
WHERE SOME_CONDITION // Single or multiple conditions associated with table products alone
要显示,我将分解产品图像,并循环显示或将其用于其他目的
现在我的问题是:
GROUP\u CONCAT(列分隔符)作为concatenatedColumn
写入,这不会影响性能吗SELECT
p.name, p.sku, p.mrp, p.selling_price,
(GROUP_CONCAT(path SEPARATOR ',') FROM productMedia WHERE product_sku = p.sku) as product_images
FROM products p
WHERE p.category = 'books'
选择
p、 名称、p.sku、p.mrp、p.selling_价格、,
(productMedia中的组_CONCAT(路径分隔符“,”),其中产品_sku=p.sku)作为产品_映像
来自产品p
其中p.售价<1000,p.类别=‘玩具’
我尽量不使用GROUP_CONCAT()来获取您描述的场景中的子行
我会做一个更简单的查询:
SELECT p.*, m.* // really write out the columns, don't use *
FROM products p
LEFT OUTER JOIN productMedia m ON m.product_sku = p.sk
WHERE <conditions on p>
SELECT p.*,m.*//真正写出列,不要使用*
来自产品p
左外连接m.product\U sku=p.sk上的productMedia m
哪里
此查询更易于编写和优化
它确实会为每个p返回可变的行数,因为productMedia中可能有0、1或多个匹配行。p.*
的值将为m
的每个匹配行重复。在获取行时,在应用程序代码中处理这些内容并不困难。形式上(取决于某些条件
此条件必须放置在何处,具有或两者都有-因此,我无法在没有条件说明的情况下将此类通用占位符插入查询中):
如果启用了ONLY\u FULL\u GROUP\u BY
,则会出现错误。此查询对于部分分组是安全的,因此我建议更改此查询的会话SQL模式(所有3个查询必须在同一个连接中执行!最好的方法是在一个多查询语句中执行它们):
如果ProductMedia
中没有匹配的记录,则该产品将为空。如果NULL对您不安全,请改用合并(GROUP_CONCAT(pm.path SEPARATOR','),'')路径
这是有效的方法吗?还是我不知道的更好的方法
是的,它足够有效。当然,您可以为每条记录选择一条路径(并获得大量重复的p.*
字段值)-这将略微减少PHP的工作量,但会增加数据传输和内存使用量。此外,在我的方法中,您不需要按照p.sku
进行额外的输出记录集预排序
当需要从子表(此处为productMedia)连接多个列时,我会多次将GROUP\u CONCAT(列分隔符)作为连接列写入
您可以对每个字段使用两个单独的GROUP_CONCAT,或者将所有内容连接成一个值,如
GROUP_CONCAT(CONCAT_WS(',', field1, field2,...) SEPARATOR ',')
您可以使用相同的分隔符(然后分解并迭代一个数组)和不同的分隔符(然后按记录分解,然后按字段分解每个记录值)
这不会影响性能吗
但是你需要这些数据吗?所以不可能,你必须做
和“性能差异”-与什么进行比较?您能否提供您正在使用的实际代码和一些示例数据,以便更容易掌握您想要在性能方面实现的目标?您缺少了部分查询。是的,我同意。在生产中,我不会使用*。为了让这个问题更容易理解,我把它写成*。
SELECT p.*,
GROUP_CONCAT(pm.path SEPARATOR ',') paths
FROM Products p
LEFT JOIN ProductMedia pm ON p.sku = pm.product_sku
GROUP BY p.sku;
SET @@sql_mode := REPLACE((@old_sql_mode := @@sql_mode), 'ONLY_FULL_GROUP_BY', '');
SELECT p.*,
GROUP_CONCAT(pm.path SEPARATOR ',') paths
FROM Products p
LEFT JOIN ProductMedia pm ON p.sku = pm.product_sku
GROUP BY p.sku;
SET @@sql_mode := @old_sql_mode;
GROUP_CONCAT(CONCAT_WS(',', field1, field2,...) SEPARATOR ',')