Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 从查询中的子表中获取连接行的更好方法是什么?_Mysql_Database_Join - Fatal编程技术网

Mysql 从查询中的子表中获取连接行的更好方法是什么?

Mysql 从查询中的子表中获取连接行的更好方法是什么?,mysql,database,join,Mysql,Database,Join,对于我的大学项目,我正在做一个学习型电子商务网站。我一直在寻找类似的问题,但我无法获得更深入的想法 我当前的表格结构: 产品-sku(主键)、名称、价格、其他_列 ProductMedia-路径(唯一)、产品库存单位(来自产品表) 路径包含媒体的文件名 当我检索产品数据时,我从table:products和LEFT中选择列,然后连接productMedia和GROUP_CONCAT并获取路径 查询: SELECT p.*, // for simplicity mentioned as * (GR

对于我的大学项目,我正在做一个学习型电子商务网站。我一直在寻找类似的问题,但我无法获得更深入的想法

我当前的表格结构:

  • 产品-sku(主键)、名称、价格、其他_列
  • ProductMedia-路径(唯一)、产品库存单位(来自产品表)
  • 路径包含媒体的文件名

    当我检索产品数据时,我从table:products和LEFT中选择列,然后连接productMedia和GROUP_CONCAT并获取路径

    查询:

    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
    
    要显示,我将分解产品图像,并循环显示或将其用于其他目的

    现在我的问题是:

  • 这是有效的方法吗?还是我不知道的更好的方法
  • 当需要从子表(此处为productMedia)连接多个列时,我会多次将
    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 ',')