【问题标题】:Is there a way to limit the amount of times a unique value is returned in a table?有没有办法限制表中返回唯一值的次数?
【发布时间】:2020-03-21 18:57:21
【问题描述】:

作为前言,我们的服务器似乎运行的是 5.5.56-MariaDB。

例如,我目前可以返回如下数据:

数据_|_数量
00001 | 1000
00001 | 900
00001 | 800
00001 | 700
00002 | 600
00002 | 500
00002 | 400
00003 | 300
00003 | 200
00003 | 100

使用 Groups 和 Counts 以及来自其他表的联接可以相当轻松地提取 Data 和 Quantity 值。但是,我试图只从提取的每条数据中返回两个最高数量值 - 所以实际上,我希望结果更像这样:

数据_|_数量
00001 | 1000
00001 | 900
00002 | 600
00002 | 500
00003 | 300
00003 | 200

值没有改变,我只是没有返回与我无关的数据。 我一直在摆弄嵌套表、计数和组以及我能想到的任何其他东西,但我最接近的是只返回最高值,这不符合我的需要。

我真的很困惑如何继续在这里,而且我似乎无法找到任何其他需要类似数据回报的人,所以如果有人可以提供任何指导,我会非常欣赏它。

非常感谢。

【问题讨论】:

  • 查看我添加的标签。

标签: mysql mariadb greatest-n-per-group


【解决方案1】:

如果你使用的是 MySQL 8+,那么这里可以使用ROW_NUMBER

SELECT Data, Quantity
FROM
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Data ORDER BY Quantity DESC) rn
    FROM yourTable
) t
WHERE
    rn <= 2
ORDER BY
    Data,
    Quantity DESC;

在早期版本的 MySQL 上,可以使用用户变量来模拟行号,但需要更多代码。如果您长期需要此类查询,请考虑升级。

【讨论】:

  • 一个优雅的解决方案,但似乎你说我使用的是旧版本是对的。不过,感谢您的尝试。
【解决方案2】:

https://en.wikibooks.org/wiki/Structured_Query_Language/Retrieve_Top_N_Rows_per_Group 有几个示例说明如何做到这一点。

在很久以前的一个用例中,我使用了以下表单的查询

 SELECT *
FROM   table_temp
WHERE  quantity = (SELECT Max(quantity)
                   FROM   table_temp AS t
                   WHERE  t.data = table_temp.data)
        OR quantity = (SELECT Max(quantity)
                       FROM   table_temp AS t
                       WHERE  t.data = table_temp.data
                              AND quantity < (SELECT Max(quantity)
                                              FROM   table_temp AS t2
                                              WHERE  t2.data = table_temp.data)) 

这会选择一个组的最高数量,并且它的下一个值很好。

第一个过滤器质量拉最大,第二个过滤器拉第二大数量。

但是,Tim Biegeleisen 的解决方案更加优雅,因为它可以扩展到任意数量的值,而不会在 SQL 中增加太多复杂性。

同样的 SQL Fiddle:http://sqlfiddle.com/#!9/372454/8

【讨论】:

    【解决方案3】:

    如果它只是一个查询,你可以尝试这样的事情

    SELECT
        T.Data,
        T.Quantity
    From
    (
        SELECT 
            Data,
            Quantity,
            if(@id = TT0.data, (select(@i := @i + 1)), (select(@i := 0))) as R, -- if previous id == data then row +1 else r=0
            @id := TT0.data -- assign Data to @id variable
        FROM
            YourTable as T0, (select @i:= 0, @id := null ) as Rows -- cross join initialise @i and @id
    ) AS T
    WHERE
        T.R < 2; -- row numbers you are interested in
    

    有关限制和更多信息:https://dev.mysql.com/doc/refman/5.7/en/user-variables.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多