SQL在两个表之间选择

时间:2016-07-02 11:48:14

标签: sql sql-server

我有这两个表:


    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值。 join的优先级是具有相同ref的值,如果表的行数不相等,则会有一些NULL结果

4 个答案:

答案 0 :(得分:2)

使用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

答案 1 :(得分:2)

这非常复杂。您希望匹配的行匹配。然后,您希望不匹配的行按位置匹配不匹配的行,然后匹配其他所有行。

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时,
  • refref
  • alt_refref值不匹配的枚举列。

拥有这些列之后,可以将表连接在一起,首先检查match_ref,然后 - 如果不存在 - 请检查alt.ref

SQL Fiddle似乎不适用于SQL Server。但是,here是一个完全相同的Postgres版本。 Here是使用SQL Server的工作版本(这与Postgres版本相同)。

答案 2 :(得分:1)

  • 查看您的问题

如果我错了,请纠正我,但是你有两个表有一个你希望返回结果集的名称的参考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。它是按连续顺序完成的,所以如果还有问题,那么你可以把这个逻辑搞清楚。但我相信这会帮助你获得你想要的地方。 :)

答案 3 :(得分:0)

感谢每一个人,如果我有时说话不好,请原谅我,因为工作时间因为我的疲劳。 我想我不能正确地说出我的意思,所以我回答了自己的问题。这不是最好的答案,我知道它没有经过优化,但它确实有效!

/home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1252:in `literal_other_append': can't express #<MatchData "79511" 1:"1"> as a SQL literal (Sequel::Error)
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:108:in `literal_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:673:in `block in placeholder_literal_string_sql_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `loop'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `placeholder_literal_string_sql_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/sql.rb:109:in `to_s_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1214:in `literal_expression_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:86:in `literal_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:345:in `literal'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1534:in `static_sql'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:23:in `insert_sql'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/actions.rb:334:in `insert'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/adapters/shared/postgres.rb:1355:in `insert'
    from tt.rb:12:in `<main>'