【问题标题】:Get rows only missing a certain type of row获取仅缺少特定类型行的行
【发布时间】:2021-02-23 11:36:37
【问题描述】:

我试图寻找没有特定地址类型的客户,从这里开始:

SELECT C.NAME, CA.ADDRESSTYPE, CA.ADDRESS
FROM CUSTOMER C
INNER JOIN CUSTOMERADDRESS CA
ON CA.CUSTOMERUUID = C.UUID
NAME ADDRESSTYPE ADDRESS
Paul Invoice ...
Paul Shipping ...
Paul Shipping ...
Bill Shipping ...

我怎样才能只从没有发票或送货地址的客户那里获得价值,在这种情况下是账单(缺少发票)

NAME ADDRESSTYPE ADDRESS
Bill Shipping ...

唯一的想法(不好的?),我的想法是 GROUP BY、LISTAGG 地址类型,然后选择具有 LISTAGG(...) LIKE '%Invoice%' AND LIKE '%Shipping'% 的行,但我想想大量的地址来解析这样的字符串。

提前致谢:)

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    嗯。 . .生成所有客户和地址类型的列表,然后过滤掉存在的:

    select ca.name, adt.addresstype
    from customer c cross join
         (select 'Invoice' as addresstype from dual union all
          select 'Shipping' as addresstype from dual
         ) adt left join
         customeraddress ca
         on ca.name = c.name and ca.addresstype = adt.addresstype
    where ca.name is null;
      
    

    【讨论】:

      【解决方案2】:

      我会使用内部选择来列出符合条件的用户 ID,然后加入此列表只是为了删除不相关的内容:

      select c.name, ca.addresstype, ca.address
      from customer c 
      join customeraddress ca on ca.customeruuid = c.uuid
      join (
          select customeruuid 
          from customeraddress 
          where addresstype in ('Invoice', 'Shipping')
          group by customeruuid
          having count(*) < 2
      ) t on t.customeruuid = c.uuid
      

      【讨论】:

        【解决方案3】:

        这可能是一种方法,通过计算每个客户的给定类型地址的出现次数(内部查询),然后使用此计数作为过滤器以仅获取缺少地址的客户:

        select NAME, ADDRESSTYPE, ADDRESS
        from
        (
            select c.name, ca.ADDRESSTYPE, ca.ADDRESS,
                   count(case when ADDRESSTYPE ='Invoice'  then 1 end) over (partition by c.name) as n_invoice,
                   count(case when ADDRESSTYPE ='Shipping' then 1 end) over (partition by c.name) as n_shipping 
            from customer C
                inner join CUSTOMERADDRESS ca
                  on CA.CUSTOMERUUID = C.UUID
        )
        where n_invoice = 0 OR n_shipping = 0 
        

        使用像您这样的数据,这将给出:

        NAME ADDRESSTYPE ADDRESS
        ---- ----------- -------
        Bill Shipping    ...
        

        【讨论】:

          【解决方案4】:

          我使用了 COUNT() OVER() 来计算“送货”地址和其他地址(我可以有多个“发票”),并且只得到 >= 1(最少 1 个“送货”地址),然后加入删除好的。

          感谢大家的帮助/时间。

          问候。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-05
            • 1970-01-01
            相关资源
            最近更新 更多