Mysql自定义排序

Mysql自定义排序,mysql,Mysql,我有一个包含不同类别的数据库表,其中包含不同的产品,每个类别都有一些优先级。假设cat-1有五种产品,cat-2包含三种产品,cat-3包含三种产品,cat-4包含两种产品 展示产品时,顺序应如下所示 1,6,2,7,3,8,4,5,9,10,11,12,13 SELECT * FROM `products` WHERE `id` IN ( 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 ) ORDER BY FIELD( id,

我有一个包含不同类别的数据库表,其中包含不同的产品,每个类别都有一些优先级。假设cat-1有五种产品,cat-2包含三种产品,cat-3包含三种产品,cat-4包含两种产品

展示产品时,顺序应如下所示

  1,6,2,7,3,8,4,5,9,10,11,12,13
 SELECT * 
 FROM  `products` 
 WHERE  `id` 
 IN ( 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 ) 
 ORDER BY FIELD( id, 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 );
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`sl_no` int(11) NOT NULL,
 PRIMARY KEY (`id`)
);

INSERT INTO `products` (`id`, `category_id`, `name`, `sl_no`) VALUES
(1, 1, 'c1p1', 1),
(2, 1, 'c1p2', 2),
(3, 1, 'c1p3', 3),
(4, 1, 'c1p4', 4),
(5, 1, 'c1p5', 5),
(6, 2, 'c2p1', 1),
(7, 2, 'c2p2', 2),
(8, 2, 'c2p3', 3),
(9, 3, 'c3p1', 1),
(10, 3, 'c3p2', 2),
(11, 3, 'c3p3', 3),
(12, 4, 'c4p1', 1),
(13, 4, 'c4p2', 2);
如果类别具有相同的优先级(假设cat-1、cat-2优先级=1、cat-3优先级=2、cat-4优先级=NULL),则产品将显示如下

array(
(int) 1 => array(
    (int) 0 => array(
        (int) 0 => '1',
        (int) 1 => '6'
    ),
    (int) 1 => array(
        (int) 0 => '2',
        (int) 1 => '7'
    ),
    (int) 2 => array(
        (int) 0 => '3',
        (int) 1 => '8'
    ),
    (int) 3 => array(
        (int) 0 => '4'
    ),
    (int) 4 => array(
        (int) 0 => '5'
    ),
),  
(int) 2 => array(
    (int) 0 => array(
        (int) 0 => '9'
    ),
    (int) 1 => array(
        (int) 0 => '10'
    ),
    (int) 2 => array(
        (int) 0 => '11'
    ),      
),
'' => array(
    (int) 0 => array(
        (int) 0 => '12'         
    ),
    (int) 1 => array(
        (int) 0 => '13'

    )
)
)
c1p1、c2p1、c1p2、c2p2、c1p3、c2p3、c1p4、c1p5、c3p1、c3p2、c3p3、c4p1、c4p2

如果类别具有相同的优先级(假设cat-1、cat-2优先级=1、cat-3和cat-4优先级=2),则产品将显示如下

array(
(int) 1 => array(
    (int) 0 => array(
        (int) 0 => '1',
        (int) 1 => '6'
    ),
    (int) 1 => array(
        (int) 0 => '2',
        (int) 1 => '7'
    ),
    (int) 2 => array(
        (int) 0 => '3',
        (int) 1 => '8'
    ),
    (int) 3 => array(
        (int) 0 => '4'
    ),
    (int) 4 => array(
        (int) 0 => '5'
    ),
),  
(int) 2 => array(
    (int) 0 => array(
        (int) 0 => '9'
    ),
    (int) 1 => array(
        (int) 0 => '10'
    ),
    (int) 2 => array(
        (int) 0 => '11'
    ),      
),
'' => array(
    (int) 0 => array(
        (int) 0 => '12'         
    ),
    (int) 1 => array(
        (int) 0 => '13'

    )
)
)
c1p1、c2p1、c1p2、c2p2、c1p3、c2p3、c1p4、c1p5、c3p1、c4p1、c3p2、c4p2、c3p3

如果类别具有不同的优先级(假设cat-1优先级=2、cat-2优先级=1、cat-3优先级=3和cat-4优先级=Null),则产品将显示如下

