限制固定数量类别的固定行数

时间:2012-09-21 07:59:31

标签: mysql

为了简单起见,我将留下与问题无关的字段。

我的表结构是,

新闻

news_id | parent_category | child_category

类别

category_id | maincategory_name

子类

subcategory_id | subcategory_name

已经很明显,category_idparent_id相关联,subcategory_idchild_category表的news相关联。


我现在拥有的

SELECT * 
 FROM (

       SELECT news . * , @rn := 
       CASE WHEN @child_category = child_category
       THEN @rn +1
       ELSE 1 
       END AS rn, @child_category := child_category
       FROM news, (

                   SELECT @rn :=0, @child_category := NULL
                   ) AS vars
                       ORDER BY child_category
                   ) AS T1

                        LEFT JOIN category ON parent_category = category.category_id
                        LEFT JOIN subcategory ON child_category =  
                        subcategory.subcategory_id
                        WHERE rn <=12 AND parent_category = (SELECT category_id FROM 
                        category WHERE maincategory_name='ukraine') AND 
                        child_category!= (SELECT `subcategory_id` FROM subcategory 
                        WHERE `subcategory_name` = 'kiev')
                        ORDER BY category.category_id DESC

上面的sql工作并从每个类别中提取12行。

问题 我现在面临的问题是,查询从每个类别中获取数据。我想将此类别编号限制为2或3,例如如果subcategory表中有8个子类别,它将从所有子类中获取数据。我想将获取限制为限制,例如3(任何3个类别)。

我尝试使用IN语句,如下所示,

SELECT * 
     FROM (

       SELECT news . * , @rn := 
       CASE WHEN @child_category = child_category
       THEN @rn +1
       ELSE 1 
       END AS rn, @child_category := child_category
       FROM news, (

                   SELECT @rn :=0, @child_category := NULL
                   ) AS vars
                       ORDER BY child_category
                   ) AS T1

                        LEFT JOIN category ON parent_category = category.category_id
                        LEFT JOIN subcategory ON child_category =  
                        subcategory.subcategory_id
                        WHERE rn <=12 AND parent_category = (SELECT category_id FROM 
                        category WHERE maincategory_name='ukraine') AND 
                        child_category IN (2,4)
                        ORDER BY category.category_id DESC

其中IN range将由子查询检索。在逻辑上,如果我将该子查询限制为3个结果,我的工作就完成了。但事实证明,IN语句不支持子查询中的LIMIT子句。

所以问题是,从数量有限的类别中检索数据(已修复但我已经弄清楚)的解决方法是什么。


sameple数据

新闻表

| news_id | parent_category | child_category
|   1     |       1         |     1
|   2     |       1         |     2

类别表

| category_id | maincategory_name
|      1      |      Ukraine
|      2      |      Russia
|      3      |      Belarus

子类别表

| subcategory_id | subcategory_name
|        1       |     Kiev
|        2       |     Odessa
|        3       |     Moscow
|        4       |     Simferopol
|        5       |     Dnipropetrovsk

结果应该像这样......

假设基辅,敖德萨,辛菲罗波尔和第聂伯罗彼得罗夫斯克进入maincategory 1即乌克兰,我想要2个类别不包括基辅(即结果应该包含 simferopol Dnipro Odessa Dnipro Odessa simferopol

问题是,查询将获取所有3个类别(或更多,如果可用),其中我只想要2(或有时3)。

更多信息


sql fiddle

create table News(news_id int, parent_category int, child_category int);
insert into News values (1,1,1), (2,1,2), (3,1,2), (4,1,4),(5,1,4), (6,1,5), (7,2,3), (8,1,5), (9,1,2);
create table Category(category_id int, maincategory_name varchar(100));
insert into Category values (1, 'Ukraine'), (2, 'Russia'), (3, 'Belarus');
create table Subcategory (subcategory_id int, subcategory_name varchar(100));
insert into Subcategory values (1, 'Kiev'), (2, 'Odessa'), (3, 'Moscow'), (4, 'Simferopol'), (5, 'Dinipro');

示例数据

enter image description here

目标

从上面的结果我想实现以下目标:

  • 仅从一个主要类别(即乌克兰,取消俄罗斯)获取结果,但可以轻松完成,因此不必担心该部分。

  • 仅获取2个子类别(上面的集合包含3个子类别。敖德萨,辛菲罗波尔和第聂伯罗。我只想要其中任何两个)。我可以对其进行硬编码以进行检索,但我也会在其他地方使用相同的查询,因此硬编码会破坏这一目的。

  • 从上面提到的上述2个子类别中,每个子类别最多可以获得5行。 (我在问题的第一个查询中实现了这一点。)

从2个以上的要求,我没有达到。 1而不是。我被困的地方是2号。 从结果集中,我无法获取仅包含2个子类别的结果。 和结果集输出数据包含所有可用的类别。 (这里只有3个子类别,所以结果包含所有3.如果有10个subcat,它将检索所有10个subcat数据)。我现在希望现在更清楚了。

1 个答案:

答案 0 :(得分:0)

恐怕我可能仍然没有得到你想要的东西。为什么不简单地使用GROUP BY

/* SELECT * FROM ( */
SELECT 
n.news_id,
c.maincategory_name,
sc.subcategory_name
FROM
News n
INNER JOIN Category c ON n.parent_category = c.category_id
INNER JOIN Subcategory sc ON n.child_category = sc.subcategory_id
WHERE maincategory_name = 'Ukraine'
GROUP BY maincategory_name, subcategory_name
ORDER BY RAND()
LIMIT 2
/* )q1 INNER JOIN with_whatever ON q1.news_id = with_whatever.Id */

with_whatever包含您想要获取的数据“应从每个子类别中获取最多5行”。您的示例数据仍然没有反映出来。这就是为什么我不确定,如果这是你要求的。