簡體   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