【问题标题】:MySQL order by random but show distinct first 5 results?MySQL 随机排序但显示不同的前 5 个结果?
【发布时间】:2012-03-08 01:07:43
【问题描述】:

好的,我有 3 个 MySQL 表

类别 公司 优惠

我希望某人点击类别页面,从而以随机顺序显示来自每家公司的报价,因此没有人被优先考虑。一家公司可以有 1 到 10 个报价,并且可以有任意数量的报价链接到一个类别。

这一切都很好,但我希望前 5 个(或更多,无论是最简单的)报价显示为来自独特的公司。下面的其他可以按任何顺序排列,只要它们不重复已经显示在前 5 中的那些。

不确定解决此问题的最佳方法,因为它有点超出我的能力 - 是否会进行 2 个查询并离开加入它们,不包括第二个查询中的第一个查询中的报价 ID?

非常感谢任何帮助!

【问题讨论】:

  • 就解决方案而言并不是很有用,但是如果您正在查看更大的数据集,mysql RANDOM() 排序可能会非常慢 - 只是觉得值得警告。
  • 谢谢西蒙,这不是一个非常大的数据集,所以目前查询时间不到 1/100 秒

标签: php mysql random distinct


【解决方案1】:

我使用了 nnichols 建议但经过调整的内容(出于某种原因,初始查询需要 3.5 秒才能运行)所以我使用了这个:

SELECT * 
FROM (SELECT offers.companyid, offerid, title, offer 
      FROM companies 
      INNER JOIN offers ON offers.companyid = companies.companyid 
      WHERE offers.categoryid='%s' AND offers.active = '1' 
      ORDER BY RAND()) AS t 
GROUP BY t.companyid 
ORDER BY RAND() 
LIMIT 10

只需要0.0088 运行。然后我存储了正在使用的报价 ID,并使用来自 nnichols 的 NOT IN 进行第二次查询,现在效果很好

再次感谢大家的帮助:)

【讨论】:

    【解决方案2】:

    必须有一种更有效的方法来做到这一点,但我的大脑今天还没有达到 100%。怎么样-

    SELECT
        company_offers.companyid,
        offers.offerid,
        offers.title,
        offers.offer
    FROM (
        SELECT
            companies.companyid,
            (
                SELECT offers.offerid
                FROM offers
                WHERE offers.companyid = companies.companyid
                AND categoryid = '%s'
                AND active = 1
                ORDER BY RAND()
                LIMIT 1
            ) AS offerid
        FROM companies
        WHERE EXISTS (SELECT NULL FROM offers WHERE offers.companyid = companies.companyid AND offers.categoryid = '%s' AND offers.active = 1)
        ORDER BY RAND()
        LIMIT 5
    ) AS company_offers
    INNER JOIN offers
        ON company_offers.offerid = offers.offerid
    

    更新:将 EXISTS 添加到内部公司 SELECT

    然后从您的主 SELECT 语句中排除这 5 个 offer_id。

    SELECT companies.companyid, offers.offerid, offers.title, offers.offer
    FROM offers
    INNER JOIN companies
        ON companies.companyid = offers.companyid
    WHERE offers.categoryid = '%s'
    AND offers.active = 1
    AND offers.offerid NOT IN (comma separated list of 5 from previous query)
    ORDER BY RAND()
    

    【讨论】:

    • 我担心这个查询的性能,所以我在我的笔记本电脑上测试了它,在 2000 个公司和 200 个类别中提供了 100 万个报价,它在不到 0.2 秒内返回。值得在 offer 表上为 companyid、categoryid、active 添加索引。
    【解决方案3】:

    未经测试,但这样的东西应该可以工作。我们可以查看您当前的查询吗?

    SELECT DISTINCT company, and, other, columns 
    FROM table
    ORDER BY RAND()
    LIMIT 5
    

    【讨论】:

    • 不,我仍然需要在其下方显示其他优惠,因此它需要显示除前 5 名之外的所有内容作为唯一公司,因此同一公司未列在前 5 名中(除非有该类别中的公司少于 5 家)。当前查询只是以随机顺序显示它们:SELECT Companies.companyid、offerid、title、offer FROM offer、companies WHERE categoryid='%s' AND active = '1' AND (companies.companyid = offer.companyid) ORDER BY RAND ()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2012-11-23
    相关资源
    最近更新 更多