如何在 SQL 查询的结果中通过偏移量过滤掉最后一列 != null 行之后的所有列 = null 行

How to Filter Out All column = null Rows Past the Last column != null Row, by an Offset, in the Result of a SQL Query

我有一个 SQL table 看起来像这样:

Flow             Head            Series_Name

0                null            A           
0                null            B
10               null            A
10               null            B
20               null            A
22.5             88              B
20               null            B
30               null            A
30               null            B
39.42            60.1            A
40               null            A
40               null            B
etc...           etc...          etc...
5000             null            A
5000             null            B

基本上,此 table 的想法是能够使用它在 Cognos Report Studio 的折线图元素中绘制 Flow vs Head。这很好用,因为我可以将 Flow 列拖放到 X 轴中,将 Head 列拖放到 Y 轴中,将 Series_Name 列拖放到 Legend 中。对于上面的示例 table,这将生成两条曲线 A 和 B。

请注意,两个系列的 Flow 值都在 0 到 5000 之间,递增 10。另请注意,Head 值大部分为空,除非数据点可用。 (通常,数据点的 Flow 值不会完全落在能被 10 整除的数字上,但如果是,那对我遇到的问题应该无关紧要。)

所以,这就是我遇到的问题。当我生成折线图时,一切看起来都很棒,除了那些数据点具有较低 Flow 值的资产。对于这些,0 到 5000 的固定 X 轴范围不会产生漂亮的折线图,因为曲线相对于 Y 轴被挤压。 (顺便说一句,Y 轴看起来很好,因为折线图元素会自动缩放其 Y 轴。)

我知道需要做些什么来解决这个问题。我需要能够为此 table 编写一个 SQL 查询,以过滤掉 Head = null 的所有行,无论最后一个 Head != null 行是什么。最好有一个偏移量,这样它直到最后一个 Head != null 行之后的几行才开始切断。这将使图表看起来更漂亮。

对于我上面给出的示例 table,如果您假设 Flow = 39.42 & Head = 60.1 行是 table 中的最后一个 Head != null 行,那么一个不错的查询table 的结果如下,它排除了它之后的所有行(偏移量为 6 行):

Flow             Head            Series_Name 

0                null            A           
0                null            B
10               null            A
10               null            B
20               null            A
22.5             88              B
20               null            B
30               null            A
30               null            B
39.42            60.1            A
40               null            A
40               null            B
50               null            A
50               null            B
60               null            A
60               null            B

我知道这需要在 SELECT 语句末尾有一个 WHERE 子句,但我不确定如何使用这样的子句来排除不必要的行查询结果的后半部分。 SQL 查询需要使用原生 SQL 语法编写。

这样的查询结果,去掉了所有不必要的数据,图表会很漂亮!感谢您的帮助!

我在 SQL SERVER 中制作了这个示例,相同的代码在 oracle 中应该可以工作

SELECT *
from Events
WHERE Flow <= (SELECT max(Flow) + 3*10 FROM Events WHERE [HEAD] IS NOT NULL)

3*10 to offset three more rows.

如果你想要更通用和可扩展的东西,你可以使用 row_number() 但需要小心 order by

WITH addRow_id as (
     SELECT *, ROW_NUMBER() OVER ( ORDER BY [Flow], [Series_Name]) as rn
     FROM Events
),
lastID as (
     SELECT MAX(rn) as last_row
     FROM addRow_id
     WHERE [HEAD] IS NOT NULL
)
SELECT *
FROM addRow_id A
CROSS JOIN lastID L
WHERE A.rn <= L.last_row + 6;

可能获取低于截止值的所有内容,并将其与截止值以上的所有内容合并,但按流排序并应用了 10 个限制:-

SELECT *
FROM sometable
WHERE flow <= 
(
    SELECT MAX(flow)
    FROM sometable 
    WHERE head IS NOT NULL
)
UNION
SELECT flow, head, series_name
FROM
(
    SELECT flow, head, series_name
    FROM sometable
    WHERE flow > 
    (
        SELECT MAX(flow)
        FROM sometable 
        WHERE head IS NOT NULL
    )
    ORDER BY flow
    LIMIT 10
) sub1

但要看订单详情