根据其他行中的列值选择行

时间:2020-10-02 08:12:10

标签: sql r dplyr subquery where-clause

对于这个问题,我将对R中的解决方案(最好是dplyr,但其他方法也可以)或纯SQL感到满意。

我有包含个人(ID)和电子邮件地址的数据,还有一个二进制指示符,表示该电子邮件地址是否是个人的主要电子邮件地址(1)或不是(0)

  • 所有ID都有一个并且只有一个主要电子邮件地址
  • ID可以有几个非主要电子邮件地址(或没有)
  • ID可以具有与主要和非主要相同的电子邮件地址

例如:

   ID Email Primary
1   1     A       1
2   1     A       0
3   1     B       0
4   2     A       1
5   2     A       0
6   3     C       1
7   4     D       1
8   4     C       0
9   5     E       1
10  5     F       0

(实际的数据集大约有五十万行)

我希望标识电子邮件地址不是主要地址但对于其他ID是主要地址的ID。也就是说,我要选择以下行:

  • 主要是0
  • 存在另一行,其中该ID为主要ID,但具有不同的ID

因此,在上面的数据中,我想选择第5行(因为电子邮件地址不是主要的,但是对于不同的ID行1是主要的,而第8行(因为它不是主要的,但是在第6行中选择主要ID)和在第2行中

对于R用户,这是上面的玩具数据框:

structure(list(ID = c(1, 1, 1, 2, 2, 3, 4, 4, 5, 5), Email = c("A", "A", "B", "A", "A", "C", "D", "C", "E", "F"), Primary = c(1, 0, 0, 1, 0, 1, 1, 0, 1, 0)), class = "data.frame", row.names = c(NA, -10L))

2 个答案:

答案 0 :(得分:5)

您可以选择其中的行

  • Primary = 0
  • ID
  • Email个数大于1。
  • primary = 1至少有一个Email

使用dplyr,您可以按照以下步骤操作:

library(dplyr)

df %>% 
   group_by(Email) %>% 
   filter(Primary == 0, n_distinct(ID) > 1, any(Primary == 1))

#     ID Email Primary
#  <dbl> <chr>   <dbl>
#1     1 A           0
#2     2 A           0
#3     4 C           0

由于您拥有大数据,因此data.table解决方案会有所帮助:

library(data.table)

setDT(df)[, .SD[Primary == 0 & uniqueN(ID) > 1 & any(Primary == 1)], Email]

答案 1 :(得分:3)

SQL 中,您可以为此使用exists

select t.*
  from mytable t
where t.primary = 0 
      and exists (
                  select 1 
                  from mytable t1 
                  where t1.email = t.email 
                    and t1.id <> t.id 
                    and t1.primary = 1
                  )
相关问题