2017-06-02 87 views
0

我有一个非常独特的查询,我必须写,并希望在1个查询中完成所有操作,但不确定是否可以。如何在此查询中使用分析函数

我有一篇文章列表,每篇文章都有一个唯一的ID。应用程序将此ID传递给存储过程。然后,我将检索该文章AND,以前的文章为&。所以,该列表按日期排序,我可以获得下一个&前一个。

我这样做是通过LEAD &滞后。它在一个查询中起作用。但是,在某些情况下,下一篇或上一篇文章在其中一个字段中为NULL。如果该字段为NULL,那么我基本上可以获取下一篇文章,该文章不是NULL。

然后还有一件事。从应用程序传递的文章有一个分配给它的类别。接下来的&以前的文章必须属于同一类别。

现在这个查询很大,但是它会在文章ID前面的下一个&工作,因为子查询按日期排序所有东西。但有了这两个新的标准,即NULL因素和类别因素,我看不出在一个查询中如何做到这一点。

有什么想法?或者需要一些例子,或者我现有的查询?

感谢您的所有时间。

回答

0

甲骨文设置

CREATE TABLE articles (id, category, value, dt) AS 
    SELECT 1, 1, 1, DATE '2017-01-01' FROM DUAL UNION ALL 
    SELECT 2, 1, 2, DATE '2017-01-02' FROM DUAL UNION ALL -- Previous row 
    SELECT 3, 1, NULL, DATE '2017-01-03' FROM DUAL UNION ALL -- Ignored as value is null 
    SELECT 4, 1, 1, DATE '2017-01-04' FROM DUAL UNION ALL -- Chosen id 
    SELECT 5, 2, 3, DATE '2017-01-05' FROM DUAL UNION ALL -- Ignored as different category 
    SELECT 6, 1, 5, DATE '2017-01-06' FROM DUAL;   -- Next row 

查询:(:your_id下面设置为4中的示例输出)

SELECT * 
FROM (
SELECT a.*, 
     LAG(CASE WHEN value IS NOT NULL THEN id END) IGNORE NULLS OVER (PARTITION BY category ORDER BY dt) AS prv, 
     LEAD(CASE WHEN value IS NOT NULL THEN id END) IGNORE NULLS OVER (PARTITION BY category ORDER BY dt) AS nxt 
FROM articles a 
) 
WHERE :your_id IN (id, nxt, prv) 
AND (id = :your_id OR value IS NOT NULL) 
ORDER BY dt; 

输出

 ID CATEGORY  VALUE DT       PRV  NXT 
---------- ---------- ---------- ------------------- ---------- ---------- 
     2   1   2 2017-01-02 00:00:00   1   4 
     4   1   1 2017-01-04 00:00:00   2   6 
     6   1   5 2017-01-06 00:00:00   4