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
SQL在列表A中选择,但即使不在列表A中也创建行_Sql_Oracle - Fatal编程技术网

SQL在列表A中选择,但即使不在列表A中也创建行

SQL在列表A中选择,但即使不在列表A中也创建行,sql,oracle,Sql,Oracle,我尝试过寻找解决方案,但找不到任何解决方案。如果重复,请指向正确的方向 [问题] 我想查询用户ID列表(('hunter1','hunter2','hunter3')),并检查他们是否同意我们的隐私政策。 然而,这里有一个问题-即使用户ID不在我们的数据库中,我也需要一个带有“N”的用户ID的行来表示策略协议状态 [原样:当前查询] 查询说明:单个userID可以有多个条目,因为该用户可能已经加入并离开并再次加入简单地说,如果可以多次找到该用户ID,该查询将返回该用户ID及其状态,其中该用户ID

我尝试过寻找解决方案,但找不到任何解决方案。如果重复,请指向正确的方向

[问题]
我想查询用户ID列表(
('hunter1','hunter2','hunter3')
),并检查他们是否同意我们的隐私政策。
然而,这里有一个问题-即使用户ID不在我们的数据库中,我也需要一个带有“N”的用户ID的行来表示策略协议状态

[原样:当前查询]

查询说明:单个userID可以有多个条目,因为该用户可能已经加入并离开并再次加入简单地说,如果可以多次找到该用户ID,该查询将返回该用户ID及其状态,其中该用户ID具有最高的序列号。

SELECT
    userID,
    policyAgreementStatus
FROM
    MEMBERTABLE m
WHERE
    userNoSeq IN (
        SELECT
            MAX(userNoSeq)
        FROM
            MEMBERTABLE
        WHERE
            m.userID = MEMBERTABLE.userID AND MEMBERTABLE.userID IN 
                 ('hunter1', 'hunter2', ...)
    )
ORDER BY userNoSeq;
如果表中不存在“hunter1”,则上述查询将返回如下内容

userID      policyAgreementStatus
-----------------------------------
hunter2             Y
hunter3             N
...
[未来]

我想要返回的结果:

userID      policyAgreementStatus
-----------------------------------
hunter1             N
hunter2             Y
hunter3             N
即使亨特一开始不在名单上

我能想到的最简单的方法是创建一个临时表或使用PL/SQL集合并将其与原始表联接。
但是,我正在处理一个只读数据库,所以这是不可能的。

任何想法都会有帮助。谢谢。

使用集合不需要创建对象,有一些内置的。例如,您可以将ID列表作为一个表提供,将其扩展为单个元素,然后将其左键连接到实际表:

WITH userIDs (userID) AS (
    SELECT
        column_value
    FROM
        TABLE(SYS.ODCIVARCHAR2LIST('hunter1', 'hunter2', 'hunter3'))
)
SELECT
    u.userID,
    COALESCE (
        MAX(m.policyAgreementStatus) KEEP (DENSE_RANK LAST ORDER BY m.userNoSeq),
        'N'
    ) AS policyAgreementStatus
FROM
    userIDs u
LEFT JOIN
    MEMBERTABLE m
ON
    m.userID = u.userID
GROUP BY
    u.userID
ORDER BY userID;
当不存在匹配项时,
coalesce()
提供默认的N值,因为左连接将保留该空值。我已经从您的子选择切换,因为它有点短,但您最初的查询仍然可以工作


您可能已经有了自己的集合类型,具体实现方式取决于值列表的来源以及如何(或如何)提供给查询。

使用集合不需要创建对象,有一些内置对象。例如,您可以将ID列表作为一个表提供,将其扩展为单个元素,然后将其左键连接到实际表:

WITH userIDs (userID) AS (
    SELECT
        column_value
    FROM
        TABLE(SYS.ODCIVARCHAR2LIST('hunter1', 'hunter2', 'hunter3'))
)
SELECT
    u.userID,
    COALESCE (
        MAX(m.policyAgreementStatus) KEEP (DENSE_RANK LAST ORDER BY m.userNoSeq),
        'N'
    ) AS policyAgreementStatus
FROM
    userIDs u
LEFT JOIN
    MEMBERTABLE m
ON
    m.userID = u.userID
GROUP BY
    u.userID
ORDER BY userID;
当不存在匹配项时,
coalesce()
提供默认的N值,因为左连接将保留该空值。我已经从您的子选择切换,因为它有点短,但您最初的查询仍然可以工作


您可能已经有自己的集合类型可用,具体实现方式取决于值列表来自何处以及如何(或如何)提供给查询。

您可以使用
LEFT
外部联接和
MAX
分析函数。CTE保存所有用户ID

with h(userID) as
(
  select 'hunter1' from dual union all 
  select 'hunter2' from dual union all 
  select 'hunter3' from dual 
)
SELECT userID,
    COALESCE(policyAgreementStatus,'N') AS policyAgreementStatus
FROM
( SELECT
    h.userID,
    m.userNoSeq,
    m.policyAgreementStatus,
    COALESCE (
        MAX(m.userNoSeq) OVER (partition by h.userID ),
        0
    ) AS max_userNoSeq
FROM
    h 
LEFT OUTER JOIN
    MEMBERTABLE m
ON m.userID = h.userID
    ) WHERE max_userNoSeq IN ( userNoSeq,0) ;

您可以使用
LEFT
外部联接和
MAX
分析函数。CTE保存所有用户ID

with h(userID) as
(
  select 'hunter1' from dual union all 
  select 'hunter2' from dual union all 
  select 'hunter3' from dual 
)
SELECT userID,
    COALESCE(policyAgreementStatus,'N') AS policyAgreementStatus
FROM
( SELECT
    h.userID,
    m.userNoSeq,
    m.policyAgreementStatus,
    COALESCE (
        MAX(m.userNoSeq) OVER (partition by h.userID ),
        0
    ) AS max_userNoSeq
FROM
    h 
LEFT OUTER JOIN
    MEMBERTABLE m
ON m.userID = h.userID
    ) WHERE max_userNoSeq IN ( userNoSeq,0) ;
我会这样做:

select m.userid,
       coalesce(max(mt.policyAgreementStatus) keep (dense_rank first order by userNoSeq desc),
                'N'
               ) as policyAgreementStatus
from (select 'hunter1' as userid from dual union all 
      select 'hunter2' from dual union all 
      select 'hunter3' from dual 
     ) m left join
     membertable mt
     on mt.userid = m.userid
group by m.userid;
您可以使用
keep
语法获取最新的
policyAgreementStatus
。我发现这在Oracle中非常有效。

我会这样做:

select m.userid,
       coalesce(max(mt.policyAgreementStatus) keep (dense_rank first order by userNoSeq desc),
                'N'
               ) as policyAgreementStatus
from (select 'hunter1' as userid from dual union all 
      select 'hunter2' from dual union all 
      select 'hunter3' from dual 
     ) m left join
     membertable mt
     on mt.userid = m.userid
group by m.userid;
您可以使用
keep
语法获取最新的
policyAgreementStatus
。我发现这在Oracle中非常有效