两个表的选择性连接(SQL Server)

时间:2014-07-09 14:42:54

标签: sql sql-server join

我如何加入这两个表:

表1

DOCNUM  DOCTYPE COST    POLINE*         
PO01        1       8       18334
PO01        1       17      18335
PO01        1       8       18336
PO02        1       16      18787
PO02        1       14      18788
PO03        2       14      18850
PO04        2       14      18894

表2

DOCNUM  INVNUM  INVSEQ*
PO01    INV001  2365301
PO01    INV002  2365302
PO01    INV003  2365303
PO02    INV007  2365450
PO02    INV008  2365451

这样做:

DOCNUM  DOCTYPE COST    INVNUM
PO01    1       8       INV001
PO01    1       17      INV002
PO01    1       8       INV003
PO02    1       16      INV007
PO02    1       14      INV008
PO03    2       14      NULL
PO04    2       14      NULL

我尝试了各种连接,但最接近的是使用ROW_NUMBER()加入两个表...

大多数时候我都会这样:

DOCNUM  DOCTYPE COST    INVNUM
PO01    1       8       INV003
PO01    1       17      INV004
PO01    1       8       INV005
PO01    1       8       INV003
PO01    1       17      INV004
PO01    1       8       INV005
PO01    1       8       INV003
PO01    1       17      INV004
PO01    1       8       INV005
PO02    1       16      INV007
PO02    1       14      INV008
PO02    1       16      INV007
PO02    1       14      INV008
PO03    2       14      NULL
PO04    2       14      NULL

(因为对于DOCNUM的每个类似条目重复连接)

或者这个:

DOCNUM  DOCTYPE COST    INVNUM      
PO01    1       8       INV003
PO01    1       17      INV004
PO01    1       8       INV005
PO02    1       16      INV007
PO02    1       14      INV008

(不含任何PO03或PO04)

我在考虑编写DOCNUM编号,然后我才能加入,只要计数是' 1',但我不知道如何计算独特的字段:

Count   DOCNUM  DOCTYPE     COST            
1       PO01        1       8
2       PO01        1       17
3       PO01        1       8
1       PO02        1       16
2       PO02        1       14
1       PO03        2       14
1       PO04        2       14

所有想法?

2 个答案:

答案 0 :(得分:3)

架构已损坏。您应该在这些表中添加一列以匹配发票号。根据提供的信息,InvNum字段甚至可以只是table1的一部分,但我知道这可能只是这些表中相关字段的部分列表。

如果您在每个表格中至少有一个列可以保证订单 - 甚至是日期时间字段 - 我们仍然可以这样做。实际上,来自table1的记录甚至不能保证是唯一的 - 没有主键。这不是数据库成功的好方法。

我可以给你下面的查询,可能工作,大部分时间,但没有存储更多信息表,Sql Server可以自由更改在任何时候对你的行进行排序并打破它,以便它可以随时间返回不一致的结果。

SELECT t1.docnum, t1.doctype, t1.code, t2.invnum
FROM 
(
    select *, row_number() over (partition by docnum ORDER BY docnum, poline) as ordinal
    from table1
) t1
LEFT JOIN 
(
    select *, row_number() over (parition by docnum ORDER BY docnum, invseq) as ordinal
) t2 ON t2.docnum = t1.docnum and t2.ordinal = t1.ordinal

答案 1 :(得分:0)

;WITH CTE1 AS 
(
    select t.doctype,t.docnum,t.code, row_number() over (partition by docnum ORDER BY docnum, doctype) as ordinal
    from table1 t
),
    CTE2 AS
    (select tt.docnum, row_number() over (parition by docnum ORDER BY docnum, invnum) as ordinal from Table2 tt)

Select c.docnum, c.doctype, c.code, cc.invnum from CTE1 C
LEFT  JOIN CTE2 CC
ON C.docnum = CC.docnum AND C.ordinal = cc.ordinal