ORACLE SQL:仅返回后来加入或从主要渠道不同的非主要帐户持有人?

Posted

技术标签:

【中文标题】ORACLE SQL:仅返回后来加入或从主要渠道不同的非主要帐户持有人?【英文标题】:ORACLE SQL: Returning only non primary account holders who joined later or from different channel from primary? 【发布时间】:2016-06-24 19:55:11 【问题描述】:

我有以下数据,其中每个帐户 id 可以有多个关联的成员

ACCOUNT_ID  MEMBER_ENROLL_DTE   PRIMARY_FLG ENROLL_CHANNEL_ID                       
3021            3/22/2011           1           50
3022            3/23/2011           1           50
3022            1/2/2013            0           50
3023            3/23/2011           1           50
3024            3/23/2011           1           52
3025            3/23/2011           1           52
3025            3/23/2011           0           48
3026            3/23/2011           1           52
3026            3/23/2011           0           52

我正在尝试执行以下操作: 如果同一帐户中有多个成员,如果注册日期或注册渠道不同,则返回这些记录。

即我想按account_id进行分区,然后按注册日期、注册通道和primary_flg排序,然后返回primary标志设置为0且日期和通道与主账户持有人不同的记录(PRIMARY_FLG = 1) .在这种情况下,我会得到两条记录

ACCOUNT_ID  MEMBER_ENROLL_DTE   PRIMARY_FLG ENROLL_CHANNEL_ID                        
3022            1/2/2013            0           50      
3025            3/23/2011           0           48

我最关心的是如何处理注册日期或注册渠道不同的条件。通过执行以下操作,我可以获得所有非初选

SELECT *
FROM   (
  SELECT t.*,
         LAG( CASE "Primary" WHEN 1 THEN 1 END ) IGNORE NULLS
           OVER ( PARTITION BY account_id ORDER BY MEMBER_ENROLL_DTE, PRIMARY_FLG, ENROLL_CHANNEL_ID )
           AS has_prev_primary
  FROM   table_name t
)
WHERE  has_prev_primary = 1;

我认为这甚至可以做我想做的事,但我不是 100% 确定 - 它似乎不会返回同一天加入的成员,但我不知道为什么。有人可以提出必要的更改吗?

【问题讨论】:

您能解释一下the primary account holder 是什么吗?您如何知道给定记录代表主要帐户持有人,而其他记录不代表? 嗨,这是 PRIMARY_FLG - 我会更清楚地说明 【参考方案1】:

原始答案获取不匹配的帐户 ID 的所有条目。这在许多情况下对我来说似乎更有用。

SELECT t.account_id, t.primary_flg, t.member_enroll_dte, t.enroll_channel_id
FROM table_name t
WHERE t.account_id IN (
    SELECT account_id
    FROM table_name t2
    GROUP BY account_id
    HAVING min(primary_flg) != max(primary_flg)
    AND NOT (
        min(member_enroll_dte) = max(member_enroll_dte) AND
        min(enroll_channel_id) = max(enroll_channel_id)
    )
)
ORDER BY 1,2 desc,3,4;

替代答案只会给您不匹配的非主要记录,仅此而已。

SELECT t.account_id, t.primary_flg, t.member_enroll_dte, t.enroll_channel_id
FROM table_name t
WHERE t.primary_flg = 0
AND NOT EXISTS (
    SELECT null
    FROM table_name t_sub
    WHERE t_sub.account_id = t.account_id
    AND t_sub.primary_flg = 1
    AND t_sub.member_enroll_date = t.member_enroll_date
    AND t_sub.enroll_channel_id = t.enroll_channel_id )
ORDER BY 1,3,4

试试这个你在 cmets 中提到的查询,其中非主要应该在主要之后。

SELECT t.account_id, t.primary_flg, t.member_enroll_dte, t.enroll_channel_id
FROM table_name t
WHERE t.primary_flg = 0
AND NOT EXISTS (
    SELECT null
    FROM table_name t_sub
    WHERE t_sub.account_id = t.account_id
    AND t_sub.primary_flg = 1
    AND t_sub.enroll_channel_id = t.enroll_channel_id
    AND t_sub.member_enroll_date >= t.member_enroll_date )
ORDER BY 1,3,4

【讨论】:

嗯,我看到主要成员和非主要成员的注册日期/频道与主要成员的注册日期/频道相同 已编辑。直到现在才注意到另一个答案。 谢谢,效果很好。我现在唯一遇到的问题是,有时主要在非主要之后被列为已注册(这将是一个数据问题)。如何添加条件以仅包括注册日期大于主要日期的非主要对象?我尝试只添加“AND t_sub.MEMBER_ENROLL_DTE > t.MEMBER_ENROLL_DTE”,但这让我得到了奇怪的结果...... 我编辑了答案以包含针对该场景的单独查询。【参考方案2】:

试试:

select * from table1 t1
where primary_flg = 0
  and NOT exists (
     select 123 + 786 from table1 t2
     where t1.account_id = t1.account_id
       and t2.primary_flg = 1
       and t2.member_enroll_dte = t1.member_enroll_dte
       and t2.ENROLL_CHANNEL_ID = t1.ENROLL_CHANNEL_ID
)

【讨论】:

以上是关于ORACLE SQL:仅返回后来加入或从主要渠道不同的非主要帐户持有人?的主要内容,如果未能解决你的问题,请参考以下文章

Hive SQL计算5天前的时间戳

ORACLE SQL仅返回重复值(不是原始值)

如何仅使用 Oracle SQL 返回 2 个字符串之间的差异

Maximo/Oracle SQL 语句从连接表中返回不需要的数据

使用 t-sql 仅加入“最新”记录

关于Oracle程序块(主要为sql)优化方法小结