【问题标题】:Combination of INNER JOIN and SELECTINNER JOIN 和 SELECT 的组合
【发布时间】:2019-02-15 22:27:36
【问题描述】:

假设我有一个表 transactions 包含报告的金融交易,其中交易报告的双方(TRNS_ID 是交易 ID,RA_ID 是报告代理 ID,CNTP_ID 是交易对手 ID)

ID, RA_ID, CNTP_ID, FIELD1, FIELD2
1        A      B        0.1     0.1    
2        B      A        0.1     0.1
---------------------------------------
3        A      B        0.1     0.1    
4        B      A        0.1     0.1
---------------------------------------
5        B      C        0.1     0.1
6        C      B        0.1     0.1

因此,对于发生在两个代理之间的每笔交易,我都有一个冗余记录,我想删除它(为了说明,我将属于一起的交易按行分开)。问题是从许多记录中识别出两个交易,可能涉及相同的代理。

为此,我使用INNER JOIN 和基于FIELD1 的几个标准在FIELD2 上执行自联接以相互匹配事务。但是,这些信息可能不足以完美匹配(参见前四条记录)。因此,我想在另一个字段上进行匹配:报告的底层抵押品(可能是多个项目)。报告的抵押品存储在表collaterals 中,其中TRNS_ID 是外键

ID, COLL, TRNS_ID
1   F     1
2   G     1
3   G     2
4   F     2
-----------
5   H     3
6   H     4
-----------
7   I     5
8   I     6

问题:如何在INNER JOIN查询中强加交易双方上报的抵押品相同的条件?

我想要的结果是

RA_TRNS_ID, RA_ID, CNTP_ID, CNTP_TRNS_ID, FIELD1, FIELD2
1           A      B        2             0.1     0.1
3           B      C        4             0.1     0.1
5           B      C        6             0.1     0.1

我当前仅尝试INNER JOINs 对FIELD1FIELD2,但是这是不完美的匹配,因为我无法区分前两组交易。

SELECT 
    x.`TRNS_ID` AS x.`RA_TRNS_ID`, 
    y.`TRNS_ID` AS y.`CNTP_TRNS_ID`, 
    x.`FIELD1` as `RA_FIELD1`,
    y.`FIELD1` as `CNTP_FIELD1`,
    x.`FIELD2` as `RA_FIELD2`,
    y.`FIELD2` as `CNTP_FIELD2`
FROM transactions x
INNER JOIN transactions y
ON x.`CNTP_ID` = y.`RA_ID` AND x.`FIELD1` = y.`FIELD1` AND x.`FIELD2` = y.`FIELD2`
GROUP BY `RA_FIELD1`, `CNTP_FIELD1`, `RA_FIELD2`, `CNTP_FIELD2`
HAVING COUNT(*) = 2;

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    AND 关键字应该在WHERE 子句中,而不是在ON 关键字之后。

    SELECT *
    FROM transactions x
    INNER JOIN transactions y
    ON x.`CNTP_ID` = y.`RA_ID` 
    WHERE (SELECT COLL FROM collaterals WHERE TRNS_ID = x.`ID`) = (SELECT COLL FROM collaterals WHERE TRNS_ID = y.`ID`)
    

    【讨论】:

    • 太好了,谢谢。我是否必须在两个SELECT 中加入一个ORDER BY COLL ASC 才能进行比较?注意表中的排序TRNS_ID...
    • @Jhonny 我认为如果您使用 Gordon Linoff 的解决方案,您可以轻松地ORDER BY cx.COLL
    • 我必须在外键上创建一个索引才能获得不错的性能。它现在按预期工作。谢谢大家。
    【解决方案2】:

    使用多个连接:

    SELECT tx.*, ty.*
    FROM transactions tx JOIN
         collaterals cx
         ON cx.trns_id = tx.id JOIN
         transactions ty
         ON tx.`CNTP_ID` = ty.`RA_ID` JOIN
         collaterals cy
         ON cy.trns_id = ty.id AND cy.COLL = cx.COLL;
    

    【讨论】:

    • 谢谢@Gordon。当我期望单个交易的行数与使用的抵押品一样多时,我是否正确理解了查询?另一个我没有解释的问题是我可能有错误的报告,即RA_ID=B 的报告代理只报告一个附属项目。在这种情况下,我不想匹配它们。现在我不知道如何适应它。
    • @Jhonny 。 . .您可能需要提出另一个问题,重点是样本数据、期望的结果,并清楚地说明您想要什么和不想要什么。
    • 感谢您的回复!我确实编辑了我的帖子以解释我的期望。但是,我的问题保持不变,我相信您的答案不满足我的要求? 如何根据存储在表collaterals中并通过外键TRNS_ID引用的项目自加入交易?
    • @Jhonny 。 . .这就是这个查询的作用。表达式 cy.COLL = cx.COLL 执行您要求的匹配。
    • 我刚刚验证了我上面的评论,即我将获得尽可能多的交易复制,因为我有基础抵押品:sqlfiddle.com/#!9/da532d/1这不是我所希望的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    相关资源
    最近更新 更多