【问题标题】:MySQL: how to select the Nth value of each group with GROUP BYMySQL:如何使用 GROUP BY 选择每个组的第 N 个值
【发布时间】:2016-11-11 00:17:37
【问题描述】:

我想选择每个 new_threads 组的第二个响应列值,如果它是一组 1 行,则值为零。

new_treads|response
------------------
 1        | 0        
 1        | 1
 2        | 0    
 2        | 0
 2        | 1
 ...      | ...
 9        | 0     
 9        | 1    
 9        | 0   
 10       | 0  

输出是:

new_treads|response
------------------
 1        | 1
 2        | 0
 ...      | ...
 9        | 1    
 10       | 0  

到目前为止,我了解如何使用 MIN 获得第一个,但我需要第二个

SELECT 
thread,
min(response)
FROM messages
GROUP BY thread;

我想使用 GROUP BY,因为我也将 GROUP BY 用于其他 SELECT

谢谢!

【问题讨论】:

    标签: mysql group-by


    【解决方案1】:

    由于行没有“编号”,您需要为每个组创建一个编号,然后选择它。我会用用户变量来做到这一点:

    select thread, response
    from (
            select @n := (case 
                    when m.thread = @prev_thread then @n 
                    else 0 
                end) + 1 as n    -- If the current thread is the same as the
                                 -- previous row, then increase the counter,
                                 -- else, reset it
                 , @prev_thread := m.thread as thread -- Update the value of
                                                      -- @prev_thread
                 , m.response
            from 
                   (select @n := 0, @prev_thread := 0) as init
                              -- The 'init' subquery initializes the 
                              -- temp variables:
                              --     @n is a counter
                              --     @prev_thread is an identifier for the
                              --     previous thread id
                 , messages as m
            order by m.thread -- You need to add a second column to order 
                              -- each response (such as "response_id", or
                              -- something like that), otherwise the returned
                              -- row may be a random one
        ) as a
    where n = 2;    -- Select the rows from the subquery where the counter equals 2
    

    上面的方法可以很好地找到每个组的第二行,但前提是有一个。那么现在:如果没有第二行,如何获得NULL 值?

    最简单的方法是使用左连接:

    select t.thread, b.response
    from (select distinct thread from messages) as t
         left join (
             -- Put the above query here
         ) as b on t.thread = b.thread;
    

    【讨论】:

    • 如果有第二个值,这非常有用。为了通过选择将其与其他组合并,我是否只需将其加入其他组?
    • @DavidFeldman 检查编辑(我忘了包括它)。希望能帮助到你。顺便说一句,如果你觉得这篇文章有用,请投票和/或接受它;)
    【解决方案2】:
    SELECT 
    thread,
    min(response)
    FROM messages
    GROUP BY thread
    HAVING response > min(response)
    

    试试这个只是想知道它是否有效

    【讨论】:

    • 我收到错误:“‘有子句’中的未知列‘响应’”
    【解决方案3】:

    我想详细说明上面的答案。虽然它对我来说效果很好,但需要一些时间来拼凑上下文并对其进行概括,以便我可以将其应用到我的代码中。我希望这个答案能更好地概括上面列出的内容......

    SELECT *
    FROM  (SELECT distinct keyField    --- keyField is the field the query is grouping by
            FROM TABLE
            --  Add keyField Constraint --
            --  Add non-keyField Constraint --     
    INNER JOIN (SELECT *,
           @n:=(CASE                                -- Iterating through...
                   WHEN keyField = @prev_keyField   -- When keyField value == previous keyField value
                   THEN @n:=@n+1                    -- Define n as the row in the group
                   ELSE 1                           -- When keyField value != previous keyField value, then n is the 1st row in the group
                   END) as n,
                @prev_keyField:= keyField           -- Define previous keyField value for the next iteration
                FROM (SELECT @n:=0,@prev_keyField:=0) r,TABLE as p
                --  Add non-keyField Constraint--  
                ORDER BY keyField,sortField DESC    -- Order by keyField and the field you are sorting by
                                                    --  ei. keyField could be `thread`, 
                                                    --  and sort field could be `timestamp` if you are sorting by time
                ) s ON s.keyField = p.keyField
    WHERE s.n = 2                                   -- Define which row in the group you want in the query
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 2014-11-22
      • 2019-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多