4

我已经尝试搜索有关在没有外键的情况下加入表的信息,但似乎答案总是创建外键。我无法修改相关表格来执行此操作,并且我必须报告已经在生产中的数据。以下是所涉及的表格中的部分数据,用于举例说明问题。

Table A
Journal    Account    Debit    Credit    Sequence
--------------------------------------------------
87041      150-00     100.00   0.00      16384
87041      150-10     0.00     100.00    32768
87041      150-00     50.0     0.0       49152
87041      210-90     0.0      50.0      65536

然后第二个表,跟踪额外的信息位,基本相同,但缺少将行项目正确绑定在一起的序列号。它有自己不相关的序列号。

Table B
Journal    Account    Label    Artist    Sequence
--------------------------------------------------
87041      150-00     Label02  Artist12  1
87041      150-10     Label09  Artist03  2
87041      150-00     Label04  Artist01  3
87041      210-90     Label01  Artist05  4

目前我能想到的最好的办法是加入日记帐和帐户,但这会重复记录。我已经通过在序列号上使用分组和 max() 来接近,但结果是,对于具有大量行的日记条目,并非所有重复项都被删除,并且总是显示第二个表中的第一个匹配项具有相同帐户的行。

Closest - but bad - result
Journal    Account    Debit    Credit    Sequence    Label    Artist
----------------------------------------------------------------------
87041      150-00     100.00   0.00      16384       Label02  Artist12
87041      150-10     0.00     100.00    32768       Label09  Artist03
87041      150-00     50.0     0.0       49152       Label02  Artist12  <-- wrong 
87041      210-90     0.0      50.0      65536       Label01  Artist05

如何加入表格以排除重复项,同时显示正确的标签和艺术家?感觉就像我必须生成一个查询,当表 A 中的 49152 记录来寻找匹配时,它知道表 B 中的一条记录已经被使用。

编辑:

@Justin Crabtree A.Sequence 将是输入行项目的顺序。因此,用户可以先输入示例中的最后一行,然后输入第一行,然后输入第三行,最后输入第二行。

@Edper Microsoft SQL Server ......嗯,我今天早上无法远程访问客户端的机器......否则我会提供版本。

@Abe Miessler 是的,你是对的。

一旦我可以回到服务器,我会尝试你的建议@pkuderov

4

4 回答 4

4

试试这个

;WITH a AS
(
    SELECT Journal,
           Account,
           Debit,
           Credit,
           Sequence,
           Id = ROW_NUMBER() OVER(PARTITION BY Journal ORDER BY Sequence)
    FROM dbo.tablea
)
, b AS
(
    SELECT Journal,
           Account,
           Label,
           Artist,
           Id = ROW_NUMBER() OVER(PARTITION BY Journal ORDER BY Sequence)
    FROM dbo.tableb
)

SELECT a.Journal,
       a.Account,
       a.Debit,
       a.Credit,
       a.Sequence,
       b.Label,
       b.Artist
FROM a
JOIN b ON b.Journal = a.Journal
      AND b.Account = a.Account
      AND b.Id = a.Id
于 2013-06-28T23:29:18.560 回答
3

你好,这只是一个想法:

select
    a.Journal, a.Account, a.Debit, a.Credit, a.Sequence, b.Label, b.Artist
from (
    select
        *, 
        row_number() over(partition by Journal, Account order by Sequence) as idInGroup
    from a
) as a
join (
    select
        *, 
        row_number() over(partition by Journal, Account order by Sequence) as idInGroup
    from b
) as b on
    a.Journal = b.Journal
    and a.Account = b.Account
    and a.idInGroup = b.idInGroup

在这里,我假设订单以序列顺序出现(在两个表中),这是连接表的基本提示。

于 2013-06-28T23:25:26.400 回答
0

如果您按它们自己的序列号对 2 个表行进行排序,这些行是否会以相同的顺序对齐?

如果是这样,这是 SQL Server 的一种可能解决方案:您可以创建 2 个 CTE,每个表一个,带有 ROW_NUMBER 列,这样,两个表将有一个匹配的行号列,您可以使用它来连接。如果你需要一个例子,请告诉我。

于 2013-06-28T23:28:07.597 回答
0

如果我正确阅读了您的要求,并且您想要表 A 中的所有行,但只需要表 B 中的第一个匹配行,那么您最好的选择是使用 TOP(1) 进行 OUTER APPLY。看起来像这样:

select *
from TableA
OUTER APPLY
 (select TOP(1) Journal, Account, Label, Artist, Sequence
  FROM TableB
  WHERE Journal = TableA.Journal AND Account = TableA.Account
  ORDER BY Sequence) as B

(绝对是伪代码,但应该有点接近。)

如果归根结底,您可以使用 ROW_NUMBER(),按 Journal 和 Account 对其进行分区,然后匹配每个结果集的 Row_Number 值。您将为 TableA 生成一个子查询/CTE,为 TableB 生成另一个 CTE - 每个都有一个 RowNumber 值,该值本质上是一个新的序列整数。TableA 中的第一行将匹配 TableB 中的第一行,TableA 中的第二行将匹配 TableB 中的第二行,等等。当然,如果“A”中的 Journal/Account 行多于在“B”中有。

一个更好的问题可能是 - “如果不能使用任何数据列将它们联系在一起,您的代码如何确定 TableA 和 TableB 之间的所有匹配项?”

于 2013-06-29T01:31:34.810 回答