[英]SQL Select Between Two tables
我有这两个表:
T1: ref || Name =========== 1 || A 2 || B 3 || C 4 || D 5 || E
和
T2: ref || Name =========== 1 || w 2 || x 6 || y 7 || z
我需要这个结果:
Name1 || Name2 ============== A || w B || x C || y D || z E || NULL
我的意思是在列ref上进行某种完全外部联接,直到没有任何记录,该联接才会产生NULL值。 连接的优先级是具有相同ref的值,如果表的行数不相等,则将出现一些NULL结果
使用UPD:以下是通过不同表中的值计数组合值的方法:
with t1_values as (
SELECT
name,
row_number() over (order by ref) as position
FROM #t1
),
t2_values as (
SELECT
name,
row_number() over (order by ref) as position
FROM #t2
)
SELECT
t1_values.name as name1,
t2_values.name as name2
FROM t1_values
left JOIN t2_values on t1_values.position = t2_values.position
这非常复杂。 您希望匹配的行匹配。 然后,您希望不匹配的行按位置匹配不匹配的行,然后按其他匹配。
with matches as (
select distinct t1.ref
from t1
where exists (select 1 from t2 where t2.ref = t1.ref)
),
tt1 as (
select t1.*, m.ref as match_ref,
row_number() over (partition by m.ref order by t1.ref) as alt_ref
from t1 left join
matches m
on t1.ref = m.ref
),
tt2 as (
select t2.*, m.ref as match_ref,
row_number() over (partition by m.ref order by t2.ref) as alt_ref
from t2 left join
matches m
on t2.ref = m.ref
)
select tt1.name, tt2.name
from tt1 left join
tt2
on tt1.match_ref = tt2.match_ref or
(tt1.match_ref is null and tt2.match_ref is null and tt1.alt_ref = tt2.alt_ref);
这是主意。 对于两个表中的每一行,添加两个新列:
match_ref
是ref
当ref
存在在另一个表中。 alt_ref
是不匹配的ref
值的枚举列。 一旦拥有这些列,就可以将表连接在一起,方法是先检查match_ref
,然后检查(如果不存在)检查alt.ref
。
SQL Fiddle似乎不适用于SQL Server。 但是, 这是可以使用的相同Postgres版本。 这是使用SQL Server的有效版本(与Postgres版本相同)。
如果我错了,请纠正我,但是您有两个表,其中的引用ID列的名称是您希望返回结果集的名称。...仅,您不会说不相同,因此可能会产生额外的结果。
...某种完全外部联接,在列ref上,除非没有任何记录,否则不会产生NULL值。JOIN的优先级是具有相同ref的值,并且如果表的行数不是相等,有一些NULL结果
实际上,结果并不是真正确定的。 无论如何,这个问题仍然太模糊了。 但是,我认为您真的只希望匹配列的行一起出现,而没有任何东西……嗯,不是。 但是归还一切。
因此,如果您知道哪一侧更大,请尝试以下操作:
WITH C AS (SELECT DENSE_RANK() OVER (PARTITION BY ref ORDER BY NAME DESC) AS ROW_ID
, ref
, Name AS Name1
FROM T1)
SELECT Name1, B.Name2
FROM C
LEFT OUTER JOIN (SELECT DENSE_RANK() (OVER PARTITION BY ref ORDER BY NAME DESC) AS ROW_ID
, ref
, Name AS Name2) B ON B.Row_ID = C.Row_ID AND B.ref = C.ref
每个ref列都有一个要附加的不同ID。 它以连续的顺序完成,因此,如果仍然存在问题,则可以弄清楚该逻辑。 但是我敢肯定,这将帮助您极大地到达想要的地方。 :)
谢谢大家,请原谅我有时候说话不好的话,这可以算是我由于工作时间而感到的疲劳。 我想我不能正确说出我的意思,所以我回答了自己的问题。 我知道,这不是最好的答案,也没有优化,但是可以!
SELECT t.ref,
t.NAME AS n1,
t2.NAME AS n2
INTO #tbl1
FROM @T1 AS t
LEFT JOIN @T2 AS t2
ON t2.ref = t.ref
WHERE t2.ref IS NOT NULL
SELECT ROW_NUMBER() OVER(ORDER BY t.NAME) AS rn,
*
INTO #tbl2
FROM @T1 AS t
WHERE t.ref NOT IN (SELECT ref
FROM #tbl1)
SELECT ROW_NUMBER() OVER(ORDER BY t.NAME) AS rn,
*
INTO #tbl3
FROM @T2 AS t
WHERE t.ref NOT IN (SELECT ref
FROM #tbl1)
SELECT n1,
n2
FROM #tbl1
UNION
SELECT t1.NAME AS n1,
t2.NAME AS n2
FROM #tbl2 t1
FULL OUTER JOIN #tbl3 t2
ON t1.rn = t2.rn
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.