如何编写单个SQL查询以选择具有多个条件的子组

时间:2018-07-03 22:03:20

标签: sql

我有这张桌子: enter image description here

我需要获取此表: enter image description here

一个类应对应一个id。该类的选择如下:

  1. 选择了最常见的id类(例如,id 333对应于A类)。

  2. ,但是如果一个id对应于“ other”类,而其他类对应,则为id分配一个专制阶级,而不考虑“ other”类。在这种情况下,如果类别数相同,则将分配最后一个日期的类别。例如,id 111对应于3个类别(“ other”,A,B)。 A类和B类的数量为两个。由于ID 111是在上一个日期,所以它被分配为A类。

  3. 如果仅为该类分配了“其他”类,则id对应于该类“其他”(例如,为类222分配了“其他”类,因为仅为其分配了“其他”类)其他”)。

2 个答案:

答案 0 :(得分:1)

如果要从子集中选择任何一行,则应按条件RANK对每一行进行排序,以对子集中的行进行排序,然后按排名对行进行过滤。

您可以尝试使用此查询解决问题。

select id, class 
from (
        Select 
            Id
            , Class
            , RANK() OVER (PARTITION BY Id 
                            ORDER BY 
                                case when class='other' then 0 else 1 end desc -- condition # 3
                                , count(*) desc -- condition # 1
                                , max(date1) desc ) AS RowRank -- condition # 2
        from @table1 
        group by id, class
    ) Q
where rowrank = 1

答案 1 :(得分:0)

如果您的DBMS具有row_number()的功能,则可以首先按idclass分组以获取计数和最大值date1。从该结果中选择以id划分的行号。作为行号的顺序,请使用CASEother进行排序,然后再降序计数和最大值date1 -如果计数相等,则最大值date1将决定。仅选择行号等于1的行,顺序中的第一行。

SELECT id,
       class
       FROM (SELECT id,
                    class,
                    row_number() OVER (PARTITION BY id
                                       ORDER BY CASE class
                                                  WHEN 'other'
                                                    THEN 1
                                                  ELSE
                                                    0
                                                END ASC,
                                                c DESC,
                                                d DESC) rn
                    FROM (SELECT id,
                                 class,
                                 count(*) c,
                                 max(date1) d
                                 FROM elbat
                                      GROUP BY id,
                                               class) x) y
       WHERE rn = 1;