SQL删除Dups并保留更长的列值

时间:2018-08-22 20:56:44

标签: sql sas

我对 SAS 上的 SQL 有疑问,该问题类似于以下内容。

ID|LName|FName|Address
1 |A    |B    |1 Street
1 |A    |B    |1 Street **APT 101**
2 |A    |B    |1 Street
2 |A    |B    |1 Street **APT 101**

是否可以先检查ID,然后如果地址长于另一个,则保留更长的ID?


3 个答案:

答案 0 :(得分:2)

还有另一种选择。一个简单的MAX和group by应该可以解决问题:

addNode

See demo here.

警告:请记住,这将适用于具有相同“基本”地址和额外文本的行。例如:

SELECT id, lname, fname, max(address)
FROM test WHERE 1=1
GROUP BY id, lname, fname;

但是,如果您更改行的基址,它将“失败”:

insert into test values(1, 'A', 'B', '1 Street'); 
insert into test values(1, 'A', 'B', '1 Street APT 101'); 
insert into test values(1, 'A', 'B', '1 Street APT 101 Other APT 202'); 
insert into test values(1, 'A', 'B', '1 Street APT 101 Other APT 202 yet another APT 333');
etc.

但是,这些将是2个不同的地址,而不是具有额外信息的相同地址。因此,无论如何,丢弃其中任何一个(无论如何)都可能没有道理。

如果此限制不适用于您的输入数据,则可以安全地使用SQL。

如果您需要一个可通过检查长度来工作的SQL,则下一个SQL将在mysql,mariadb和SQLite上工作。您必须检查您的dbms。

insert into test values(1, 'A', 'B', '1 Street APT 101'); 
insert into test values(1, 'A', 'B', '1 Street APT 2'); # This is shorter but will come up instead of the other.

请参见演示 here

答案 1 :(得分:0)

这很棘手,但是您可以这样做:

select t.*
from t
where t.address = (select t2.address
                   from t t2
                   where t2.id = t.id
                   order by length(t2.address) desc
                  );

答案 2 :(得分:0)

您可以在数据上按行编号,并按“地址”列的长度排序。 https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-2017

会是这样的:

select id 
    ,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Length(address) DESC)
    ,LName
    ,FName
    ,Address
from table_name;

然后仅对行号= 1进行过滤。