我到处搜索,花了几天时间尝试不同的连接组合,但都没有用,所以欢迎大家的集体建议。我已经创建了多个联接和"with“语句的场景,无法帮助我错过一个明显的解决方案。
背景.
例如,我们有一个列类似于:-
BuySideTradeDate | BuySideContract | BuySidePrice | BuySideQuantity | SellSideTradeDate | SellSideContract | SellSidePrice | SellSideQuantity这是一个示例表,但概念是相同的。此表的目的是存储来自内部系统和外部系统的数据,以比较任何差异或丢失的数据。对于这个例子,我们假设每天执行一次交易。每宗交易都会有一排,例如:-
挑战
我们需要创建一个查询来做两件事:第一,“匹配”相同的合同(在买卖双方)和交易日期(如果有两个匹配的行),然后,如果没有匹配,我们只需要返回该单行(不管是买入方还是卖出方)。如果有匹配的合同和交易日期,我们需要将这两行合并为一!
从本质上说,这为报告提供了数据,该报表用于发现任何一方的缺失交易或不匹配的交易。
示例输入数据(谢谢您的提示@Radim) (抱歉格式很差)
BuySideTradeDate BuySideContract BuySidePrice BuySideQuantity SellSideTradeDate SellSideContract SellSidePrice SellSideQuantity
10/04/2018 Sugar 100 10
15/04/2018 Sugar 101 12
16/04/2018 Coffee 200 10
20/04/2018 Corn 300 11
25/04/2018 Corn 305 15
10/04/2018 Sugar 100.5 10
15/04/2018 Sugar 101 11
16/04/2018 Coffee 201 10
26/04/2018 Oil 1000 1
Expected Output
10/04/2018 Sugar 100 10 10/04/2018 Sugar 100.5 10 (contract/date/quantity match but price do not)
15/04/2018 Sugar 101 12 15/04/2018 Sugar 101 11 (contract/date/price match but quantity does not)
16/04/2018 Coffee 200 10 16/04/2018 Coffee 201 10 (contract/date/quantity match but price does not)
20/04/2018 Corn 300 11 (missing from sell side)
25/04/2018 Corn 305 15 (missing from sell side)
26/04/2018 Oil 1000 1 (missing from buy side)我怀疑这是一个子查询和连接的组合,但有一个更简单的方式,我错过了!
真的非常感谢您的任何投入!
如果我太模棱两可,或者你需要进一步澄清,就大声喊一声。
谢谢。
发布于 2018-05-02 20:36:01
我创建了两个表:buy_side和sell_side。
create table #buy_side (
foo varchar(5) null
, bar int null
, san int null
);
create table #sell_side (
foo varchar(5) null
, bar int null
, san int null
);我为每个表添加值:
INSERT INTO #buy_side (foo, bar, san)
VALUES ('XYZ', 3, 5)
, ('ABC', 11, 8)
, ('XYP', 2, 5)
INSERT INTO #sell_side (foo, bar, san)
VALUES ('XYP', 8, 9)
, ('ABC', 11, 8)
, ('XYZ', 6, 4)这两个表之间只有一个值匹配:('ABC',11,8)。
--In both buy and sell side
select *
from #buy_side
INTERSECT
select *
from #sell_side
--In buy side but not sell side
select *
from #buy_side
EXCEPT
select *
from #sell_side
--In sell side but not buy side
select *
from #sell_side
EXCEPT
select *
from #buy_side这是我运行这些的结果..。

只要两个表之间的模式(或关系,如果选择一个表的子集)匹配,这应该可以工作。
更新
澄清最后的评论。假设您的所有数据都在同一个表中。您是在区分带标志的买入和卖出;在本例中,我们将称其为category。你会选择购买记录。你会选择销售记录。然后对select语句进行intersect或except。
create table #trade (
foo varchar(5) null
, bar int null
, san int null
, category varchar(max) null
);
INSERT INTO #trade (foo, bar, san, category)
VALUES ('XYZ', 3, 5, 'buy')
, ('ABC', 11, 8, 'buy')
, ('XYP', 2, 5, 'buy')
, ('XYP', 8, 9, 'sell')
, ('ABC', 11, 8, 'sell')
, ('XYZ', 6, 4, 'sell')
SELECT foo, bar, san
FROM #trade
WHERE category = 'sell'
INTERSECT
SELECT foo, bar, san
FROM #trade
WHERE category = 'buy'
SELECT foo, bar, san
FROM #trade
WHERE category = 'sell'
EXCEPT
SELECT foo, bar, san
FROM #trade
WHERE category = 'buy'
SELECT foo, bar, san
FROM #trade
WHERE category = 'buy'
EXCEPT
SELECT foo, bar, san
FROM #trade
WHERE category = 'sell'我在这里使用临时表,因为它使创建示例更容易(之后我不需要清理)。你可以用你想要的任何桌子。
发布于 2018-05-02 20:36:01
从将表连接到自身开始(使用两个不同的别名)。类似于:
SELECT BuySide.BuySidePrice,
BuySide.BuySideQuantity,
SellSide.SellSidePrice,
SellSide.SellSideQuantity
FROM MyTable BuySide
LEFT JOIN MyTable SellSide ON BuySide.BuySideTradeDate=SellSide.SellSideTradeDate AND BuySide.BuySideContract=SellSide.SellSideContract到目前为止,这还不是完全的,但这是你需要去的地方的第一步。我也不确定您想要匹配的只是日期还是合同;这个比较两者,但您可以很容易地修改它,以匹配只是日期。
发布于 2018-05-02 20:36:47
您应该使用FULL JOIN。这允许连接两边的NULL值保持不变,同时还可以在整个联接中组合“匹配”值的行。
示例:
SELECT BuySide.TradeDate, SellSide.TradeDate, etc...
FROM TBL_BuySide BuySide
FULL JOIN TBL_SellSide SellSide ON BuySide.TradeDate = SellSide.TradeDate
AND BuySide.Contract = SellSide.Contract请注意,如果买卖双方的两条线有相同的交易日期和合同,这将产生重复。
https://stackoverflow.com/questions/50142661
复制相似问题