【问题标题】:SQL query with CASE statement ,multiple variables and sub variables带有 CASE 语句、多个变量和子变量的 SQL 查询
【发布时间】:2018-07-18 09:45:48
【问题描述】:

我正在处理数据集,我需要在 R-programmingSQLDF 中为以下要求编写查询,我想知道并学习用两种语言 (SQL and R) 编写,请帮助。

要求是:我需要从表中打印变量“a” id 34 和 Rank 3 的 Total_Scores 大于 Total_Scores of id 34 和排名 4 否则打印变量 b 。 以上情况适用于idRank

id   Rank    Variable     Total_Scores
34      3     a              11
34      4     b               6
126     3     c              15
126     4     d              18
190     3     e               9
190     4     f              10
388     3     g              20
388     4     h              15
401     3     i              15
401     4     x              11
476     3     y              11
476     4     z              11
536     3     p              15
536     4     q               6 

我试图写SQL CASE 声明,但我被卡住了,请你帮忙 帮助编写查询

"select id ,Rank ,
                      CASE 
           WHEN (select Total_Scores from table where id == 34 and Rank == 3) > (select Total_Scores from table where id == 34 and Rank == 4)
           THEN "Variable is  )

最终输出应该是:

id   Rank    Variable     Total_Scores
34      3        a          11
126     4        d          18
190     4        f          10
388     3        g          20
401     3        i          15
536     3        p          15

【问题讨论】:

  • id 476 未出现在示例输出中。这是一个错误吗?
  • 抱歉,它应该在最终输出中。
  • 应该有什么 - 两行或其中一行,或者没关系?
  • 要求为每个 id 选择具有最高 Total_scores 的行,在此我需要 Total_Scores Level 的行
  • 这个还不清楚。您需要 all 特定 id 的这些行还是只需要 任何一个 这些行?这两种选择都是共同的要求。

标签: sql r sqldf


【解决方案1】:

您似乎想要每个 id 得分最高的行。在 SQL 中编写此代码的规范方法是使用 row_number():

select t.*
from (select t.*,
             row_number() over (partition by id order by score desc) as seqnum
      from t
     ) t
where seqnum = 1;

这将返回每 id 一行,即使分数相同。如果您希望在这种情况下使用所有行,请使用 rank() 而不是 row_number()

另一种方法可以通过(id, score) 上的索引获得更好的性能:

select t.*
from t
where t.score = (select max(t2.score) from t t2 where t2.id = t.id);

【讨论】:

    【解决方案2】:

    你可以试试这个。

    SELECT T.* FROM (
        SELECT id, 
            MAX(Total_Scores) Max_Total_Scores 
        FROM MyTable
        GROUP BY id
        HAVING MAX(Total_Scores) > MIN(Total_Scores) ) AS MX 
    INNER JOIN MyTable T ON MX.id = T.id AND MX.Max_Total_Scores = T.Total_Scores
    ORDER BY id
    

    Sql Fiddle

    【讨论】:

      【解决方案3】:

      在R中

      library(dplyr)
      df %>% group_by(id) %>% 
               filter(Total_Scores == max(Total_Scores)) %>% filter(n()==1) %>% 
               ungroup()
      
      # A tibble: 6 x 4
         id  Rank Variable Total_Scores
       <int> <int> <chr>           <int>
      1    34     3 a                  11
      2   126     4 d                  18
      3   190     4 f                  10
      4   388     3 g                  20
      5   401     3 i                  15
      6   536     3 p                  15
      

      数据

      df <- read.table(text="
                   id   Rank    Variable     Total_Scores
                     34      3     a              11
                     34      4     b               6
                     126     3     c              15
                     126     4     d              18
                     190     3     e               9
                     190     4     f              10
                     388     3     g              20
                     388     4     h              15
                     401     3     i              15
                     401     4     x              11
                     476     3     y              11
                     476     4     z              11
                     536     3     p              15
                     536     4     q               6 
      
                     ",header=T, stringsAsFactors = F)
      

      【讨论】:

      • 谢谢苏利曼。但是我能够弄清楚解决方案数据 %>% group_by(id) %>% mutate(Rank = rank(Total_Scores))%>% filter(Rank == 2)
      【解决方案4】:

      假设您想要的是获得Total_Scoresid 最大的行的子集,这里有两种方法。

      问题没有讨论如何处理关系。示例中有一个id 有一个平局,但没有与之对应的输出,我认为这不是故意的,或者两行都应该输出,或者其中之一。无论如何,在 (1) 中的解决方案中,如果有重复,它将任意给出其中一行,而 (2) 将给出两者。

      1) sqldf

      如果您在 SQLite select 中使用 max,它将自动选择同一行的其他变量,因此:

      library(sqldf)
      sqldf("select id, Rank, Variable, max(Total_Scores) Total_Scores 
             from DF
             group by id")
      

      给予:

             id Rank Variable Total_Scores
      1  34    3        a           11
      2 126    4        d           18
      3 190    4        f           10
      4 388    3        g           20
      5 401    3        i           15
      6 476    3        y           11
      7 536    3        p           15
      

      2) base R 在base R中,我们可以像这样使用avesubset

      subset(DF, ave(Total_Scores, id, FUN = function(x) x == max(x)) > 0)
      

      给予:

          id Rank Variable Total_Scores
      1   34    3        a           11
      4  126    4        d           18
      6  190    4        f           10
      7  388    3        g           20
      9  401    3        i           15
      11 476    3        y           11
      12 476    4        z           11
      13 536    3        p           15
      

      注意

      可重现形式的输入:

      Lines <- "id   Rank    Variable     Total_Scores
      34      3     a              11
      34      4     b               6
      126     3     c              15
      126     4     d              18
      190     3     e               9
      190     4     f              10
      388     3     g              20
      388     4     h              15
      401     3     i              15
      401     4     x              11
      476     3     y              11
      476     4     z              11
      536     3     p              15
      536     4     q               6"
      
      DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-13
        相关资源
        最近更新 更多