1

我在使用 SQL 方面相对较新,所以我希望您能就一个案例提供帮助。

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

| 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 中的重复项

使表格看起来像这样:

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

我的想法是创建一个标志列,条件是列 FName_LVL1 和 LName_LVL1 中的上方或下方的 IF 行相同,然后输入“1”,否则输入“0”

有一个看起来像这样的列:

| 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

有了这样的表格后,我可以过滤并获得想要的结果。

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

4

6 回答 6

2

您可以使用count()with window功能。

SQL小提琴

查询 1

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

结果

| 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 |
于 2018-04-18T17:59:16.173 回答
0

no_of_records是一列,它告诉您组合在表中出现的次数。即在您的示例表中它将是 2

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
于 2018-04-18T17:58:22.657 回答
0

您可以使用“半连接”子查询来获得这样的结果:

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 |
于 2018-04-18T18:01:39.990 回答
0

您可能更喜欢使用LAG&LEAD具有以下贡献的分析函数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 小提琴演示

于 2018-04-18T18:25:18.380 回答
0

最有效的方法是使用 partition by 子句只进行一次表扫描。我已将输出保存在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 FLAG John Kennedy Marc Guy 2 John Kennedy Olivier Oslo 2 not john vijay balebail 1 下载 CSV 3 行已选择。语句 7 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 标志
约翰肯尼迪马克盖伊 1
约翰肯尼迪奥利维尔奥斯陆 1
不是约翰·维杰·巴勒拜尔 0
于 2018-04-18T18:33:25.887 回答
0

嗯谢谢大家!看来这个案子确实有很多解决方案!

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

对不起,我的回复延迟,因为工作而离开

于 2018-04-20T11:00:54.773 回答