获取MySQL结果,其中每个第N行都是必需项

时间:2015-06-17 14:37:51

标签: mysql

我有一个mysql查询问题,如果可能的话。

示例:我们有产品表,每个产品都有字段类型,可以是“免费”或“黄金”。当我们按关键字搜索所有产品时,我们会得到像

这样的结果
id | product_name | ... | type
---+--------------+-----+-----
1  | ...          | ... | free
2  | ...          | ... | gold
3  | ...          | ... | free
4  | ...          | ... | free
5  | ...          | ... | free
6  | ...          | ... | gold
7  | ...          | ... | free
8  | ...          | ... | free
9  | ...          | ... | gold
10 | ...          | ... | free
11 | ...          | ... | gold
12 | ...          | ... | free
13 | ...          | ... | free
14 | ...          | ... | gold
15 | ...          | ... | free
16 | ...          | ... | gold
17 | ...          | ... | free
18 | ...          | ... | free
19 | ...          | ... | free

问题是:如何订购此结果以获得每个第4行类型“gold”

id | product_name | ... | type
---+--------------+-----+-----
1  | ...          | ... | free
3  | ...          | ... | free
4  | ...          | ... | free
2  | ...          | ... | gold
5  | ...          | ... | free
7  | ...          | ... | free
8  | ...          | ... | free
6  | ...          | ... | gold
10 | ...          | ... | free
12 | ...          | ... | free
13 | ...          | ... | free
9  | ...          | ... | gold
15 | ...          | ... | free
17 | ...          | ... | free
18 | ...          | ... | free
11 | ...          | ... | gold
19 | ...          | ... | free
14 | ...          | ... | gold
16 | ...          | ... | gold

我不知道如何解决它。有可能吗?

我知道如何用PHP解决它,但我需要知道我是否可以用MySQL查询来解决它!

2 个答案:

答案 0 :(得分:2)

您可以使用以下查询:

SELECT id, product_name, type, r
FROM ( 
SELECT id, product_name, type,  
       IF((@r1+1) % 4 = 0, @r1:= @r1 + 2, @r1:= @r1 + 1) AS r
FROM mytable, (SELECT @r1:=0) AS var
WHERE type <> 'gold'
ORDER BY id ) t


UNION ALL

SELECT id, product_name, type,  r*4 AS r
FROM (
SELECT id, product_name, type,  
       @r2:= @r2+1 AS r
FROM mytable, (SELECT @r2:=0) AS var
WHERE type = 'gold' ) s
ORDER BY r

<强>解释

  • UNION的第一部分检索所有非金币&#39;记录并将r值等于1,2,3,5,6,7,9,..
  • 第二部分检索所有&#39; gold&#39;记录并将r值等于4,8,12,...
  • ORDER BY r已应用于UNION ALL的整套回复,并执行所需的排序。

Demo here

答案 1 :(得分:2)

如果你想要&#34;黄金&#34;在每四行,然后列举&#34; gold&#34;并列举其他一切。然后,您可以将结果组合起来并使用算术来获得&#34; gold&#34;在第四排:

select t.*
from ((select t.*, (@rng := @rng + 1) as rn
       from table t cross join
            (select @rng := 0) params
       where type = 'gold'
      ) union all
      (select t.*, (@rn := @rn + 1)
       from table t cross join
            (select @rn := 0) params
       where type <> 'gold'
      )
     ) t
order by (case when type = 'gold' then rn
               else 1 + floor((rn - 1) / 3)
          end),             -- get groups of 3 non-gold and 1 gold
         (type = 'gold') ,  -- put the gold last in the group
         id                 -- order the rest by id