Sql 一对二关系连接
在表2中,每个T_代码(AB和AC)应有2个E_编号(55和56) 我想连接这两个表以显示所有的T_代码和E_编号。如果在表2中不可用,则应显示NULL 表-1Sql 一对二关系连接,sql,oracle,join,Sql,Oracle,Join,在表2中,每个T_代码(AB和AC)应有2个E_编号(55和56) 我想连接这两个表以显示所有的T_代码和E_编号。如果在表2中不可用,则应显示NULL 表-1 T_NO T_Code 1 AB 1 AC 2 AB 3 AB 3 AC 4 AC 表-2 T_NO T_Code E_NO 1 AB 55 1 AC 56 2 AB 55
T_NO T_Code
1 AB
1 AC
2 AB
3 AB
3 AC
4 AC
表-2
T_NO T_Code E_NO
1 AB 55
1 AC 56
2 AB 55
3 AC 55
3 AC 56
3 AB 55
3 AB 56
4 AC 55
结果
T_NO T_Code E_NO
1 AB 55
1 **AB** **56**
1 AC 56
1 (null) (null) -> AC 55
2 AB 56
2 **AB** **55**
3 AC 55
3 AC 56
3 AB 55
3 AB 56
4 AC 55
4 **AC** **56**
你们能帮我问一下吗
我尝试在表1和表2之间应用左外部联接,但由于这是一对二关系,因此表2中不可用的记录不会出现NULL
谢谢马特和维切利
我正在尝试的另一件事是用缺少的字段填充(null)。我正在使用一些逻辑来尝试PL-SQL,但有没有简单的方法来实现这一点是我的问题。使用辅助视图(aux
)并与之交叉连接
with aux as (select 55 as e_no from dual
union all
select 56 as e_no from dual)
select t1.T_NO, t2.T_CODE, t2.E_NO
from table1 t1 cross join aux a
left join table2 t2 on t1.T_NO = t2.T_NO
and t1.T_CODE = t2.T_CODE
and a.E_NO = t2.E_NO;
使用辅助视图(aux
)并与其交叉连接
with aux as (select 55 as e_no from dual
union all
select 56 as e_no from dual)
select t1.T_NO, t2.T_CODE, t2.E_NO
from table1 t1 cross join aux a
left join table2 t2 on t1.T_NO = t2.T_NO
and t1.T_CODE = t2.T_CODE
and a.E_NO = t2.E_NO;
假设3和4应返回所有空值,因为没有匹配项:
WITH cteAllPossibleCombinations AS (
SELECT DISTINCT t.T_NO, c2.T_code, c.E_NO
FROM
Table1 t
CROSS JOIN (SELECT 55 as E_NO from dual UNION SELECT 56 from dual) c
CROSS JOIN (SELECT 'AB' as T_code from dual UNION SELECT 'AC' from dual) c2
)
SELECT
c.T_NO
,t.T_Code
,t.E_NO
FROM
cteAllPossibleCombinations c
LEFT JOIN Table2 t
ON c.T_NO = t.T_NO
AND c.T_code = t.T_Code
AND c.E_NO = t.E_NO
当表1中缺少“AB”或“AC”时,此答案也适用
根据您的评论进行编辑。因此,我仍然不清楚你想要什么来填补空白。如果您不想区分它是否存在,只想知道所有可能的组合,请忘记上面的第二个选择,只需选择
SELECT * FROM cteAllPossibleCombinations
如果您想区分哪些匹配,哪些不匹配,这里有一个查询可以帮助您理解:
SELECT
c.T_NO
,COALESCE(t.T_Code,'**' + c.T_Code) AS T_Code
,COALESCE(CAST(t.E_NO AS VARCHAR(10)),CAST(c.E_NO AS VARCHAR(10)) + '**') as E_No
,CASE WHEN t.T_Code IS NULL THEN 'NO' ELSE 'yes' END as Matched
FROM
cteAllPossibleCombinations c
LEFT JOIN @Table2 t
ON c.T_NO = t.T_NO
AND c.T_code = t.T_Code
AND c.E_NO = t.E_NO
注意,后面的两段代码都需要CTE。假设3和4应该返回所有空值,因为没有匹配项:
WITH cteAllPossibleCombinations AS (
SELECT DISTINCT t.T_NO, c2.T_code, c.E_NO
FROM
Table1 t
CROSS JOIN (SELECT 55 as E_NO from dual UNION SELECT 56 from dual) c
CROSS JOIN (SELECT 'AB' as T_code from dual UNION SELECT 'AC' from dual) c2
)
SELECT
c.T_NO
,t.T_Code
,t.E_NO
FROM
cteAllPossibleCombinations c
LEFT JOIN Table2 t
ON c.T_NO = t.T_NO
AND c.T_code = t.T_Code
AND c.E_NO = t.E_NO
当表1中缺少“AB”或“AC”时,此答案也适用
根据您的评论进行编辑。因此,我仍然不清楚你想要什么来填补空白。如果您不想区分它是否存在,只想知道所有可能的组合,请忘记上面的第二个选择,只需选择
SELECT * FROM cteAllPossibleCombinations
如果您想区分哪些匹配,哪些不匹配,这里有一个查询可以帮助您理解:
SELECT
c.T_NO
,COALESCE(t.T_Code,'**' + c.T_Code) AS T_Code
,COALESCE(CAST(t.E_NO AS VARCHAR(10)),CAST(c.E_NO AS VARCHAR(10)) + '**') as E_No
,CASE WHEN t.T_Code IS NULL THEN 'NO' ELSE 'yes' END as Matched
FROM
cteAllPossibleCombinations c
LEFT JOIN @Table2 t
ON c.T_NO = t.T_NO
AND c.T_code = t.T_Code
AND c.E_NO = t.E_NO
注意,后面的两段代码都需要CTE。给你:
SELECT C.E_NO, C.T_CODE, T2.T_NO
FROM (
SELECT E_NO.E_NO, T_CODE.T_CODE
FROM ( VALUES (55), (56) ) AS E_NO(E_NO),
( VALUES ('AB'), ('AC') ) AS T_CODE(T_CODE)
) AS C
LEFT JOIN Table-2 AS T2 ON (C.E_NO, C.T_CODE) = (T2.E_NO, T2.T_CODE)
这会给你一个T2.T_NO的值。如果您想插入缺失的部分,则只需使用上面的查询,而是添加,其中T2.T\u NO为null
,您将得到“缺失”部分的列表。给您:
SELECT C.E_NO, C.T_CODE, T2.T_NO
FROM (
SELECT E_NO.E_NO, T_CODE.T_CODE
FROM ( VALUES (55), (56) ) AS E_NO(E_NO),
( VALUES ('AB'), ('AC') ) AS T_CODE(T_CODE)
) AS C
LEFT JOIN Table-2 AS T2 ON (C.E_NO, C.T_CODE) = (T2.E_NO, T2.T_CODE)
这会给你一个T2.T_NO的值。如果您想插入缺失的部分,那么只需使用上面的查询,而是添加
,其中T2.T\u NO为null
,您将得到“缺失”部分的列表。因此表1的T\u NO 3和4应全部为null或不包括在结果集中?表1和表2之间的关系是什么?例如,对于T_NO=2,表_1只有T_代码=AB,但在表_2中仍然有T_NO=2和T_代码=AC。那么这与表_1有什么关系?那么-表2中是否有重复项,如果有,结果会怎样?如果对应的对不在表2中,您只是想在T_代码和E_NO中添加带有null的行吗?对于表1中的T_NO=2和T_Code=AB,只有两行与表2(其中T_Code=AB)匹配,对于T_NO=2和T_Code=AC,您的结果不同,可能它必须有空值?所以表1的T_NO 3和4应该都是空值或不包括在结果集中?表_1和表_2之间的关系是什么?例如,对于T_NO=2,表_1只有T_代码=AB,但在表_2中仍然有T_NO=2和T_代码=AC。那么这与表_1有什么关系?那么-表2中是否有重复项,如果有,结果会怎样?如果对应的对不在表2中,您只是想在T_Code和E_NO中添加带有null的行吗?对于表1中的T_NO=2和T_Code=AB,只有两行与表2匹配(其中T_Code=AB),对于T_NO=2和T_Code=AC,您的结果不同,可能是它必须具有null值,而不是union(或union all)使用如下交叉连接(值(55),(56))c交叉连接(值('AB'),('AC'))c2感谢Matt和Vercelli。我正在尝试的另一件事是用缺少的字段填充(null)。我正在使用一些逻辑来尝试PL-SQL,但有没有简单的方法来实现这一点是我的问题。只需从cteAllPossibleCombinations中选择*,它将为表1中的每个T_No提供4行组合,如果您想区分匹配的和未匹配的,您可以合并()或case语句。因此,您是否希望任何null变为**值**值?????表1包含4AC**表2仅包含4AC55和56,因此我希望将4AC56插入表2中,类似于2AB**56,而不是union(或union all)使用以下语句交叉连接(值(55),(56))c交叉连接(值('AB'),('AC'))c2
谢谢马特和维切利。我正在尝试的另一件事是用缺少的字段填充(null)。我正在使用一些逻辑来尝试PL-SQL,但有没有简单的方法来实现这一点是我的问题。只需从cteAllPossibleCombinations中选择*,它将为表1中的每个T_No提供4行组合,如果您想区分匹配的和未匹配的,您可以合并()或case语句。因此,您是否希望任何空值变为**值**值?????表1有4AC**表2只有4AC55和56缺失,因此我希望4AC56插入表2中,类似于2AB**56,您应该使用如下值aux(e_no)作为(值(55),(56))
,而不是unionall@Hogan谢谢我会研究一下,你应该用像这样的值来代替并集,比如aux(e_no)as(values(55),(56))
all@Hogan谢谢,我会调查的