从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表中选择每隔一行作为男性/女性的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4481非诚勿扰(期望dp)

我想从子查询的结果中计算男性和女性的总数。有没有mysql查询

如果条件唯一,MySQL独特计数

将列值从“男性”替换为“女性”,将“女性”替换为“男性”

使用不同的where条件mysql一次更新所有行

男性女性的心灵刮骨疗毒师