扩展查询的结果集(或使用中间表)?

Posted

技术标签:

【中文标题】扩展查询的结果集(或使用中间表)?【英文标题】:Expanding a query's result set (or using an intermediate table)? 【发布时间】:2011-07-07 17:11:08 【问题描述】:

作为我previous question 的后续行动,我想探索一个替代方案。我的表格布局如下:

T1:  ID  |  Date  |  Hour  | Interval

时间间隔从112(每小时的5 分钟间隔),时间从124,日期/ID 是任意的。当我从外部源提取数据时,有些行的间隔为0。当区间有0 时,表示覆盖了整个小时(即从112 的所有区间)。

示例数据:

T1:  1  |  1/1/2011  |  1  |  1
     1  |  1/1/2011  |  1  |  4
     1  |  1/1/2011  |  1  |  0

     1  |  1/1/2011  |  2  |  2
     1  |  1/1/2011  |  2  |  5

     1  |  1/1/2011  |  3  |  0

请注意,间隔和0 标记的间隔重叠。有什么办法可以将0 间隔扩展到一小时的所有 12 个间隔?所以,我基本上想将示例数据转换为:

T1:  1  |  1/1/2011  |  1  |  1
     1  |  1/1/2011  |  1  |  2
     1  |  1/1/2011  |  1  |  3
     1  |  1/1/2011  |  1  |  4
     ...
     1  |  1/1/2011  |  1  |  11
     1  |  1/1/2011  |  1  |  12

     1  |  1/1/2011  |  2  |  2
     1  |  1/1/2011  |  2  |  5

     1  |  1/1/2011  |  3  |  1
     1  |  1/1/2011  |  3  |  2
     1  |  1/1/2011  |  3  |  3
     ...
     1  |  1/1/2011  |  3  |  11
     1  |  1/1/2011  |  3  |  12

这样的事情甚至可以使用 SQL 实现吗?

【问题讨论】:

【参考方案1】:

创建一个表“intervals”,其中 12 行包含一个字段“iinterval”,值从 1 到 12。

iinterval
        1
        2
        3
        4
        5
        6
        7
        8
        9
       10
       11
       12

然后您可以在区间表和区间为零的那些 T1 行之间进行交叉连接。 (我重命名了 T1 字段 Date、Hour 和 Interval,因为它们都是保留字。)

SELECT T1.ID, T1.idate, T1.ihour, intervals.iinterval
FROM T1, intervals
WHERE T1.iinterval=0;

由于没有指定 JOIN 条件,每个 T1 行(其间隔为零)将与每个间隔行连接。

ID  idate    ihour iinterval
 1  1/1/2011     1         1
 1  1/1/2011     1         2
 1  1/1/2011     1         3
 1  1/1/2011     1         4
 1  1/1/2011     1         5
 1  1/1/2011     1         6
 1  1/1/2011     1         7
 1  1/1/2011     1         8
 1  1/1/2011     1         9
 1  1/1/2011     1        10
 1  1/1/2011     1        11
 1  1/1/2011     1        12

如果对于间隔等于 0 的行,这获得了您想要的结果,您可以在 UNION 查询中使用它来将这些行添加到间隔为为零的 T1 行。

SELECT a.ID, a.idate, a.ihour, a.iinterval
FROM T1 AS a
WHERE a.iinterval<>0
UNION
SELECT T1.ID, T1.idate, T1.ihour, intervals.iinterval
FROM T1, intervals
WHERE T1.iinterval=0;

我希望这将为您指出一些有用的东西,但怀疑这正是您最终想要的。我的保留是因为这种情况:“注意间隔和标记为 0 的间隔有重叠”。我不知道应该如何应对这些重叠。

【讨论】:

基本上,我将此结果集与另一个表进行内部连接,该表仅包含“有效”间隔(即 1 到 12)。它应该与现有的重叠(并摆脱间隔 0 行),就像我的结果集看起来一样(最后 1 小时的数据只包含间隔 1 到 12,没有重复)。但是,即使该方法确实给我留下了重复项,我确信我可以创建另一个查询来仅过滤掉不同的行... UNION 仅返回不同的行,因此您可能已经了解了这一点(如果我正确理解了您的评论)。还有 UNION ALL,它比 UNION 运行得更快,并且会返回所有行,包括重复的行。但这不是我的建议。 啊,抱歉,我不知道 UNION 只返回不同的行。我会接受这个答案,但我很好奇,你认为有没有办法在不使用中间表的情况下解决这个问题(或者这超出了结构化查询语言本身的范围?) 是的,我想是的。您不必将 UNION 查询的结果保存在表中。将其保存为命名查询,然后将该查询和您的其他表用作新查询中的数据源。

以上是关于扩展查询的结果集(或使用中间表)?的主要内容,如果未能解决你的问题,请参考以下文章

关于oracle中table函数的使用

将两个查询与计数函数组合为一个结果集

获取 dapper.QueryMultiple 方法返回的结果集计数

MySQL 存储过程,获取使用游标查询的结果集

hibernate框架之-查询结果集返回类型

多表查询