Laravel Eloquent 按字段排序为 1,2,3,4,1,2,3,4
Posted
技术标签:
【中文标题】Laravel Eloquent 按字段排序为 1,2,3,4,1,2,3,4【英文标题】:Laravel Eloquent order by field as 1,2,3,4,1,2,3,4 【发布时间】:2020-09-05 10:13:42 【问题描述】:我有商品表
good_link, parent_link, name
sdf-sdfg ffff rock
utyruuur ffff qwe
gfhdfggg dddd paper
sdfghvcx eeee water
ncvbcxvb dddd tree
dsgfdsg zzzz sdff
sdfsdff zzzz fdgdf
sdfgdgg zzzz sdfsdf
dsvfdgg zzzz ssdfgr
brtyfgh zzzz fgdfgdf
如何通过 parent_link 订购数据以获得类似的数据
ffff
dddd
eeee
zzzz
ffff
dddd
zzzz
zzzz
zzzz
zzzz
所以所有的货物都是一个接一个,但总是有不同的 parent_link(上一行 parent_link != 下一行 parent_link,排序 A-Z 没有区别)?
【问题讨论】:
到目前为止你有什么尝试? 事实上没有。 ->groupBy('parent_link') 当然像我需要的那样工作,但它不是一个变体我不明白我应该如何开始 下一个 parent_link 应该与上一个不同 我认为您应该添加更多上下文,解释您为什么需要它,因为有了可用的元素,这个问题没有任何意义。您需要按相同的 parent_link 对元素进行分组,还是需要将它们分开?它们应该如何分开,它们不能是顺序的,但除此之外它们可以按任何顺序排列,或者应该用某种逻辑分开? @gbalduzzi,我不想分组。我只想要排序元素,其中每个下一个 parent_link != 上一个 parent_link。 【参考方案1】:在mysql 5.x
您使用用户定义的变量为不同的 parentid 添加行号。
首先,您必须按 parentid 对它们进行排序,如果您有更多行并且想要 parentid 的另一个顺序,您可以在 ORDER BY 中添加另一列。
每一个相同的parentid得到不同的rownumber,从0开始,随着parentid相同的每一行递增,最后就是按照这些rownumber对它们进行排序。
CREATE TABLE goods ( `good_link` VARCHAR(31), `parent_link` VARCHAR(31), `name` VARCHAR(31) ); INSERT INTO goods (`good_link`, `parent_link`, `name`) VALUES ('sdf-sdfg', 'ffff', 'rock'), ('utyruuur', 'ffff', 'qwe'), ('gfhdfggg', 'dddd', 'paper'), ('sdfghvcx', 'eeee', 'water'), ('ncvbcxvb', 'dddd', 'tree'), ('dsgfdsg', 'zzzz', 'sdff'), ('sdfsdff', 'zzzz', 'fdgdf'), ('sdfgdgg', 'zzzz', 'sdfsdf'), ('dsvfdgg', 'zzzz', 'ssdfgr'), ('brtyfgh', 'zzzz', 'fgdfgdf');
好链接 |父链接 |姓名 :-------- | :------------ | :------ gfhdfgg | dddd |纸 sdfghvcx | eeee |水 sdf-sdfg | ffff |岩石 dsgfdsg | zzzz | sdf ncvbcxvb | dddd |树 乌特鲁乌尔 | ffff | qwe sdfsdff | zzzz | fdgdf sdfgdgg | zzzz | sdfsdf dsvfdgg | zzzz | ssdfgr brtyfgh | zzzz | fgdfgdfSELECT `good_link`, `parent_link`, `name` FROM (SELECT `good_link`, IF(@parentid = `parent_link`,@rn := @rn +1,@rn := 0) rn, `name`, @parentid := `parent_link` 'parent_link' FROM (SELECT * FROM goods ORDER BY parent_link) t1, (SELECT @rn :=0) t2, (SELECT @parentid :='') t3) ta ORDER BY rn;
db小提琴here
【讨论】:
在生产中它为每个请求生成新订单...看起来不错,但对我不起作用:)【参考方案2】:对于 mysql 8+ 使用简单
WITH cte AS ( SELECT good_link,
parent_link,
name,
ROW_NUMBER() OVER (PARTITION BY parent_link) AS rn -- may add any ORDER BY
FROM source_table )
SELECT good_link,
parent_link,
name
FROM cte
ORDER BY rn -- may add any additional expression
对于 MySQL 5+,使用 ROW_NUMBER() 模拟,例如,基于用户定义的变量。
【讨论】:
看起来不错,但尝试添加限制 2 偏移量 4 就像这里 dbfiddle.uk/…【参考方案3】:此代码在 mysql db 上测试。
如果您有 ONLY_FULL_GROUP_BY,则必须禁用它...
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))
然后创建一个存储过程来制作你想要的顺序:
CREATE PROCEDURE custom_order()
BEGIN
SET @restCount := 1;
CREATE TEMPORARY TABLE IF NOT EXISTS my_result_table
SELECT * FROM goods group by parent_link order by parent_link;
CREATE TEMPORARY TABLE IF NOT EXISTS my_temp_table
SELECT * FROM goods;
WHILE @restCount >0 DO
DELETE FROM my_temp_table where (name in (SELECT name FROM my_result_table));
INSERT into my_result_table(good_link,parent_link,name) select good_link,parent_link,name FROM my_temp_table group by parent_link order by parent_link;
set @restCount=(SELECT COUNT(*) FROM my_temp_table);
END WHILE;
SELECT * FROM my_result_table;
END
那么你可以随意调用它......
基本思想是制作两个临时表,一个保存结果,另一个删除移动的排序行, 每个 while 循环...不同的有序行将从临时移动到结果表。
请注意,在将“名称”列视为唯一主键时,您可以将其更改为合适的主键。 您也可以将要排序的表名和列名作为参数传递给存储过程...
我在我的数据库中创建了一个表格,将其命名为“商品”并插入了您提供的确切数据。 如果有帮助,请告诉我
【讨论】:
以上是关于Laravel Eloquent 按字段排序为 1,2,3,4,1,2,3,4的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 6.0 Eloquent - 按日期和状态排序