【问题标题】:Reduce total number of SQL queries减少 SQL 查询的总数
【发布时间】:2014-10-30 16:11:01
【问题描述】:

我目前正在尝试通过将 2 个查询合二为一来减少发送到我的 RedShift 集群的 sql 查询总数。

这是我的场景。

  • 给定一个卡号范围,确定该范围内的哪些卡昨天进行了交易。
  • 对于这些卡中的每一张,确定其最后记录的交易(如果有)。

这是我目前的缓慢但正确的方法:

query1 = '''SELECT card_no, timestamp, code_one, transaction_amount
        FROM table1
        WHERE card_no BETWEEN %s AND %s
        AND code_one = 202
        AND code_two = 0
        AND timestamp < date_trunc('day', CURRENT_DATE)
        AND timestamp >= (CURRENT_DATE - INTERVAL '1 days')
        ORDER BY card_no, timestamp DESC''' % (card_from, card_to)

query2 = '''SELECT * FROM table2 WHERE card_number = %s
        ORDER BY transaction_date DESC LIMIT 1''' % card_no

这种方法会产生正确的输出。
Query1 首先运行,并根据不同的范围创建事务文件。
然后我对这些文件中的每个 card_no 运行 query2 并执行一些逻辑操作以获得最终输出。

我的数据集现在包含 4000 多个卡片范围,每个范围返回 30 到 100 张带有交易的卡片。查询的数量迅速增加,超出了我的控制。
有没有办法可以将这两个查询合并为一个以大幅减少查询总数?

感谢您的宝贵时间。

【问题讨论】:

  • FROM table1 LEFT JOIN table2 ON table1.card_no = table2.card_number 是否不适合您?如果你这样做,你会在一个查询中得到你需要的东西。
  • 这两个表之间有关系吗?如果有,你可以简单地用左连接来连接它们
  • 很遗憾,这不起作用。我只想附加到查询 1 的结果,查询 2 的结果,但由于查询 2 依赖于查询 1,我似乎找不到围绕它的逻辑。
  • 您是否总是要获取所有卡片范围的所有数据(目前通过多个查询)?如果是这样,为什么要过滤而不是一次获取所有数据?
  • 每个卡范围包含很多卡号,其中大部分是昨天没有交易的。第一个检查是只过滤昨天有交易的卡。第二个检查是查看这些卡号中哪些之前进行过交易,哪些没有。希望这能澄清一点。

标签: mysql sql


【解决方案1】:

你只需要创建一个join并使用MAX()聚合函数

SELECT
    table1.card_no AS card_no,
    table1.timestamp AS timestamp,
    table1.code_one AS code_one,
    table1.transaction_amount AS transaction_amount,
    MAX(transaction_date) AS max_trans_date
FROM table1
LEFT JOIN table2
  ON table1.card_no = table2.card_number
WHERE table1.card_no BETWEEN %s AND %s
AND table1.code_one = 202
AND code_two = 0
AND table1.timestamp < date_trunc('day', CURRENT_DATE)
AND table1.timestamp >= (CURRENT_DATE - INTERVAL '1 days')
GROUP BY card_no
ORDER BY card_no

max_trans_date 具有非空值的那些记录将是在 table2 上进行过交易的卡。如果您将 LEFT JOIN 更改为 INNER JOIN,您将只会获得之前交易过的那些卡。如果您在 where 子句 AND max_trans_date IS NULL 中使用带有附加过滤器的 LEFT JOIN,您将只获得那些没有以前交易的卡。

【讨论】:

  • 我喜欢这个想法,我认为这个想法很接近,但如果没有 group by 子句中的 select 语句的其他成员,您的查询将不会运行。这也将用查询 2 中的记录替换查询 1 中的记录,而不是追加它们
  • @Zihs 查询将运行,假设表1中每个卡id只有一条记录,聚合不会有任何问题。如果表 1 中每个 card_no 有多个记录,那么您需要在其他 table1 列上指定聚合函数,否则您将得到不可预测的结果。我想我不知道您所说的替换或附加是什么意思。这严格来说是一个 SELECT,它根本不会更改任何数据。如果您使用实际的表架构信息和示例数据以及您期望的最终输出来更新您的问题,这将有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 2020-09-29
  • 2015-06-04
  • 2018-04-01
  • 1970-01-01
相关资源
最近更新 更多