array(
(int) 1 => array(
    (int) 0 => array(
        (int) 0 => '1',
        (int) 1 => '6'
    ),
    (int) 1 => array(
        (int) 0 => '2',
        (int) 1 => '7'
    ),
    (int) 2 => array(
        (int) 0 => '3',
        (int) 1 => '8'
    ),
    (int) 3 => array(
        (int) 0 => '4'
    ),
    (int) 4 => array(
        (int) 0 => '5'
    ),
),  
(int) 2 => array(
    (int) 0 => array(
        (int) 0 => '9'
    ),
    (int) 1 => array(
        (int) 0 => '10'
    ),
    (int) 2 => array(
        (int) 0 => '11'
    ),      
),
'' => array(
    (int) 0 => array(
        (int) 0 => '12'         
    ),
    (int) 1 => array(
        (int) 0 => '13'

    )
)
)
c2p1、c2p2、c2p3、c1p1、c1p2、c1p3、c1p4、c1p5、c3p1、c3p2、c3p3、c4p1、c4p2

这里c=类别,p=产品

这种排序在Mysql中是可能的。请帮忙

下面是数据库表的结构和示例数据-

   CREATE TABLE IF NOT EXISTS `categories` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `priority` int(11) DEFAULT NULL,
     PRIMARY KEY (`id`)
   ) ;

   INSERT INTO `categories` (`id`, `name`, `priority`) VALUES
   (1, 'c1', 1),
   (2, 'c2', 1),
   (3, 'c3', 2),
   (4, 'c4', NULL);

   CREATE TABLE IF NOT EXISTS `products` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `category_id` int(11) NOT NULL,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
   ) ;

INSERT INTO `products` (`id`, `category_id`, `name`) VALUES
(1, 1, 'c1p1'),
(2, 1, 'c1p2'),
(3, 1, 'c1p3'),
(4, 1, 'c1p4'),
(5, 1, 'c1p5'),
(6, 2, 'c2p1'),
(7, 2, 'c2p2'),
(8, 2, 'c2p3'),
(9, 3, 'c3p1'),
(10, 3, 'c3p2'),
(11, 3, 'c3p3'),
(12, 4, 'c4p1'),
(13, 4, 'c4p2');

您可以创建具有优先级的表:

create table priorities (
  category varchar(255),
  priority int null);
然后,您可以通过以下方式选择产品:

select
  products.*
from
  products inner join priorities
  on products.category = priorities.category
order by
  priorities.priority is null, -- this to put null values at the end
  priorities.priority,
  products.id                  -- or some other field
编辑:这可能就是您正在寻找的:

select
  products.name
from
  products inner join categories
  on products.category_id = categories.id
order by
  categories.priority is null,
  categories.priority,
  substr(products.name,3),
  categories.name

这是一种间接解决方案,用于根据需求获得序列

当我使用PHP获取数据时,首先我编写了一个sql查询来根据优先级获取数据

SELECT `Category`.`id`, `Category`.`name`, `Category`.`priority` , `Product`.`name`, `Product`.`category_id` FROM `categories` AS `Category` INNER JOIN `products` AS `Product` WHERE `Category`.`id` = `Product`.`category_id` ORDER BY CASE WHEN `Category`.`priority` IS NULL THEN 1 ELSE 0 END ASC, `Category`.`priority` ASC;
然后我做了一个简单的数组操作,得到一个数组,如下所示

array(
(int) 1 => array(
    (int) 0 => array(
        (int) 0 => '1',
        (int) 1 => '6'
    ),
    (int) 1 => array(
        (int) 0 => '2',
        (int) 1 => '7'
    ),
    (int) 2 => array(
        (int) 0 => '3',
        (int) 1 => '8'
    ),
    (int) 3 => array(
        (int) 0 => '4'
    ),
    (int) 4 => array(
        (int) 0 => '5'
    ),
),  
(int) 2 => array(
    (int) 0 => array(
        (int) 0 => '9'
    ),
    (int) 1 => array(
        (int) 0 => '10'
    ),
    (int) 2 => array(
        (int) 0 => '11'
    ),      
),
'' => array(
    (int) 0 => array(
        (int) 0 => '12'         
    ),
    (int) 1 => array(
        (int) 0 => '13'

    )
)
)
用于系列c1p1、c2p1、c1p2、c2p2、c1p3、c2p3、c1p4、c1p5、c3p1、c3p2、c3p3、c4p1、c4p2。 其中,数组键是优先级,叶值是产品ID

然后我从上面的数组中生成一个ID字符串,如下所示

  1,6,2,7,3,8,4,5,9,10,11,12,13
 SELECT * 
 FROM  `products` 
 WHERE  `id` 
 IN ( 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 ) 
 ORDER BY FIELD( id, 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 );
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`sl_no` int(11) NOT NULL,
 PRIMARY KEY (`id`)
);

