mysql从不同的表排序

wyyhbhjk  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(252)

我有一个查询,它获取文章列表的标签,并将每个文章的标签限制在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\u 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/1日期99/1/0
我不想让某些东西总是先出现:http://sqlfiddle.com/#!9/0d36b7/1(加入第二组似乎打破了排名体系)

gpfsuwkq

gpfsuwkq1#

你的问题不在where条件下,而是你正在创建的排名。
正如你将在我的回答中看到的,我已经创建了一个内部查询,它将按照特定的顺序获取记录并应用准确的排名。
如果检查内部查询,就会发现所有行都具有相同的排名,这是由于排序问题造成的。
所以我添加了 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;

你可以在这里查。

相关问题