SQL Server:将相同表中的记录相互连接起来

时间:2016-04-20 19:53:36

标签: sql sql-server self-join

我有一张看起来像这样的桌子。

我想要实现的目标

  1. 我想选择属于一起的行(根据我提供的规则)

  2. 然后,我想搜索日期大于2016-01-01 的F类行和O类行,这些行已在2015年发生

  3. 示例数据:

    type        docnr           connection1     connection2    date
    F    40195.000000          36950.000000        0.000000    2016-01-29 00:00
    O    36950.000000              0.000000    40195.000000    2015-01-29 00:00
    

    正如您所看到的,行的类型决定了与另一个的连接所在的位置。

    • TYPE F :与另一行的连接位于connection2
    • TYPE O :与另一行的连接位于connection1

    如果我要选择属于彼此的所有行,我该怎么做?

    到目前为止,我已尝试创建表

    的自引用
    SELECT *
    FROM 
       (SELECT  
            faktoofen.datum1 as faktdatum,
            faktoofen.doknr as faktdok,
            ordoofen.doknr as orddok,
            ordoofen.datum1 as orddatum
        FROM 
            [FTG1].[dbo].[oof] as faktoofen,
            [FTG1].[dbo].[oof] as ordoofen
        WHERE 
           (faktoofen.doknr = ordoofen.koppl_dok2 
            OR ordoofen.doknr = faktoofen.koppl_dok1) 
    ) as subq1
    WHERE
        YEAR(subq1.orddatum) = '2015'
        AND YEAR(subq1.faktdatum) = '2016'
    

    这看起来有点笨拙,我觉得联盟会在这里工作,但我看不出怎么样。

2 个答案:

答案 0 :(得分:2)

你可以使用一些cte和UNION ALL

来做到这一点
;WITH TypeF AS 
(
    -- F type rows with a date bigger than 2016-01-01
    SELECT * FROM [FTG1].[dbo].[oof] WHERE [type] = 'F' and [date] >= '2016-01-02'
),
TypeO AS
(
    -- O type rows which has happened under year 2015
    SELECT * FROM [FTG1].[dbo].[oof] WHERE [type] = 'O' and YEAR([date]) = 2015
)

--get only F type rows with matching O type records
SELECT  *
FROM    TypeF
WHERE   [connection1] IN (SELECT    [docnr]
                          FROM      TypeO)
UNION ALL

--get only O type rows with matching F type records
SELECT  *
FROM    TypeO
WHERE   [connection2] IN (SELECT    [docnr]
                          FROM      TypeF)

答案 1 :(得分:0)

我认为您可以使用下面的

之类的查询获得结果
SELECT *
FROM [FTG1].[dbo].[oof]
where 
(YEAR(subq1.orddatum) = '2015' AND YEAR(subq1.faktdatum) = '2016')
 AND 
(doknr = koppl_dok2 OR doknr = koppl_dok1)