从mysql表中选择每隔一行作为男性/女性
Posted
技术标签:
【中文标题】从mysql表中选择每隔一行作为男性/女性【英文标题】:Select every other row as male/female from mysql table 【发布时间】:2012-04-15 12:03:53 【问题描述】:我有一个表格,其中包含性别编码为 0 和 1 的人员。我需要每隔一行选择男性/女性。我以为我可以通过使用模数和性别代码 0 和 1 以某种方式管理这个问题,但我还没有设法弄清楚......
我正在寻找的结果如下所示:
+-----+--------+--------+ |行 |性别 |姓名 | +-----+--------+--------+ | 1 |女|丽莎 | | 2 |男|格雷格 | | 3 |女|玛丽 | | 4 |男|约翰 | | 5 |女|珍妮 | +-----+--------+--------+等等
另一种方法是在 php 中合并 2 个单独的数组,但我真的很喜欢它作为 SQL 查询...
欢迎提出任何建议!
【问题讨论】:
我不确定我是否明白您的问题,您是否想从您的数据库中仅检索男性(或女性)?目前尚不清楚您要完成什么。 请说明您要求的结果.. 我需要每隔一行检索一次男性/女性:例如1. 丽莎,2. 格雷格,3. 玛丽,4. 约翰,5. 珍妮 您的逻辑似乎有缺陷,因为无法保证男女人数相等。您认为应该如何处理? 如果这是您需要的结果,您选择的表格是什么样的? 【参考方案1】:执行两个子查询来选择男性和女性。使用排名函数来枚举它们。
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
【讨论】:
对不起,我没有注意到这是 mysql 相关的问题。不确定MySQL是否有排名功能。 它没有,但你可以使用用户变量来实现。【参考方案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
试试SQL Fiddle
注意:来自9.4. User-Defined Variables
作为一般规则,您永远不应该为用户变量赋值 并读取同一语句中的值。你可能会得到 您期望的结果,但这不能保证。
我会让你决定是否可以使用它。我不使用 MySQL,所以我不能告诉你是否应该担心。
【讨论】:
我们越来越近了,但还没有到。你的代码只能部分工作,因为这些行似乎给出了相同数量的性别,但并不像其他每一行一样严格。这只会在更多行时变得明显:sqlfiddle.com/#!2/05b02/1 @darwin 看起来像派生表中的order by gender
处理了这个问题。【参考方案3】:
类似于 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 - 女性排名)。
【讨论】:
【参考方案4】:我有一个表格,其中包含性别编码为 0 和 1 的人员
那你为什么要假设结果集中的行顺序呢?在我看来,将 0/1 转换为“男性”/“女性”要强大得多:
select name, case gender when 0 then 'male' else 'female' end
from Person
【讨论】:
我使用 0 和 1 的原因是因为我认为使用模 2 可以达到我想要的效果【参考方案5】:SELECT alias.*, ROW_NUMBER() OVER (PARTITION BY GENDER ORDER BY GENDER) rnk
FROM TABLE_NAME
ORDER BY rnk, GENDER DESC
【讨论】:
以上是关于从mysql表中选择每隔一行作为男性/女性的主要内容,如果未能解决你的问题,请参考以下文章