【问题标题】:How can you update a table with an ascending order position based on different groups in MYSQL?如何根据 MYSQL 中的不同组更新具有升序位置的表?
【发布时间】:2019-04-14 13:49:21
【问题描述】:

我正在为这个复杂的查询而苦苦挣扎。我正在尝试插入某些产品的订单位置。 例如, 我目前有一个位置为 NULL 的表 1,我想对每个产品 ID 进行分组,并根据 ProductID 组为每个尺寸分配一个菜单位置,并使用这个 FIND_IN_SET:

FIND_IN_SET(size,"UNI,XS,S,M,L,XL,XXL,3XL,4XL,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60") asc;

换句话说,我希望它看起来像 Table2。

表1

ID   |   ProductID   |   Size   |   Menu_position
1    |      100      |    S     |   NULL
2    |      100      |    M     |   NULL
3    |      100      |    L     |   NULL
4    |      101      |    40    |   NULL
5    |      101      |    41    |   NULL
6    |      101      |    42    |   NULL
7    |      102      |    XS    |   NULL
8    |      102      |    L     |   NULL

表2

ID   |   ProductID   |   Size   |   Menu_position
1    |      100      |    S     |   1
2    |      100      |    M     |   2
3    |      100      |    L     |   3
4    |      101      |    40    |   1
5    |      101      |    41    |   2
6    |      101      |    42    |   3
7    |      102      |    XS    |   1
8    |      102      |    L     |   2

到目前为止我收集的内容:

产品组数:select count(distinct ProductID) from Table1

按特定顺序排序大小: SELECT * FROM Table1 ORDER BY FIND_IN_SET(size,"UNI,XS,S,M,L,XL,XXL,3XL,4XL,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60") asc;

【问题讨论】:

  • 分配这样的菜单位置背后的逻辑是什么?
  • 产品 ID 的菜单位置是否必须升序?例如,如果产品只有尺寸“S”和“L”,菜单位置应该是 1 和 2,还是 1 和 3 的位置可以?
  • 您可以将您的尺寸和菜单位置值(整数)放入一个表格并加入该表格以获取每种尺寸的菜单位置。
  • @rd_nielsen 是的,菜单必须按时间顺序 1 和 2,不能跳过。这就是为什么我不能硬分配每个值。
  • @vivek_23 用于下拉菜单

标签: mysql sql if-statement while-loop


【解决方案1】:

您可以在 MySQL 8.0 之前使用变量:

SELECT t1.*,
       (@rn := if(@p = productid, @rn + 1,
                  if(@p := productid, 1, 1)
                 )
       ) as menu_position
FROM (SELECT t1.*
      FROM Table1 t1
      ORDER BY ProductId,
               FIND_IN_SET(size, 'UNI,XS,S,M,L,XL,XXL,3XL,4XL,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60') asc
     ) AS alias CROSS JOIN
     (SELECT @p := -1, @rn := 0) params;

在 MySQL 8+ 中,这要简单得多:

select t1.*,
       row_number() over (partition by productid order by FIND_IN_SET(size, 'UNI,XS,S,M,L,XL,XXL,3XL,4XL,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60')) as menu_position
from table1 t1

【讨论】:

  • 你们是畜生!非常感谢你,希望有一天能达到你的水平!
  • 有没有办法可以将其添加为视图?我不断收到错误 1351:视图的 SELECT 包含变量或参数 SQL 语句:CREATE OR REPLACE ALGORITHM = UNDEFINED
  • @Beck。 . .没有一种简单的方法可以将其添加到视图中。这是可能的,但并不值得付出努力,因为视图必须使用相关的子查询并且成本很高。
  • 谢谢,我设法将它放入商店产品并制作了一个临时表。
【解决方案2】:

创建一个包含所有Size 值在一列中和这些大小的整数顺序在第二列中的双列表——将该表称为menu_pos。将此添加到您的Table 大小,以生成包含product_idsizemenu_pos 列的表或视图(称为product_pos)。然后使用窗口函数修改menu_pos的值,确保它们是严格顺序的,例如:

select
    product_id,
    size,
    rank() over (partition by product_id order by menu_pos) as new_menu_pos
from
    product_pos;

窗口函数需要 MySQL 8。

【讨论】:

  • 这行不通。我们无法创建新表,因为我们无法修复菜单位置。对于特定数据集,它可能是 1,对于另一个数据集可能是 2,等等。
  • 附件表只需要整数是升序的,不需要顺序的。窗口函数将确保数字是连续的。
  • @rd_nielsen 请标记。 the integer order of those sizes in the second column 是什么意思?如果窗口函数确保它的顺序,为什么要在数据库中创建一个单独的表?我认为我们可以拥有同一个表,但名称不同,并且管理这些大小的整数顺序作为它们的 id 本身(因为它无论如何都会按升序排列)。
  • @vivek_23 “按这些大小的整数顺序,”我的意思是如果“S”要在“M”之前排序,那么分配给“S”和“M”的整数应该反映该顺序——也就是说,“S”的整数小于“M”的整数。如果你为这些信息创建一个单独的表,那么你的数据都在数据库中,而不是部分在数据库中,部分在你的接口代码中。
  • @vivek_23 因为“L”和“40”用于不同的产品 ID。使用附件表,Table1 根本不需要Menu_position 列。尺寸标签和菜单位置排序整数的辅助表将只有很少的行,但完成相同的目的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多