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中非常有效