繁体   English   中英

如何按联接表的行(而非列)中的值对mysql查询结果排序?

[英]How do I order mysql query results by values from a joined table's rows (not columns)?

我有一个表items和一个表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"

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

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

在项目结果中,我希望该item所有item_parameters都包括order by子句中未使用的parameters

该查询仍在进行中,因为我还没有返回每个item所有item_parameters

 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

您可以加入参数表以获取名称,以防万一它们发生更改,但这为您提供了一个轮廓。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM