仅查询最早可能日期的数值

时间:2014-10-02 15:14:34

标签: sql oracle oracle11g

我必须从oracle 11 db进行查询。 通过下面的查询,我从我的数据库中获取所有最近的TAG_VALUE, TAG_DESC, INSERTION_DATE and PROJECT_ID

SELECT * 
FROM   (SELECT t.tag_value, 
               t.tag_desc, 
               u.update_as_of                    AS INSERTION_DATE, 
               p.proj_id                         AS PROJECT_ID, 
               Row_number() 
                 over( 
                   PARTITION BY p.proj_id 
                   ORDER BY u.update_as_of DESC) RN 
        FROM   project p 
               join update u 
                 ON p.project_id = u.project_id 
               join tag t 
                 ON t.tag_id = u.tag_id 
        WHERE  t.tag_desc LIKE 'Equity%') 
WHERE  rn = 1;

然而,我遇到的情况是,我的请求的答案(没有按日期排序)看起来像这样:

+----------------------------------------------+
| TAG_VALUE TAG_DESC INSERTION_DATE PROJECT_ID |
+----------------------------------------------+
| null        Equity  14-DEC-14       1        |
| 0           Equity  14-DEC-14       1        |
| 312         Equity  14-DEC-14       1        |
| 23343       Equity  17-DEC-11       5        |
| 1263        Equity  16-DEC-11       5        |
| null        Equity  22-JÄN-14       2        |
| null        Equity  11-JÄN-14       2        |
| null        Equity  25-SEPT-13      2        |
| 0           Equity  20-SEPT-13      2        |
| 1234        Equity  19-SEPT-13      2        |
| 13415       Equity  18-SEPT-13      2        |
| 99999       Equity  16-OCT-10       9        |
+----------------------------------------------+

我的Result Set应该是这样的:

+----------------------------------------------+
| TAG_VALUE TAG_DESC INSERTION_DATE PROJECT_ID |
+----------------------------------------------+
| 312         Equity  14-DEC-14       1        |
| 23343       Equity  17-DEC-11       5        |
| 1234        Equity  19-SEPT-13      2        |
| 99999       Equity  16-OCT-10       9        |
+----------------------------------------------+

有两种情况,主要关注同一问题:

  • 如您所见,有两种情况,project_id = 1插入日期始终相同。但是,根据我上面的查询,由于null,我仍然会返回ordering。如何在不获取312null值的情况下获取号码0
  • 如果projectID = 2有不同的插入日期,而较早的日期有TAG_VALUE null元素。但是,我希望获得tagValue | 1234 Equity 19-SEPT-13 2 |,因为它是最新值?

如何,我可以基本上忽略所有null0值,并且只采用最早日期大于0值的数字吗?

我非常感谢你的回答!

4 个答案:

答案 0 :(得分:3)

您的问题是:“如何,我基本上可以忽略所有空值和0值值”

简单的答案是:删除WHERE子句中的那些记录。

我在这里使用AND t.tag_value > 0。如果您想允许负值,可以将其替换为AND t.tag_value <> 0 AND t.tag_value IS NOT NULL

SELECT * 
FROM 
(
  SELECT 
    t.tag_value,
    t.tag_desc, 
    u.update_as_of AS INSERTION_DATE, 
    p.proj_id AS PROJECT_ID, 
    ROW_NUMBER() OVER(PARTITION BY p.proj_id ORDER BY u.update_as_of DESC) RN
  FROM updated u 
  JOIN project p ON p.project_id = u.project_id  
  JOIN tag t ON t.tag_id = u.tag_id 
  WHERE t.tag_desc LIKE 'Equity%' AND t.tag_value > 0
)
WHERE RN = 1;

答案 1 :(得分:3)

考虑到您的分组在INSERTION_DATE DESC的PROJECT_ID内发生,并且TAG_VALUE为正,我调整了分析函数以实现结果。这可能不是一个强有力的解决方案,但肯定会帮助你。

数据设置:

CREATE TABLE Table1
    ("TAG_VALUE" varchar2(5), "TAG_DESC" varchar2(6), "INSERTION_DATE" varchar2(10), "PROJECT_ID" int)
;

INSERT ALL 
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES (NULL, 'Equity', '14-DEC-14', 1)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('0', 'Equity', '14-DEC-14', 1)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('312', 'Equity', '14-DEC-14', 1)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('23343', 'Equity', '17-DEC-11', 5)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('1263', 'Equity', '16-DEC-11', 5)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES (NULL, 'Equity', '22-JÄN-14', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES (NULL, 'Equity', '11-JÄN-14', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES (NULL, 'Equity', '25-SEPT-13', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('0', 'Equity', '20-SEPT-13', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('1234', 'Equity', '19-SEPT-13', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('13415', 'Equity', '18-SEPT-13', 2)
    INTO Table1 ("TAG_VALUE", "TAG_DESC", "INSERTION_DATE", "PROJECT_ID")
         VALUES ('99999', 'Equity', '16-OCT-10', 9)
SELECT * FROM dual
;

<强>查询:

SELECT tag_value, 
       tag_desc, 
       insertion_date, 
       project_id 
FROM   (SELECT tag_value, 
               tag_desc, 
               insertion_date, 
               project_id, 
               Last_value(Decode(tag_value, 0, NULL, 
                                            tag_value) ignore nulls) 
                 over ( 
                   PARTITION BY project_id 
                   ORDER BY insertion_date ROWS BETWEEN unbounded preceding AND 
                 unbounded 
                 following ) new_tag_value 
        FROM   table1) 
WHERE  tag_value = new_tag_value; 

<强>结果:

TAG_VALUE   TAG_DESC    INSERTION_DATE  PROJECT_ID
312         Equity      14-DEC-14       1
1234        Equity      19-SEPT-13      2
23343       Equity      17-DEC-11       5
99999       Equity      16-OCT-10       9

以下是fiddle

答案 2 :(得分:1)

您可以从表格的内部查询中选择min(Insertion_Date)和项目ID,并按Tag_Value&lt;&gt;过滤它空值。然后你在外部查询中,在project_id和insertion_date上用内部查询连接表。

答案 3 :(得分:1)

使用案例1:

如果我正确理解了您的用例,您可以通过分析函数的排序子句中的非null非零tag_value - s的“优先级”来完成,如下所示:

ROW_NUMBER() OVER (
    PARTITION BY p.proj_id
    ORDER BY
        CASE WHEN t.tag_value > 0 THEN 0 ELSE 1 END ASC,
        u.update_as_of DESC
) RN

当然,每当null标识的数据分区中没有其他tag_value - s时,这会在您的输出中为您提供p.proj_id个或零。


用例2:

如果你想完全摆脱零和null - s,你将不得不修改你的(内部)查询的where子句:

WHERE t.tag_desc LIKE 'Equity%'
    AND t.tag_value > 0