如何从表中的每个不同类别中选择三行?

Posted

技术标签:

【中文标题】如何从表中的每个不同类别中选择三行?【英文标题】:How to select three rows from each different category from a table? 【发布时间】:2010-06-01 10:27:35 【问题描述】:

我有两个表类别和酒店,其中 category.id 应该等于hotels.catid。现在如何从酒店表中的每个不同类别中选择 3 行。

我有这个问题:

select h.* from hotels h inner join category c on h.catid = c.id
order by h.catid, h.hid

这会选择所有记录,但我想为每个不同的类别选择三行,所以它应该返回 9 行,每个类别有 3 行。

如果这在 mysql 中做不到,可以在 php 中完成吗?

【问题讨论】:

你想要什么 3 行?前三名?随机3?具体的3?最后 3 个? @AndyC:前 3 名或后 3 名,我想在主页上显示每个类别的 3 行。 【参考方案1】:

试试这个:

select h.* 
from category c
  inner join (select * from hotels h where c.id = h.catid limit 3) h
order by h.catid, h.hid

我想知道这是否是 MySQL 中的有效语法...

如果没有,你可以试试:

select h.*
from category c
  inner join hotels h on (c.id = h.catid)
where h.hid in (select h2.hid from hotels h2 where h2.catid = c.id limit 3)

第三次尝试:

select h.*
from category c
  inner join hotels h on (c.id = h.catid)
where exists (select * from (select h2.hid from hotels h2 where h2.catid = c.id limit 3) h3 where h3.hid = h.hid)

好吧,这是另一个非常丑陋的尝试:

select * from hotels h
where h.hid <=
(select min(h1.hid) 
 from hotels h1 
 where h1.catid = h.catid 
   and h1.hid > (select min(h2.hid) 
                 from hotels h2 
                 where h2.catid = h1.catid 
                   and h2.hid > (select min(h3.hid) 
                                 from hotels h3
                                 where h3.catid = h2.catid)
                )
)

我希望它有效。如果它没有,希望它能给你一些可能有用的想法,或者甚至给其他人关于如何解决这个问题的想法。至少它可以用来查看什么不起作用。

【讨论】:

'where 子句'中的未知列'c.id' 哎呀,现在我明白了:这个版本的 MySQL 还不支持 'LIMIT & IN/ALL/ANY/SOME 子查询' @Me-and-Coding:你用的是什么版本?如果没有LIMIT 子句,我看不出你怎么能做到。【参考方案2】:

你可以通过以下方式做到这一点。

select 
    h.* 
from 
    hotels h 
where 
    h.catid IN (
        select 
            c.catid 
        from 
            category c 
        order by
            RAND() 
        limit 1
    ) 
order by 
    h.catid, h.hid 
limit 3

这应该会为您提供一个随机类别中的 3 家酒店。

使用php你可以这样做

$i = 0;
$sql = "select catid from category order by rand()";
$query = mysql_query($sql);
while($row = mysql_fetch_object($query))

    if($i < 3)
    
        $i++;
        $categories[] = $row->catid;
    
    else
    
        break;
    


foreach($categories as $catid)

    $i = 0;
    $sql = "select * from hotels where catid = $catid";
    $query = mysql_query($sql);
    while($row = mysql_fetch_object($query))
    
        if($i < 3)
        
            $i++;
            $hotels[] = $row;
        
        else
        
            break;
        
    

【讨论】:

这个版本的 MySQL 还不支持 'LIMIT & IN/ALL/ANY/SOME 子查询' 用 php 解决方案更新了我的答案。 +1,我也这样做了,但现在使用了我接受的仅查询解决方案。谢谢【参考方案3】:

您应该能够使用 DISTINCT(category) 并将查询限制为 3 个结果

【讨论】:

我试过了,但它只显示了一只猫的记录:SELECT DISTINCT(c.id), h.* FROM hotels h INNER JOIN category c ON h.catid = c.id ORDER BY h.catid, h.hid LIMIT 3【参考方案4】:

所以你想为每个类别找到三家酒店......有很多选择!

我能想到的最简单的方法是按类别执行查询。

SELECT
    h.* 
FROM
    hotels h
WHERE
    h.catid = 1
LIMIT 0, 3        

【讨论】:

你说过 h.catid = 1 但 catid 是未知的,它不可能是 1,也可能是其他数字。【参考方案5】:

嗨,我不确定查询,但我有另一种方法。首先找到所有类别数组,然后从酒店表中找到 3 条记录。

第一步: $sql="SELECT * FROM 表类别"; 执行查询并将结果放入类别数组中

第二步: 做一个循环 For($i=0;isset(类别数组 [$i]);$i++) 从酒店表中查询 3 条记录 执行此操作并将所有数据存储在数组中 通过这种方式您也可以获得记录。这不是您问题的确切解决方案,但您可以使用它来解决您的问题

【讨论】:

以上是关于如何从表中的每个不同类别中选择三行?的主要内容,如果未能解决你的问题,请参考以下文章

从表和参考表中选择列、count(id)

从表 SQL 中选择多个不同的行

从表中检索所有不同的记录,如果两个相似的不同记录之间发生任何更改,则需要同时考虑两者。使用选择查询

从表中选择不同的记录并执行重复行的列总和(托盘、总和)。并显示重复的行一次[关闭]

从表中选择 WHERE 子句中具有不同 IN 列表的表

OCR 软件能否可靠地从表中读取值?