mysql order by 来自不同的表打破了排名

标签 mysql sql

我有一个查询,该查询获取文章列表的标签并将其限制为每篇文章的标签数不超过 5 个。这效果非常好。

这是查询:

SET @rank=null, @val=null;
SELECT * FROM (
SELECT r.article_id, c.`category_name`, c.`category_id`, 
@rank := IF( @val = r.article_id, @rank +1, 1 ) AS rank, 
@val := r.article_id
FROM  `article_category_reference` r
INNER JOIN  `articles_categorys` c ON c.category_id = r.category_id
WHERE r.article_id
IN ( 1,2 )
ORDER BY r.`article_id` ASC
) AS a
WHERE rank < 5

但是,我想首先显示特定的标签,其中包含“show_first”0/1 列,并且我希望首先包含它们并进行计数。

我尝试过这样做:

ORDER BY CASE WHEN (c.`show_first` = 1) THEN 0 ELSE 1 END, r.`article_id` ASC

这会破坏排名计数,因此所有标签最终都会显示。

如有任何指点,我们将不胜感激。

表格:

CREATE TABLE `article_category_reference` (
  `ref_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `category_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `article_category_reference`
--
ALTER TABLE `article_category_reference`
  ADD PRIMARY KEY (`ref_id`),
  ADD KEY `category_id` (`category_id`),
  ADD KEY `article_id` (`article_id`);

CREATE TABLE `articles_categorys` (
  `category_id` int(11) NOT NULL,
  `category_name` varchar(32) CHARACTER SET utf8 NOT NULL,
  `quick_nav` tinyint(1) NOT NULL DEFAULT '0',
  `is_genre` tinyint(1) NOT NULL DEFAULT '0',
  `show_first` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

--
-- Indexes for table `articles_categorys`
--
ALTER TABLE `articles_categorys`
  ADD PRIMARY KEY (`category_id`);

-- And some data:

INSERT INTO `articles_categorys` (`category_id`, `category_name`, `quick_nav`, `is_genre`, `show_first`) VALUES
(1, 'one', 1, 0, 0),
(2, 'two', 1, 0, 0),
(3, 'three', 1, 0, 0),
(4, 'four', 0, 0, 0),
(5, 'five', 0, 0, 0),
(6, 'six', 0, 0, 0),
(7, 'seven', 0, 0, 1),
(8, 'eight', 0, 0, 1);

INSERT INTO `article_category_reference` (`ref_id`, `article_id`, `category_id`) VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 1, 4),
(5, 1, 5),
(6, 1, 6),
(7, 1, 7),
(8, 1, 8),
(9, 2, 1),
(10, 2, 2),
(11, 2, 3),
(12, 2, 4),
(13, 2, 5),
(14, 2, 6),
(15, 2, 7),
(16, 2, 8);

了解其工作原理:http://sqlfiddle.com/#!9/1de99/1/0

它不适合我,希望一些总是先显示:http://sqlfiddle.com/#!9/0d36b7/1 (添加第二组似乎破坏了排名系统)

最佳答案

您的问题不在于条件,而在于您创建的排名。

正如您将在我的回答中看到的,我创建了一个内部查询,它将按特定顺序获取该记录并应用准确的排名。

如果您检查内部查询,则会显示所有行都具有相同的排名,这是由于排序问题造成的。

所以我在最里面的查询中添加了 ORDER BY 子句,然后过滤掉 rank1 小于 5 的记录。

SET @rank1=null, @val=null;

SELECT * FROM (
    SELECT a.article_id, a.`category_name`, a.`category_id`, 
           @rank1 := IF( @val = a.article_id, @rank1 +1, 1 ) AS rank1, 
           @val := a.article_id
    FROM (
        SELECT r.article_id, c.`category_name`, c.`category_id`
        FROM  `article_category_reference` r
        INNER JOIN  `articles_categorys` c ON c.category_id = r.category_id
        GROUP BY r.article_id, c.`category_name`, c.`category_id`
        ORDER BY r.`article_id`,CASE WHEN (c.`show_first` = 1) THEN 0 ELSE 1 END ASC
    ) AS a
) Z
WHERE Z.rank1 < 5;

您可以查看here .

关于mysql order by 来自不同的表打破了排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52106069/

相关文章:

mysql - 字符集服务器和mysql的配置文件

sql - 在需要条件的上下文中指定的非 bool 类型表达式,位于 'then' 附近

PHP/MySQL - 递增变量名以循环获取数据

mysql - GROUP BY 多个值给了我所有可能的组合

sql - 在 SQL Server 中查询对话中用户的精确匹配

mysql - 安全散列 SSN 以适合 BIT 列或扩展 BIT 列以适合安全散列?

sql - 尽可能多地从 CLOB 到 VARCHAR2 选择数据,数据中包含多字节字符

mysql - mysql中的累计值

python - mysql 源命令在 docker 容器内什么都不做

mysql - SQL - 检查记录是否存在于多个表中