mysql - 如何按连接表的行(而不是列)中的值对 mysql 查询结果进行排序?

标签 mysql join

我有一张 table items和一张 table parameters 。连接表 item_parameters存储项目的每个可能参数的值,而不是为每个参数使用单独的列。

例如(简化):

parameters:             items:              
id: 1, name: color      id: 1, name: bike
id: 2, name: size       id: 2, name: phone
id: 3, name: weight     id: 3, name: shoe

item_parameters: 
id: 1, item_id: 1, parameter_id: 1, value: "blue"
id: 2, item_id: 1, parameter_id: 2, value: "large"
id: 3, item_id: 1, parameter_id: 3, value: "heavy"
id: 4, item_id: 2, parameter_id: 1, value: "black"
id: 5, item_id: 2, parameter_id: 2, value: "medium"
id: 6, item_id: 2, parameter_id: 3, value: "medium"
id: 7, item_id: 3, parameter_id: 1, value: "white"
id: 8, item_id: 3, parameter_id: 2, value: "small"
id: 9, item_id: 3, parameter_id: 3, value: "light"

如何搜索项目(对特定参数应用过滤器)并根据 value 对结果进行排序特定的parameter对于items

我知道如何使用带有 item_parameters.parameter_id = ? AND item_parameters.value = ? 的 where 子句来应用过滤器部分但对于订购部分,只需添加 ORDER BY item_parameters.value desc仅通过那些 item_parameters.value 似乎不足以订购where item_parameters.parameter_id = ?

在我的项目结果中,我想要所有 item_parameters为此item包括parameters未在 order by 子句中使用。

此查询仍在进行中,因为我尚未让它返回所有 item_parameters对于每个 item :

 SELECT DISTINCT
         `items`.name,
         `parameters`.name,
         `item_parameters`.value
 FROM `items` 
 LEFT OUTER JOIN `item_parameters` ON `item_parameters`.`item_id` = `items`.`id`
 LEFT OUTER JOIN `parameters` ON `item_parameters`.`parameter_id` = `parameters`.`id`
 WHERE (item_parameters.parameter_id = 3 AND item_parameters.value = 'light') 
 ORDER BY item_parameters.value LIMIT 10000;

此外,目前未返回所有 item_parameters,本文上面的相关缺失部分是订单逻辑(伪代码)需要为 ORDER BY items_parameters.value where item_parameters.parameter_id = 1

以下是所需结果的示例,假设来自比上面提供的示例更大的示例数据集:

item name     color       size      weight
cup           brown       small     light
shirt         green       medium    light
candy         pink        large     light
chair         tan         medium    light
paper         white       large     light

请注意,结果均按参数 3(重量)= 光进行过滤,并按参数 1(颜色)排序。

感谢您对此的任何指导。

最佳答案

我不确定这对性能是否最好,但这是我如何逻辑地构建查询的方法。

首先选择所有项目及其参数:

   SELECT i.name, p.name, ip.value
     FROM items i
     JOIN item_parameters ip
       ON ip.item_id = i.id
     JOIN parameters p
       ON p.id = ip.parameter_id

然后确保您只有具有特定参数正确值的项目:

     JOIN item_parameters ip3
       ON ip3.parameter_id = 3
      AND ip3.item_id = i.id
      AND ip3.value = 'light'

然后包含您订购时所依据的参数:

     JOIN item_parameters ip1
       ON ip1.parameter_id = 1
      AND ip1.item_id = i.id

然后添加 ORDER BY:

 ORDER BY ip1.value DESC, i.id, p.id

如果您按可能不存在的参数进行排序,则必须 LEFT JOIN 到该参数并选择将结果 NULL 值放置在何处。

这也不会像示例结果中所示那样对表格进行透视,但会将项目很好地分组在一起。

如果您希望拥有数据透视表,您可能需要单独连接所有参数,类似于上面的 1 和 3。您可以手动执行此操作,也可以通过从预期/必需参数列表动态构建查询来执行此操作。

更新

对于显示的透视结果,需要进行一些硬编码:

  SELECT i.name, color.value color, size.value size, weight.value weight
    FROM items i
    JOIN item_parameters color
      ON color.parameter_id = 1
     AND color.item_id = i.id
    JOIN item_parameters size
      ON size.parameter_id = 2
     AND size.item_id = i.id
    JOIN item_parameters weight
      ON weight.parameter_id = 3
     AND weight.item_id = i.id
   WHERE weight.value = 'light'
ORDER BY color.value DESC

您也可以加入参数表来获取名称,以防万一它们发生变化,但这会给您一个大纲。

这种方法的缺点是每次添加新参数时都必须更新查询。

我个人更喜欢分组样式的方法,可以使用应用程序代码生成数据透视表。

关于mysql - 如何按连接表的行(而不是列)中的值对 mysql 查询结果进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33941563/

相关文章:

php - 避免电子商务网站中的产品重复

mysql - 如何统计不同用户,获取用户的MaxDate和最新记录的UserId

mysql - 修改查询以获取值相对于列值的百分比

python - 选择具有非零值且在 pandas 中共享索引且无循环的列

mysql - 替代包含 max() 和 GROUP BY 的自连接以提高性能

mysql - MySQL 中的关系型数据库

php - max_allowed_pa​​cket 和文件上传问题

MySql 显示不在第二个表中的值

Java:使用分隔符连接基元数组

mysql - 使用 case 语句从 SELECT 更新记录。 (mysql)