SQL 服务器:将同一 table 中的记录相互连接
SQL Server : join records in same table against each other
我有一个 table 看起来像这样。
我想达到的目标
我想select属于一起的行(根据我提供的规则)
然后我想搜索日期 大于 2016-01-01 的 F 类型行和已经发生的 O 类型行 低于 2015 年。
示例数据:
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 所有行都属于彼此,我会怎么做?
到目前为止,我已尝试创建对 table
的自我引用
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'
这似乎有点笨拙,我能感觉到 Union 可以在这里工作,但我看不出如何。
我认为您可以使用如下所示的一个查询获得结果
SELECT *
FROM [FTG1].[dbo].[oof]
where
(YEAR(subq1.orddatum) = '2015' AND YEAR(subq1.faktdatum) = '2016')
AND
(doknr = koppl_dok2 OR doknr = koppl_dok1)
您可以使用一些 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)
我有一个 table 看起来像这样。
我想达到的目标
我想select属于一起的行(根据我提供的规则)
然后我想搜索日期 大于 2016-01-01 的 F 类型行和已经发生的 O 类型行 低于 2015 年。
示例数据:
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 所有行都属于彼此,我会怎么做?
到目前为止,我已尝试创建对 table
的自我引用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'
这似乎有点笨拙,我能感觉到 Union 可以在这里工作,但我看不出如何。
我认为您可以使用如下所示的一个查询获得结果
SELECT *
FROM [FTG1].[dbo].[oof]
where
(YEAR(subq1.orddatum) = '2015' AND YEAR(subq1.faktdatum) = '2016')
AND
(doknr = koppl_dok2 OR doknr = koppl_dok1)
您可以使用一些 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)