使用外连接将两个 select 语句连接在一起
Joining two select statements together with outer join
我在 SQL 服务器上的查询:
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')
我正在尝试加入这两个查询,但遇到了问题。外连接语句是不是放错地方了?有人可以帮我修复此代码吗?
编辑:
外部连接在这里不是有效语法,所以我使用左连接。查询仍然 returns 错误:
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)
总结
outer join
是 not valid in SQL Server/t-sql 我相信。它应该是 left outer join
、right outer join
或 full outer join
.
在你的情况下,我怀疑你希望它是 left outer join
。
Explanation/longer版本
在左外连接和右外连接中,'left' 和 'right' 指的是 tables/etc 字面意义上的左右连接(例如,连接前后,分别)。
- 在左外连接中,它获取左侧 table 中的所有值(第一个 table)和右侧 table 中的所有匹配行
- 在右外连接中,它获取右侧 table 中的所有值(第二个 table)和左侧 table 中的所有匹配行
完全外部联接从两个 table 中获取所有行,并尽可能匹配它们。
这是一个例子
/* 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 要求将有效地将完全外部联接转变为左外部联接 - 沿着类似的逻辑线路。
我在 SQL 服务器上的查询:
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')
我正在尝试加入这两个查询,但遇到了问题。外连接语句是不是放错地方了?有人可以帮我修复此代码吗?
编辑: 外部连接在这里不是有效语法,所以我使用左连接。查询仍然 returns 错误:
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)
总结
outer join
是 not valid in SQL Server/t-sql 我相信。它应该是 left outer join
、right outer join
或 full outer join
.
在你的情况下,我怀疑你希望它是 left outer join
。
Explanation/longer版本
在左外连接和右外连接中,'left' 和 'right' 指的是 tables/etc 字面意义上的左右连接(例如,连接前后,分别)。
- 在左外连接中,它获取左侧 table 中的所有值(第一个 table)和右侧 table 中的所有匹配行
- 在右外连接中,它获取右侧 table 中的所有值(第二个 table)和左侧 table 中的所有匹配行
完全外部联接从两个 table 中获取所有行,并尽可能匹配它们。
这是一个例子
/* 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 要求将有效地将完全外部联接转变为左外部联接 - 沿着类似的逻辑线路。