Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle SQL中选择唯一行并忽略空值_Sql_Oracle - Fatal编程技术网

在Oracle SQL中选择唯一行并忽略空值

在Oracle SQL中选择唯一行并忽略空值,sql,oracle,Sql,Oracle,有一个表有四列:客户、城市、邮政编码和街道。对于每个客户端,我要计算唯一地址的数量。不幸的是,某些列中可能有空值:城市、邮政编码或街道。在比较计数时,我必须忽略它们。所以这不能通过简单的分组和计数来解决 例如,有 'client1', 'city1', 'postcode1', 'street1' 'client1', 'city1', 'postcode1', null 'client1', 'city1', null, 'street1' 'client1', null, null, 'st

有一个表有四列:客户、城市、邮政编码和街道。对于每个客户端,我要计算唯一地址的数量。不幸的是,某些列中可能有空值:城市、邮政编码或街道。在比较计数时,我必须忽略它们。所以这不能通过简单的分组和计数来解决

例如,有

'client1', 'city1', 'postcode1', 'street1'
'client1', 'city1', 'postcode1', null
'client1', 'city1', null, 'street1'
'client1', null, null, 'street2'

'client1', 'city2', null, 'street1'
'client1', 'city2', null, 'street2'
对于我的任务,应编辑唯一地址

所以答案是客户的3个唯一地址1, 但对于标准的distinct子句,这些都是唯一的,例如行

'client1', 'city1', 'postcode1', 'street1'
'client1', 'city1', 'postcode1', null
'client1', 'city1', null, 'street1'
它们被视为不同的,而对于我的任务,它们没有什么不同,我想将它们计算为1

在一些评论之后编辑: 如果我们有

'client1', null, null, 'street3'
那么这是一个唯一的地址,因为没有其他带有“street3”的地址,应该计入。

您可以按如下方式使用min分析功能:

Select distinct t.client,
       t.city,
       Coalesce(t.postcode,Min(t.postcode) over (partition by t.client, t.city)) as postcode,
       Coalesce(t.street,Min(t.street) over (partition by t.client, t.city)) as street
  From your table
 Where city is not null;
-更新

我可以想出一个自助解决方案,看看它是否适合你

Select distinct a.client,
       Coalesce(a.city, b.city) as city,
       Coalesce(a.postcode, b.postcode) as postcode,
       Coalesce(a.street, b.street) as street
  From your_table a left join your_table b
    On a.client = b.client
   And (a.city = b.city or (a.city is null or b.city is null))
   And (a.postcode = b.postcode or (a.postcode is null or b.postcode is null))
   And (a.street = b.street or (a.street is null or b.street is null))
   And a.rowid <> b.rowid
       

我已经用PL/SQL解决了我的问题。代码相当长,因此我将只给出想法的概要,以防有人感兴趣

我们创建一个具有不同元组的表。这是我们的输入表

我们在输出表中插入三个非空值的元组,因为它们不会被任何其他缺少值的元组覆盖

我们向输出表插入两个非空值的元组。这里我们从2中过滤元组覆盖的元组

我们向输出表插入一个非空值的元组。在这里,我们从2和3中过滤元组覆盖的元组


我认为这个解决方案没有反例。

我不明白。为什么第四排和第六排都有?它们具有相同的街道,其他列要么匹配,要么为空。您是对的。答案是3。我已经编辑了这个问题。谢谢你的努力。这很有趣,但是,我根据戈登·林多夫的评论编辑了我的问题。很抱歉造成混淆,不应计算client1、null、null、street2行。因此,在查询中如何处理城市是一个问题。能修好吗?可能需要另一种方法?您必须需要三列中的一列不为null,因此我相应地更新了答案。在示例中,“client1”,null,null,“street2”被拒绝,因为存在“client1”,“city2”,null,“street2”,而不是因为city一般不能为null。现在,对于给定的示例,查询工作得很好,但是如果我们有'client1',null,null,'street3',那么您的查询将不会选择该元组。我希望这个元组被计算在内,因为它是一个唯一的地址,也就是说,没有其他带有“street3”的地址。不幸的是,更新后的查询为“client1”、null、null、“street3”的扩展问题提供了九个地址。包括那些不存在的,比如“client1”、“city1”、“postcode1”、“street3”。现在就试试更新的。在更新的查询中几乎没有更改。
Select distinct a.client,
       Coalesce(a.city, b.city) as city,
       Coalesce(a.postcode, b.postcode) as postcode,
       Coalesce(a.street, b.street) as street
  From your_table a left join your_table b
    On a.client = b.client
   And (a.city = b.city or (a.city is null or b.city is null))
   And (a.postcode = b.postcode or (a.postcode is null or b.postcode is null))
   And (a.street = b.street or (a.street is null or b.street is null))
   And a.rowid <> b.rowid