MySql Query从每个组中检索一个集合编号

时间:2017-06-01 12:34:39

标签: mysql

如果我有桌子:

------------------
| Provider | ID  |
------------------
| X        | 125 |
------------------
| X        | 133 |
------------------
| X        | 342 |
------------------
| X        | 327 |
------------------
| Y        | 123 |
------------------
| Y        | 853 |
------------------
| Y        | 123 |
------------------
| Z        | 853 |
------------------
| Z        | 533 |
------------------
| Z        | 174 |
------------------

我希望从每个提供者X和Y(忽略Z)中获得2个随机条目以生成

X  id
X  id
Y  id
Y  id

我已经尝试过几个问题,包括

select id, provider from tableName a where (SELECT COUNT(*) FROM tableName b where b.provider =  a.provider) = 2;

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你尝试这个查询怎么样:

select provider, ID, Rank from 
(
    select *, @row_num := IF(@prev_value=provider,@row_num+1,1) AS rank, @prev_value := provider from 
    (
        select provider, ID, rand() as SortingField from yourTable
        order by provider, SortingField
    ) t1,
    (SELECT @rownum := 0) x, (SELECT @prev_value := '') y
) src
where Rank <= 2 and Provider <> 'Z'

好的,这就是它的工作原理。首先,您需要随机输入,因此您需要添加&#34;随机&#34;我使用mySql&#39; rand()函数进行的排序字段。由于它提供了一个随机数,因此您的字段将始终随机排序。

这为我们的下一个要求设置了两个随机条目。由于您的字段是随机排序的,因此我们只选择前两条记录,每次查询运行时它们都会不同。要做到这一点,我们需要一个行计数器,每当所需字段更改值时重置(在您的情况下,它是&#39;提供商&#39;)。这就是我们使用变量做的事情:

@rownum是您的行计数器,每次出现新记录时都会加1。

@prev_value是您的值检查器,用于确定何时需要重置计数器。请注意,它是在@row_num增量之后设置的,这很关键,因为如果您之前设置它,那么您将检查当前值,这将毫无意义。

最后,你所要做的就是选择所需的字段(提供者,ID,等级)并获取低于2的等级并忽略&#39; Z&#39;提供者,这是查询的最后部分。

如果您有疑问,请不要犹豫,但我希望我的解释足够明确。

答案 1 :(得分:1)

按rand()排序,并使用x和y的where子句限制为2,并将所有结果合并。显而易见的是你要做的事情并且易于维护。

SELECT Provider, ID
FROM tableName
WHERE provider = 'X'
ORDER BY Rand()
LIMIT 2

UNION ALL

SELECT Provider, ID
FROM tableName
WHERE provider = 'Y'
ORDER BY Rand()
LIMIT 2