【问题标题】:How to designate specified records based on the date in huge Oracle table如何在巨大的Oracle表中根据日期指定指定记录
【发布时间】:2019-03-23 18:51:41
【问题描述】:

我有一个巨大的表,有 5 亿条记录。我必须根据 4 个属性将此表分成组(分区)。

如果日期差异大于或等于 7 天,我必须在每个组中选择(设置标志)最新记录和后续记录(从 7 天期间选择最新条目)。

我认为表格太大,无法对其进行计算。我应该把它分成几个较小的吗?但是一组的所有记录都必须在同一个表中。

有没有办法只使用 SQL 来指定适当的记录(不将其提取到 PL/SQL 数组中)?这是一次性操作。

你知道如何解决这个问题吗?

示例(一组 - 属性和日期 dd-mm-yyyy 格式):

  1. [A1 A2 A3 A4] 08-05-2018(标志 1 - 最新的)
  2. [A1 A2 A3 A4] 06-05-2018(标志 0 - 差异小于 7 天)
  3. [A1 A2 A3 A4] 01-05-2018(标志 1 - 差异更大/等于 7 天)
  4. [A1 A2 A3 A4] 30-04-2018(标志 0 - 差异小于 7 天 - 相对于记录 3)
  5. [A1 A2 A3 A4] 10-04-2018(标志 1 - 差异更大/等于 7 天 - 相对于记录 3)

【问题讨论】:

  • 因此,对于每个键,我查看最新记录并将其标记为 1。然后我查找该键的第一条记录,该记录至少早 7 天,并将其标记为 1。然后我将此记录date 并再次查找该密钥的第一个记录,该记录至少早 7 天,并将其标记为 1。依此类推。 (所有其他记录都标记为 0。)是吗?
  • 预期的结果是什么?使用正确标志更新了所有 5 亿条记录的表?还是仅显示 5 亿条记录的查询结果,每条记录都带有计算的标志?显示所有标记为 1 的行的查询结果?
  • @ThorstenKettner - 正是您的第一条评论的情况。结果 - 使用正确的标志更新源表。
  • 因此您需要读取整个表,按顺序扫描并更新每条记录。我会为此编写一个 PL/SQL 函数,在其中循环所有记录。如果您希望大多数记录必须标记为 0,那么您可能希望先对标记 0 进行完整更新,然后在循环中只更新单个记录为 1。
  • @ThorstenKettner 试图只考虑 SQL 查询,但似乎你是对的 - PL/SQL 函数将是必要的......谢谢

标签: sql database oracle performance plsql


【解决方案1】:

由于您需要将表转换为分区,但只保留与之前记录的日期差大于7的记录,如果可能的话,我建议您尽可能删除不需要的记录。

您需要比较相邻的行,因此您可以使用lag()lead() 函数。

https://oracle-base.com/articles/misc/lag-lead-analytic-functions

我认为以下查询可能会有所帮助:

SELECT pk, A1, A2, A3, A4, a_date
  FROM (SELECT PK, A1, A2, A3, A4, a_date,
       LAG (a_date, 1, 0)   OVER (ORDER BY A1, A2, A3, A4, a_date DESC) AS date_prev,
       a_date - LAG (a_date, 1, 0) OVER (ORDER BY A1, A2, A3, A4, a_date DESC) AS date_diff
          FROM tbl1)
 WHERE date_diff < 7

这些是您可以删除的记录。

然后您可以根据表的结构创建一个分区表 - 基于列表的分区,然后插入到 select 中。

【讨论】:

  • 同时按 Y 和 O 键会杀死你吗?如果您想受到专业社区的重视,在旧的 nkia dumfone 上 nt ryt lyk 一个 Tngr 会有所帮助吗?
  • 这个想法从何而来? OP 的问题中没有任何内容表明他们要删除记录。
  • @APC - 谢谢你的回答。除了一个例外,这似乎是一个好方法: date_diff 在当前记录和先前记录之间指定。但它应该在当前和最后一个正标记之间指定。例如你标记了第一条记录。第二个与第一个相比。让我们假设 date_dif 小于 7,因此第二条记录被标记为负数。第三条记录与第一条记录进行比较,而不是与第二条记录进行比较(第一条被标记为阳性)。等等……
  • @Darek:写这个答案的是 AmeyaN99,而不是 APC。你是说这个解决方案没有做你想要的,但你接受了?为什么?
  • 我的错,当然是@AmeyaN99 - 谢谢你的回答
猜你喜欢
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 2014-08-18
  • 2014-01-09
  • 2017-10-20
  • 1970-01-01
相关资源
最近更新 更多