繁体   English   中英

SQL在两个表之间选择

[英]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_refrefref存在在另一个表中。
  • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM