【问题标题】:Combining two-part SQL query into one query将两部分 SQL 查询合并为一个查询
【发布时间】:2010-06-07 20:45:20
【问题描述】:

我有一个 SQL 查询,我目前正在通过执行两个查询来解决该查询。我想知道是否有一种方法可以在单个查询中提高效率。

考虑两个表:

Transaction_Entries 表和 Transactions,每一个定义如下:

Transactions
- id
- reference_number  (varchar)


Transaction_Entries
- id
- account_id
- transaction_id (references Transactions table)

注意:每笔交易有多个交易条目。一些交易是相关的,并且会有相同的reference_number字符串。

要获取账户 X 的所有交易条目,我会这样做

SELECT E.*, T.reference_number, sum(debit_value) total 
  FROM Transaction_Entries E 
  JOIN Transactions T ON (E.transaction_id=T.id) 
 where E.account_id = X

下一部分是困难的部分。我想找到所有相关的交易,不管账户 ID。首先,我列出了在上一个结果集中找到的所有唯一参考编号。然后对于每一个,我可以查询所有具有该参考号的交易。假设我在 PreviousResultSet 中保存了上一个查询中的所有行

UniqueReferenceNumbers = GetUniqueReferenceNumbers(PreviousResultSet) // in Java
foreach R in UniqueReferenceNumbers // in Java
     SELECT *, sum(debit_value) total 
       FROM Transaction_Entries 
       where transaction_id IN (SELECT * 
                                 FROM Transactions 
                                WHERE reference_number=R)
       AND account_id = X
       GROUP BY another_field

有什么建议可以将其放入一个有效的查询中吗?

注意:我已经编辑了原始问题。新增的事实是,当我进行第二次查询时,我只查找与 reference_number 匹配且具有相同帐户 ID 的交易条目。另外,我正在尝试按 another_field 分组,并根据该分组对 debit_values 求和。

在尝试使用@Gratzy 提供的以下解决方案时,我发现返回的是重复的行,因此 sum(debit_value) 始终是应有的值的两倍。我认为这是因为那里有其他 Transaction_Entries 与 account_id 不匹配但符合加入条件。

【问题讨论】:

    标签: sql join performance


    【解决方案1】:

    试试

    SELECT distinct E2.*, T.reference_number 
    FROM Transaction_Entries E 
    INNER JOIN Transactions T ON (E.transaction_id=T.id) 
    INNER JOIN Transactions T2 on T.reference_number = T2.reference_number
    INNER JOIN Transaction_Entries E2 on T2.id = E2.transaction_Id
    where E.account_id = X
    

    如果帐户有多个相同reference_number的交易条目,您可能会得到重复

    编辑添加@van的建议我相信他是正确的,谢谢。

    编辑 对此进行了编辑以限制为相同的 account_id

    SELECT distinct E2.*, T.reference_number  
    FROM Transaction_Entries E  
    INNER JOIN Transactions T ON (E.transaction_id=T.id)  
    INNER JOIN Transactions T2 on T.reference_number = T2.reference_number 
    INNER JOIN Transaction_Entries E2 on T2.id = E2.transaction_Id and E2.account_id = E.account_id
    where E.account_id = x 
    

    【讨论】:

    • 我认为这会将其限制为仅共享相同 account_id 的条目。他提到它应该包括具有相同参考号的所有交易,无论帐户 ID 是什么。
    • 在我用 7 个 Transaction_Entries 创建的测试表上,您的查询返回一个包含 8 行的结果集。这对我来说似乎很令人惊讶。是否应该返回比现有更多的行,或者您的查询中有错误?如果您需要,我可以发布测试表。
    • @Eric Petroelje 不,我不这么认为,但它可能会导致重复行
    • 将您的SELECT 替换为SELECT DISTINCT E2.*,您就有了确切的答案。
    【解决方案2】:

    我认为这可行:

    SELECT * 
    FROM Transaction_Entries te
    INNER JOIN Transactions t ON t.id = te.transaction_id
    INNER JOIN (
      SELECT DISTINCT T.reference_number 
      FROM Transaction_Entries E 
      JOIN Transactions T ON (E.transaction_id=T.id) 
      WHERE E.account_id = X
    ) refs ON t.reference_number = refs.reference_number
    

    【讨论】:

      【解决方案3】:

      为什么不:

      select *
      from   Transaction_Entries
      where  transaction_id In (select   id, 
                                from     transactions 
                                group by reference_number) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-23
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        相关资源
        最近更新 更多