将两个 select 语句与外部连接连接在一起

Posted

技术标签:

【中文标题】将两个 select 语句与外部连接连接在一起【英文标题】:Joining two select statements together with outer join 【发布时间】:2020-11-13 20:56:40 【问题描述】:

我在 SQL Server 上的查询:

select 
    s.learners_id, s.cv_student_id, 
    s.first_name + ' ' + s.last_name student_name,
    p.program_name, dc.fulldate program_start_date, 
    sd.discount_value, dt.type_name
from
    fact_student_programs_t sp 
left join 
    object_sTATUSES_T os on os.object_statusid = sp.status_id
inner join 
    dim_programs_t p on p.programs_sk_id = sp.programs_sk_id
left join 
    dim_calendar dc on dc.datekey = sp.start_date_key
inner join 
    dim_students_t s on s.students_sk_id = sp.students_sk_id
outer join 
    (select 
         s.learners_id, sd.discount_value, dt.type_name
     from 
         fact_student_discountS_T sd 
     inner join 
         discount_types_t dt on dt.id = sd.discount_type_id
     inner join 
         dim_students_t s on s.students_sk_id = sd.students_sk_id
     where 
         sd.curr_in = 1) discounts on discounts.learners_id = s.learners_id
where 
    sp.curr_in = 1  
    and dc.fulldate is not null 
    and os.status_name in ('Active') 
    and s.learners_id in ('201328', '237744', '237817', '239826', '308486', '308961',
                          '308973', '309352', '311521', '312269', '312951',
                          '313254', '313289', '384170', '384224', '384228', 
                          '408911', '408912', '408936', '411293', '411308',
                          '411322', '411324', '411325', '411352', '411413',
                          '411417', '412865', '412923')

我正在尝试加入这两个查询,但遇到了问题。外连接语句是不是放错地方了?有人可以帮我修复此代码吗?

编辑: 外连接在这里不是有效的语法,所以我使用左连接。查询仍然返回错误:

Msg 4104, Level 16, State 1. The multi-part identifier "dt.type_name" could not be bound. Msg 4104, Level 16, State 1. The multi-part identifier "sd.discount_value" could not be bound. (Line 2)

【问题讨论】:

请查看允许的 SQL Server 语法,以及它在此处返回的数据的可视化表示:sqlservertutorial.net/sql-server-basics/sql-server-joins 【参考方案1】:

总结

outer join 是not valid in SQL Server/t-sql 我相信。它应该是left outer joinright outer joinfull outer join

在您的情况下,我怀疑您希望它是 left outer join

说明/加长版

在左外连接和右外连接中,“左”和“右”指的是连接上左右两侧的表/等(例如,分别在连接之前和之后)。

在左外连接中,它获取左侧表(第一个表)中的所有值以及右侧表中的任何匹配行 在右外连接中,它获取右侧表(第二个表)中的所有值以及左侧表中的所有匹配行

完全外连接从两个表中获取所有行,并尽可能匹配它们。

这是一个例子

/* Data setup */
CREATE TABLE #T1 (T1_ID int);
CREATE TABLE #T2 (T2_ID int);
INSERT INTO #T1 (T1_ID) VALUES (1), (2);
INSERT INTO #T2 (T2_ID) VALUES (1), (3);

/* Example joins */
SELECT #T1.T1_ID, #T2.T2_ID
FROM #T1
LEFT OUTER JOIN #T2 ON #T1.T1_ID = #T2.T2_ID;

SELECT #T1.T1_ID, #T2.T2_ID
FROM #T1
RIGHT OUTER JOIN #T2 ON #T1.T1_ID = #T2.T2_ID;

SELECT #T1.T1_ID, #T2.T2_ID
FROM #T1
FULL OUTER JOIN #T2 ON #T1.T1_ID = #T2.T2_ID;

/* Results
-- LEFT OUTER JOIN
T1_ID   T2_ID
1       1
2       NULL

-- RIGHT OUTER JOIN
T1_ID   T2_ID
1       1
NULL    3

-- FULL OUTER JOIN
T1_ID   T2_ID
1       1
2       NULL
NULL    3
*/

鉴于您的 WHERE 子句中有 WHERE s.learners_id in (...),这意味着您不希望 s.learners 为 NULL 的行。

如果您有右外连接,则 WHERE 要求将有效地将右外连接转换为内连接(因为它会排除 s.learners_id 为 NULL 的所有行)。 如果您有完全外连接,那么 WHERE 要求将有效地将完全外连接变成左外连接 - 沿着类似的逻辑线。

【讨论】:

感谢您的回复。是的,左连接是我需要的。此代码不运行。我的错误信息是:Msg 4104, Level 16, State 1. The multi-part identifier "dt.type_name" could not be bound. Msg 4104, Level 16, State 1. The multi-part identifier "sd.discount_value" could not be bound. (Line 2) 因为别名为sd的表是子查询的一部分,所以外层查询看不到表本身;外部查询只能是别名为discounts 的子查询。尝试在外部选择中使用discounts.type_namediscounts.discount_value

以上是关于将两个 select 语句与外部连接连接在一起的主要内容,如果未能解决你的问题,请参考以下文章

SQL连接两个SELECT语句的麻烦

将游标适配器与多个表游标一起使用(内连接)

将左连接与两个选择语句一起使用时的不同值

将 Dapper MultiMapper 与外部连接查询一起使用

SQL多表链接查询、嵌入SELECT语句的子查询技术

如何将两个 DataTable 与内部连接连接在一起