用于过滤重复项的多行功能

Multi-Row function to filter out Duplicates

我对使用 SQL 比较陌生,所以我想请您帮忙处理一个案例。

我有以下 Table(只是一个示例):

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  |
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         |
| 2  | John        | Kennedy    | Olivier    | Oslo        |
| 3  | Mike        | Lanes      | Patrick    | James       |

我想隔离 FName_LVL1 和 LName_LVL1

中的重复项

所以 Table 看起来像这样 :

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  |
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         |
| 2  | John        | Kennedy    | Olivier    | Oslo        |

我的想法是创建一个标志列,条件是如果 FName_LVL1 列和 LName_LVL1 列中的上方或下方行相同,则输入“1”,否则输入“0”。 =13=]

栏目如下所示:

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  | Flag
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         | 1
| 2  | John        | Kennedy    | Olivier    | Oslo        | 1
| 3  | Mike        | Lanes      | Patrick    | James       | 0

有了这样的 table 之后,我可以过滤并得到我想要的结果。

这是我在 Alteryx 中习惯的工作方式,但我不确定是否可以使用 SQL 语句,或者即使这是解决这种情况的最佳方式

no_of_records 列告诉您该组合在 table 中出现了多少次。 IE。在你的例子中它将是 2 table

select table1.*
from table as table1
inner join
(
  Select FName_LVL1, LName_LVL1, count(*) as no_of_records
  from Table
  group by FName_LVL1, LName_LVL1
) table2
  on table1.FName_LVL1 = table2.FName_LVL1
     and table1.LName_LVL1 = table2.LName_LVL1
     and no_of_records>1

您可以将 count()window 函数一起使用。

SQL Fiddle

查询 1:

SELECT t.*
    ,CASE 
        WHEN COUNT(*) OVER (
                PARTITION BY fname_lvl1
                ,lname_lvl1
                ) > 1
            THEN 1
        ELSE 0
        END AS Flag
FROM t

Results:

| ID | FNAME_LVL1 | LNAME_LVL1 | FNAME_LVL2 | LNAME_LVL2 | FLAG |
|----|------------|------------|------------|------------|------|
|  1 |       John |    Kennedy |       Marc |        Guy |    1 |
|  2 |       John |    Kennedy |    Olivier |       Oslo |    1 |
|  3 |       Mike |      Lanes |    Patrick |      James |    0 |

您可以使用 "semi join" 子查询来获得这样的结果:

SELECT * FROM Table1 t1
WHERE EXISTS (
  SELECT 'Anything' FROM Table1 t2
  WHERE t1.FName_LVL1 = t2.FName_LVL1
    AND t1.LName_LVL1 = t2.LName_LVL1
    AND t1.id <> t2.id
)

演示:http://sqlfiddle.com/#!4/f9c44/3

| ID | FNAME_LVL1 | LNAME_LVL1 | FNAME_LVL2 | LNAME_LVL2 |
|----|------------|------------|------------|------------|
|  2 |       John |    Kennedy |    Olivier |       Oslo |
|  1 |       John |    Kennedy |       Marc |        Guy |

您可能更喜欢使用 LAGLEAD 分析函数以及 NVL2 的贡献:

select n.*,
       nvl2(lag(FName_LVL1||' '||LName_LVL1,1,null) over 
       (partition by FName_LVL1||' '||LName_LVL1 order by FName_LVL1, LName_LVL1),1,0)+
       nvl2(lead(FName_LVL1||' '||LName_LVL1,1,null) over 
       (partition by FName_LVL1||' '||LName_LVL1 order by FName_LVL1, LName_LVL1),1,0) flag
  from names n;

ID FNAME_LVL1   LNAME_LVL1  FNAME_LVL2  LNAME_LVL2  FLAG
--  ----------  ----------  ----------  ----------  -----
1    John        Kennedy      Marc        Guy         1
2    John        Kennedy      Olivier     Oslo        1
3    Mike        Lanes        Patrick     James       0

SQL Fiddle Demo

最有效的方法是使用 partition by 子句只进行一次 table 扫描。 我已将输出保存在 Livesql

drop table t1 purge;
      create table t1 ( c1 varchar2(20), c2 varchar2(20), c3 varchar2(20), c4 varchar2(20));
      insert into t1 values ('John','Kennedy','Marc','Guy');
      insert into t1 values ('John','Kennedy','Olivier','Oslo');
      insert into t1 values ('not','john','vijay','balebail');
      commit;
      select t1.*, count(c1||c2) over (partition by c1,c2 order by c1,c2  ) flag from t1;
      select t1.*, decode (count(c1||c2) over (partition by c1,c2 order by c1,c2  ),1,0,1) flag from t1;

C1 C2 C3 C4 标志 约翰肯尼迪马克盖伊 2 约翰肯尼迪奥利维尔奥斯陆 2 不是 john vijay balebail 1 下载 CSV 3 行 selected。 报表 7 select t1.*, 解码 (count(c1||c2) over (partition by c1,c2 order by c1,c2 ),1,0,1) 来自 t1

的标志
C1      C2      C3      C4       FLAG
John    Kennedy Marc    Guy         1
John    Kennedy Olivier Oslo        1
not     john    vijay   balebail    0

谢谢大家!看来那个案子确实有很多解决办法!

我会继续深入研究,看看我最喜欢哪一个,但多亏了你,它让我对 SQL 逻辑有了很好的了解

抱歉,我的回复延迟了,因为工作不在