【问题标题】:Compare rows from two join tables and gives result from two tables in alternate fashion比较两个连接表中的行并以交替方式从两个表中给出结果
【发布时间】:2018-03-08 04:53:20
【问题描述】:
Table X

First Name    Last Name    Job
----------    ---------    ---
CHIN          JACK         A
GREEN         JAMES        B

Table Y

First Name    Last Name    Job
----------    ---------    ---
CHIN          JACK         D
GREEN         JAMES        B


  RESULT
------
First Name          Last Name           Job
----------          ---------           ---
CHIN                JACK                >> A <<   --(first row from Table X)
CHIN                JACK                >> D <<   --(first row from Table Y)
>> CHIN <<          >> JACK <<          >> A <<   --(first row from Table X)
>> GREEN <<         >> JAMES <<         >> B <<   --(second row from Table Y)
>> GREEN <<         >> JAMES <<         >> B <<   --(second row from Table X)
>> CHIN <<          >> JACK <<          >> D <<   --(first row from Table Y)
GREEN               JAMES               B         --(second row from Table X) 
GREEN               JAMES               B         --(second row from Table Y)

我正在尝试逐列比较两个表中的行。如果两个表之间的列值不匹配,我会通过在结果表中的表 TableX 和 TableY 中的不匹配字段附加“>>

结果集的最后两个表是可选的。拥有或不拥有都可以。

这个查询是我最初想到的,但它不会交替给出两个表中的行,它只考虑 TableX 中的列值 有没有一种可能的方法来编写查询来实现结果表。请指教。

SELECT
CASE
  WHEN x.firstname = y.firstname THEN x.firstname
  ELSE '>> '+x.firstname+' <<'
END FirstName,
CASE 
  WHEN x.lastname = y.lastname THEN x.lastname
  ELSE '>> '+x.lastname+' <<'
END LastName,
CASE 
  WHEN x.job = y.job THEN x.job
  ELSE '>> '+x.job+' <<'
END Job
FROM
TableX x
JOIN
TableY y
ON x.firstname <> y.firstname
OR x.lastname <> y.lastname
OR x.job <> y.job

改进 我想出了一个与我的预期结果非常相似的查询。我通过添加一个新列“公司”来实现它,该列的值在 TableX 和 TableY 中始终相同。所以现在表格看起来像

表 X

Company    First Name    Last Name    Job
-------    ----------    ---------    ---
C          CHIN          JACK         A
C          GREEN         JAMES        B

Y 表

Company    First Name    Last Name    Job
-------    ----------    ---------    ---
T          CHIN          JACK         D
T          GREEN         JAMES        B

这是我的新查询

    SELECT
    *
FROM 
(
SELECT      ROW_NUMBER() OVER (ORDER BY x.Company) as RowNumber,
            1 AS 'RowOrder',
            x.TableName,
            CASE
                WHEN x.firstname = y.firstname THEN x.firstname
                ELSE '>> '+x.firstname+' <<'
            END FirstName,
            CASE
                WHEN x.LastName = y.LastName THEN x.LastName
                ELSE '>> '+x.LastName+' <<'
            END LastName,
            CASE
                WHEN x.Job = y.Job THEN x.Job
                ELSE '>> '+x.Job+' <<'
            END Job
    FROM
            #tableX x
        JOIN #tableY y
        ON x.FirstName <> y.FirstName
        OR x.LastName <> y.LastName
        OR x.Job <> y.Job

UNION ALL

SELECT 
            ROW_NUMBER() OVER (ORDER BY y.Company) as RowNumber,
            2 AS 'RowOrder',
            y.TableName,
            CASE
                WHEN x.firstname = y.firstname THEN y.firstname
                ELSE '>> '+y.firstname+' <<'
            END FirstName,
            CASE
                WHEN x.LastName = y.LastName THEN y.LastName
                ELSE '>> '+y.LastName+' <<'
            END LastName,
            CASE
                WHEN x.Job = y.Job THEN y.Job
                ELSE '>> '+y.Job+' <<'
            END Job
    FROM
            #tableX x
        JOIN #tableY y
        ON x.FirstName <> y.FirstName
        OR x.LastName <> y.LastName
        OR x.Job <> y.Job

) rt
ORDER BY rt.RowNumber, rt.RowOrder

现在的问题是大括号内的第二个选择语句中的连接打乱了行的显示顺序。这会导致最终结果中的行排序错误。请在下面找到最终结果。您还可以在大括号内找到各个 select 语句。图片中的最后一个表格以打乱的顺序给出了行,这弄乱了最终结果。

Final result, result from first select statement, result from second select statement

【问题讨论】:

  • 为什么不横向而不是纵向显示差异?这似乎是一种更简单的查询方式,可以让您完美地研究数据。与CHIN JACK A 相比,为什么要显示GREEN JAMES B?如果您在名称上匹配,该行似乎与它没有对应关系。如果您不匹配名称,匹配规则是什么?您希望在比较或锚点旁边显示哪些行?
  • 您希望它们出现的顺序是什么?请记住,不管它看起来如何,SQL 表没有它们自己的固有顺序,因此从表中说“第一/第二/第三/等行”是没有意义的,除非你定义一个基于键值的顺序。

标签: sql sql-server tsql join


【解决方案1】:

我认为您想比较两个表之间的所有行对。只要意识到这将很快变得庞大而缓慢。

with X as (
    select *, row_number() over (order by "First Name", "Last Name", "Job") as rnX
    from TableX
), Y as (
    select *, row_number() over (order by "First Name", "Last Name", "Job") as rnY
    from TableY
), horizontal as (
    select
        rnX, rnY,
        case when x."First Name" = y."First Name" then x."First Name"
            else '>> ' + x."First Name" + ' <<' end as FirstNameX,
        case when x."First Name" = y."First Name" then y."First Name"
            else '>> ' + y."First Name" + ' <<' end as FirstNameY,
        case when x."Last Name" = y."Last Name" then x."Last Name"
            else '>> ' + x."Last Name" + ' <<' end as LastNameX,
        case when x."Last Name" = y."Last Name" then y."Last Name"
            else '>> ' + y."Last Name" + ' <<' end as LastNameY,
        case when x."Job" = y."Job" then x."Job"
            else '>> ' + x."Job" + ' <<' end as JobX,
        case when x."Job" = y."Job" then y."Job"
            else '>> ' + y."Job" + ' <<' end as JobY
    from X as x cross join Y as y
), interleave as (
    select
        rnX, rnY, n,
        case when n = 1 then 'X' else 'Y' end as src,
        case when n = 1 then rnX else rnY end as rn,
        case when n = 1 then FirstNameX else FirstNameY end as "First Name",
        case when n = 1 then LastNameX else LastNameY end as "Last Name",
        case when n = 1 then JobX else JobY end as "Job"
    from horizontal cross apply (select n from (values (1), (2)) d(n)) c
)
select src, rn, "First Name", "Last Name", "Job" from interleave
order by rnX, rnY, n;

http://rextester.com/JRQ91122

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多