我有一张包含性别编码为0和1的人的表格。我需要选择每隔一行作为男/女。我以为我可以通过使用modulo和性别代码0和1以某种方式管理这个,但我还没有设法解决它......
我正在寻找的结果如下:
+-----+--------+-------+ | row | gender | name | +-----+--------+-------+ | 1 | female | Lisa | | 2 | male | Greg | | 3 | female | Mary | | 4 | male | John | | 5 | female | Jenny | +-----+--------+-------+
等
另一种方法是通过合并2个独立的数组在PHP中完成它,但我真的希望它作为SQL查询......
任何建议都表示赞赏!
答案 0 :(得分:2)
选择两个子查询来选择男性和女性。使用排名功能来枚举它们。
Males:
1 | Peter
2 | John
3 | Chris
Females:
1 | Marry
2 | Christina
3 | Kate
然后按x10进行多重播放排名,并为女性添加5。所以你有这个:
Males:
10 | Peter
20 | John
30 | Chris
Females:
15 | Marry
25 | Christina
35 | Kate
然后执行UNION ALL并按新排序顺序/新ID排序。
它应该像这样(伪代码)
SELECT
Name
FROM
(subquery for Males: RANK() AS sortOrd, Name)
UNION ALL
(subquery for Females: RANK()+1 AS SortOrd, Name)
ORDER BY SortOrd
结果应该是这样的:
Males and Females:
10 | Peter
15 | Marry
20 | John
25 | Christina
30 | Chris
35 | Kate
答案 1 :(得分:2)
找到Emulate Row_Number()并为您的案例修改了一下。
set @rownum := 0;
set @pg := -1;
select p.name,
p.gender
from
(
select name,
gender,
@rownum := if(@pg = gender, @rownum+1, 1) as rn,
@pg := gender as pg
from persons
order by gender
) as p
order by p.rn, p.gender
注意:来自9.4. User-Defined Variables
作为一般规则,您不应该为用户变量赋值 并在同一语句中读取值。你可能会得到 你期望的结果,但这不能保证。
我会留下你决定是否可以使用它。我不使用MySQL,所以我不能真的告诉你是否应该关注。
答案 2 :(得分:1)
与Mikael的解决方案类似,但无需多次订购结果集 -
SELECT *
FROM (
SELECT people.*,
IF(gender=0, @mr:=@mr+1, @fr:=@fr+1) AS rank
FROM people, (SELECT @mr:=0, @fr:=0) initvars
) tmp
ORDER BY rank ASC, gender ASC;
为避免必须同时选择内部和外部选择,我在内部选择中使用了单独的计数器(@mr - 男性等级,@ fr - 女性等级)。
答案 3 :(得分:0)
我有一张表格,其中包含性别编码为0和1的人
那你为什么要对结果集中的行顺序做出假设?在我看来,将0/1转变为“男性”/“女性”更为强大:
select name, case gender when 0 then 'male' else 'female' end
from Person
答案 4 :(得分:-1)
SELECT alias.*, ROW_NUMBER() OVER (PARTITION BY GENDER ORDER BY GENDER) rnk
FROM TABLE_NAME
ORDER BY rnk, GENDER DESC