INSERT INTO `products` (`id`, `category_id`, `name`, `sl_no`) VALUES
(1, 1, 'c1p1', 1),
(2, 1, 'c1p2', 2),
(3, 1, 'c1p3', 3),
(4, 1, 'c1p4', 4),
(5, 1, 'c1p5', 5),
(6, 2, 'c2p1', 1),
(7, 2, 'c2p2', 2),
(8, 2, 'c2p3', 3),
(9, 3, 'c3p1', 1),
(10, 3, 'c3p2', 2),
(11, 3, 'c3p3', 3),
(12, 4, 'c4p1', 1),
(13, 4, 'c4p2', 2);
最后编写了如下查询

  1,6,2,7,3,8,4,5,9,10,11,12,13
 SELECT * 
 FROM  `products` 
 WHERE  `id` 
 IN ( 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 ) 
 ORDER BY FIELD( id, 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 );
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`sl_no` int(11) NOT NULL,
 PRIMARY KEY (`id`)
);

INSERT INTO `products` (`id`, `category_id`, `name`, `sl_no`) VALUES
(1, 1, 'c1p1', 1),
(2, 1, 'c1p2', 2),
(3, 1, 'c1p3', 3),
(4, 1, 'c1p4', 4),
(5, 1, 'c1p5', 5),
(6, 2, 'c2p1', 1),
(7, 2, 'c2p2', 2),
(8, 2, 'c2p3', 3),
(9, 3, 'c3p1', 1),
(10, 3, 'c3p2', 2),
(11, 3, 'c3p3', 3),
(12, 4, 'c4p1', 1),
(13, 4, 'c4p2', 2);

最后我找到了一个更好的解决办法。我在products表中添加了一个额外字段。目的是为每一类产品提供一个序列号。我的最终产品表结构如下所示

  1,6,2,7,3,8,4,5,9,10,11,12,13
 SELECT * 
 FROM  `products` 
 WHERE  `id` 
 IN ( 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 ) 
 ORDER BY FIELD( id, 1, 6, 2, 7, 3, 8, 4, 5, 9, 10, 11, 12, 13 );
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`sl_no` int(11) NOT NULL,
 PRIMARY KEY (`id`)
);

INSERT INTO `products` (`id`, `category_id`, `name`, `sl_no`) VALUES
(1, 1, 'c1p1', 1),
(2, 1, 'c1p2', 2),
(3, 1, 'c1p3', 3),
(4, 1, 'c1p4', 4),
(5, 1, 'c1p5', 5),
(6, 2, 'c2p1', 1),
(7, 2, 'c2p2', 2),
(8, 2, 'c2p3', 3),
(9, 3, 'c3p1', 1),
(10, 3, 'c3p2', 2),
(11, 3, 'c3p3', 3),
(12, 4, 'c4p1', 1),
(13, 4, 'c4p2', 2);
这个查询看起来像-

SELECT  `Category`.`id` ,  `Category`.`name` ,  `Category`.`priority` ,    `Product`.`name` ,  `Product`.`category_id` 
FROM  `categories` AS  `Category` 
INNER JOIN  `products` AS  `Product` 
WHERE  `Category`.`id` =  `Product`.`category_id` 
ORDER BY CASE WHEN  `Category`.`priority` IS NULL 
THEN 1 
ELSE 0 
END ASC ,  `Category`.`priority` ASC ,  `Product`.`sl_no` ,  `Product`.`category_id`;

也许您想
按category.priority asc、product.position\u在\u category asc、category.id asc中排序
?您将每个类别的优先级存储在哪里?谢谢Jack。目前我把所有数据都放在同一张表中。字段包括类别id、专业名称和优先级。稍后可以将其扩展为两个表,即类别(cat_id、名称、优先级)和产品(cat_id、pro_名称)。嗨,Jack,我附加了一个新的数据库结构和示例数据。希望这能对你有所帮助。谢谢你的帮助。我已经运行了查询,并且我正在按照以下顺序获得产品(c1p1、c1p2、c1p3、c1p4、c1p5、c2p1….c4p2),但在这里,我希望得到一个序列(c1p1、c2p2、c1p2、c2p2、c1p3、c2p3、c1p4、c1p5、c3p1、c3p2、c3p3、c4p1、c4p2)。序列很重要。@Sitansu不客气!我看到您已经有了一个类别id,所以没有必要使用
LEFT()
,但我认为还不清楚为什么在第一个示例中
c2p2
应该在
c1p2
之前……假设类别1和2具有优先级1,类别3具有优先级2,类别4具有优先级Null。@Sitansu是,但c2p2和c1p2都有不同的类别,但优先级相同,为1,产品为p2,所以我不明白这背后是否有逻辑。抱歉,混淆了。所有的产品都不同。序列不是c1p1,c2p2而是c1p1,c2p1。。。c1p1是类别的一种产品,c2p1是类别的两种产品,依此类推。