Sql server 连接设计糟糕的SQL表?

Sql server 连接设计糟糕的SQL表?,sql-server,tsql,Sql Server,Tsql,我曾尝试搜索关于在没有外键的情况下连接表的信息,但答案似乎总是创建外键。我无法修改有问题的表来执行此操作,我必须报告已经在生产中的数据。以下是相关表格中的部分数据,以举例说明该问题 Table A Journal Account Debit Credit Sequence -------------------------------------------------- 87041 150-00 100.00 0.00 16384 870

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

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
目前我能想出的最好办法是加入日记账和账户,但这会重复记录。我在序列号上使用了grouping和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
最接近但不好的结果
日记账借方贷方顺序标签艺术家
----------------------------------------------------------------------
87041 150-00 100.00 0.00 16384 Label02艺人12
87041 150-10 0.00 100.00 32768标签09艺术家03
87041 150-00 50.0 0.0 49152 Label02艺人12
嗨,这只是一个想法:

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

在这里,我假设顺序是按顺序出现的(在两个表中),这是联接表的基本提示。

如果您按自己的序列号对两个表行进行排序,行是否会按相同的顺序排列

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

试试看


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

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(),按日记账和帐户对其进行分区,然后为每个结果集匹配这些ROW_NUMBER值。您将为TableA生成一个子查询/CTE,为TableB生成另一个子查询/CTE,每个子查询/CTE都有一个RowNumber值,该值本质上是一个新的序列整数。表A中的第一行将与表B中的第一行匹配,表A中的第二行将与表B中的第二行匹配,等等。当然,如果“A”中日记账/科目的行数比“B”中的多,您会遇到一些问题


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

您的请求听起来可能。。。但很难准确地确定。请粘贴用于获取结果的SQL。当表B中有多条记录时-应该使用哪条记录?我想我现在明白了,您将面临的一个问题是,相信元素表中的自然顺序不是100%可靠的-在大多数情况下,这可能与另一个表中的顺序一致,但不一致。是否可以相信表A中的顺序至少是正确的?@CodenameCain您使用的是什么RDBMS,sqlserver、mysql或其他什么?您可以发布您想要的输出吗?标记为
的行是否应该改为
Label04 Artist01
?“我尝试搜索有关无外键联接表的信息,但答案似乎总是创建外键。”关系模型和SQL基都基于公共值联接。不必使用外键约束来连接公共值。这里的问题是这两个表没有足够的公共值来正确执行联接。(这两个表之间的外键可以防止这个问题。)如果存在具有不同B.Journal的行,并且所有B.Journal都共享B.Sequence,则将不起作用。所以您根本不需要在A上进行分区,也不需要在B上进行分区too@pkuderov因此,“根据提供的数据”。我想知道你的答案哪一个可能更重要correct@TI最后一个需要的小语法修正-您忘了在join子句中将
tableb
更改为
b
)@TI-ah,sry,刚刚检查了join子句中是否真的需要a.Account=b.Account。这是需要的。只需在给定数据上检查您的联接-日志是相同的,id是:[1,1,2,1],对于A和[1,1,2,1]。id=1的所有行都将相互连接(但如果我们需要保持帐户相等,这是错误的)@我还想知道订单的情况。到目前为止,我详细检查的每个事务都显示了一个良好的匹配顺序。
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