【问题标题】:SQL want efficient query to SELECT columnA, columnB FROM table1 WHERE both columnA, columnB are in columnC FROM table2 WHERE columndD > valueSQL 希望高效查询 SELECT columnA, columnB FROM table1 WHERE columnA, columnB 都在 columnC FROM table2 WHERE columndD > value
【发布时间】:2022-11-01 17:10:55
【问题描述】:

我正在寻找一种更有效的方法来完成我已经用几个不同的 SQL 语句解决的问题。

问题:

我有两张桌子

  1. 事务表,以及
  2. 帐户表

    transactions 表的列如下所示:

    acct_sending acct_receiving amount tx_datetime
    100 101 10 yyyy-mm-dd hh-mm-ss
    101 100 5 yyyy-mm-dd hh-mm-ss
    101 200 1 yyyy-mm-dd hh-mm-ss
    200 101 11 yyyy-mm-dd hh-mm-ss
    200 234 22 yyyy-mm-dd hh-mm-ss
    234 567 24 yyyy-mm-dd hh-mm-ss
    567 890 56 yyyy-mm-dd hh-mm-ss
    890 100 73 yyyy-mm-dd hh-mm-ss

    accounts 表的列如下所示:

    account balance last_tx
    100 10 yyyy-mm-dd hh-mm-ss
    101 100 yyyy-mm-dd hh-mm-ss
    102 100 yyyy-mm-dd hh-mm-ss
    200 1000 yyyy-mm-dd hh-mm-ss
    234 10000 yyyy-mm-dd hh-mm-ss
    567 1000 yyyy-mm-dd hh-mm-ss
    890 100 yyyy-mm-dd hh-mm-ss

    我想创建一个查询,它返回一个事务列表,其中acct_sendingacct_receiving 都在accounts 表中并且balance 大于某个值。如果查询结果有一个 count 列包含这两个帐户之间的交易总数,则奖励积分。

    鉴于上面的transactionsaccounts 表,如果我们使用balance > 10 运行此查询,那么结果将是:

    acct_sending acct_receiving count
    101 200 2
    200 234 1
    234 567 1
    567 890 1

    ---

    我的解决方案

    首先,使用acct_sending = accountaccount > 10 的事务创建一个临时表

    CREATE TEMP TABLE temp_sending AS
    SELECT acct_sending, acct_receiving
    FROM transactions t
    WHERE EXISTS
        (SELECT account
        FROM accounts a
        WHERE t.acct_sending = a.account AND a.balance > 10)
    

    然后,使用 acct_receiving = accountaccount > 10 的最后一个临时表创建一个新的临时表

    CREATE TEMP TABLE temp_sending_receiving AS
    SELECT acct_sending, acct_receiving
    FROM temp_sending t
    WHERE EXISTS
        (SELECT account
        FROM accounts a
        WHERE t.acct_sending = a.account AND a.balance > 10)
    

    最后,我查询temp_sending_receiving 以获取唯一交易列表,并生成count 列。

    SELECT acct_sending, account_receiving, count(*)
    FROM (
        SELECT 
            CASE WHEN sender < receiver THEN sender ELSE receiver END AS sender, 
            CASE WHEN sender < receiver THEN receiver ELSE sender END AS receiver 
        FROM temp_sending_receiving
    ) AS x
    GROUP BY acct_sending, account_receiving
    

    运行这些查询中的每一个都会给我想要的结果,但是......

    有没有更好/更有效的方法来做到这一点?

    我正在考虑查询时间和内存效率。谢谢!!!

    ---

    笔记

    我在 DBeaver 和 Python 中将这些 SQL 查询作为脚本运行,所以我将它们添加为标签。如果那是错误的,LMK!谢谢。 :)

【问题讨论】:

    标签: python sql sqlite dbeaver


    【解决方案1】:

    您必须将transactions 加入accounts 的2 个副本并聚合:

    SELECT MIN(t.acct_sending, t.acct_receiving) sender,
           MAX(t.acct_sending, t.acct_receiving) receiver,
           COUNT(*) count
    FROM transactions t 
    INNER JOIN accounts a1 ON a1.account = t.acct_sending AND a1.balance > 10
    INNER JOIN accounts a2 ON a2.account = t.acct_receiving AND a2.balance > 10
    GROUP BY sender, receiver;
    

    请参阅demo

    【讨论】:

      猜你喜欢
      • 2018-04-28
      • 1970-01-01
      • 2013-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      • 2015-01-26
      • 2010-10-18
      相关资源
      最近更新 更多