首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从多行创建缺失或不匹配的数据查询

从多行创建缺失或不匹配的数据查询
EN

Stack Overflow用户
提问于 2018-05-02 20:02:37
回答 3查看 163关注 0票数 0

我到处搜索,花了几天时间尝试不同的连接组合,但都没有用,所以欢迎大家的集体建议。我已经创建了多个联接和"with“语句的场景,无法帮助我错过一个明显的解决方案。

背景.

例如,我们有一个列类似于:-

代码语言:javascript
复制
BuySideTradeDate | BuySideContract | BuySidePrice | BuySideQuantity | SellSideTradeDate | SellSideContract | SellSidePrice | SellSideQuantity

这是一个示例表,但概念是相同的。此表的目的是存储来自内部系统和外部系统的数据,以比较任何差异或丢失的数据。对于这个例子,我们假设每天执行一次交易。每宗交易都会有一排,例如:-

  1. 我们可能有一个交易做在买方,这是从卖方(将只有一行在这个交易表中,只有购买信息完成)。
  2. 反过来说,我们可能有一个交易做在卖侧,从买方(将只有一行在这个交易表中,只有出售信息完成)。
  3. 我们可以在买卖端进行交易,但价格可能是不同的(表中有两行,并填充了相应的列)。

挑战

我们需要创建一个查询来做两件事:第一,“匹配”相同的合同(在买卖双方)和交易日期(如果有两个匹配的行),然后,如果没有匹配,我们只需要返回该单行(不管是买入方还是卖出方)。如果有匹配的合同和交易日期,我们需要将这两行合并为一!

从本质上说,这为报告提供了数据,该报表用于发现任何一方的缺失交易或不匹配的交易。

示例输入数据(谢谢您的提示@Radim) (抱歉格式很差)

代码语言:javascript
复制
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)

我怀疑这是一个子查询和连接的组合,但有一个更简单的方式,我错过了!

真的非常感谢您的任何投入!

如果我太模棱两可,或者你需要进一步澄清,就大声喊一声。

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2018-05-02 20:36:01

我创建了两个表:buy_sidesell_side

代码语言:javascript
复制
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
);

我为每个表添加值:

代码语言:javascript
复制
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)。

代码语言:javascript
复制
--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语句进行intersectexcept

代码语言:javascript
复制
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'

我在这里使用临时表,因为它使创建示例更容易(之后我不需要清理)。你可以用你想要的任何桌子。

票数 0
EN

Stack Overflow用户

发布于 2018-05-02 20:36:01

从将表连接到自身开始(使用两个不同的别名)。类似于:

代码语言:javascript
复制
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

到目前为止,这还不是完全的,但这是你需要去的地方的第一步。我也不确定您想要匹配的只是日期还是合同;这个比较两者,但您可以很容易地修改它,以匹配只是日期。

票数 0
EN

Stack Overflow用户

发布于 2018-05-02 20:36:47

您应该使用FULL JOIN。这允许连接两边的NULL值保持不变,同时还可以在整个联接中组合“匹配”值的行。

示例:

代码语言:javascript
复制
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

请注意,如果买卖双方的两条线有相同的交易日期和合同,这将产生重复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50142661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档