Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询:获取列A和列B值不存在的行_Sql_Oracle - Fatal编程技术网

SQL查询:获取列A和列B值不存在的行

SQL查询:获取列A和列B值不存在的行,sql,oracle,Sql,Oracle,很抱歉,标题很混乱,但没有找到更好的标题。情况如下: CREATE TABLE orders ( order_id int NOT NULL, company_id int NOT NULL, last_update date NULL ) 表数据: ORDER_ID COMPANY_ID LAST_UPDATE 1 1 2020/06/08 2

很抱歉,标题很混乱,但没有找到更好的标题。情况如下:

CREATE TABLE orders (
    order_id    int  NOT NULL,
    company_id  int  NOT NULL,
    last_update date     NULL
)
表数据:

ORDER_ID   COMPANY_ID       LAST_UPDATE  
       1            1        2020/06/08  
       2            1        2020/06/08  
       3            1        2020/06/08  
       4            2        2020/06/08  
       5            2        2020/01/27  
       6            3        2020/06/08  
       7            3        2020/06/08  
       8            3        2020/06/08  
       9            3        NULL  
      10            4        2020/06/08  
      11            4        2020/06/08  
      12            4        2020/06/08  
      13            4        2020/06/08  
      14            4        2020/06/08  
我想要所有的行,有一个公司,其中没有同一个公司的行,并且最后的更新时间超过3个月或为空

什么不起作用: 我不能使用带有日期的简单WHERE子句,因为这只会过滤掉第5行和第9行。我只想要第1-3行和第10-14行

有效的方法是放慢速度:
我可以在SELECT DISTINCT company_ID[…]中使用子查询和company_ID,但这会完全破坏我的性能。在prod环境中,我有将近50M行,子查询的结果集太大了

我当前的解决方法: 我只是按公司id、上次更新和Java代码中的continue排序结果,如果上次更新太旧了。但这也不是最优的

问题: 要实现这一点,是否有性能SQL的唯一方法。也许是一组。。。有-从句


提前谢谢

您可以使用窗口功能:

select o.*
from (select o.*, min(last_update) over (partition by company_id) as min_last_update
      from orders o
     ) o
where min_last_update >= add_months(sysdate, -3);
但一个简单的不存在也可以:

select o.*
from orders o
where not exists (select 1
                  from orders o2
                  where o2.company_id = o.company_id and
                        o2.last_update < add_months(sysdate, -3)
                 );

其中任何一个都可以利用orderscompany\u id上的索引,即上次更新。

您可以使用窗口功能:

select o.*
from (select o.*, min(last_update) over (partition by company_id) as min_last_update
      from orders o
     ) o
where min_last_update >= add_months(sysdate, -3);
但一个简单的不存在也可以:

select o.*
from orders o
where not exists (select 1
                  from orders o2
                  where o2.company_id = o.company_id and
                        o2.last_update < add_months(sysdate, -3)
                 );
这两种方法中的任何一种都可以利用orderscompany\u id,last\u update上的索引。

您可以按如下方式使用窗口功能:

SELECT T.* FROM (
    SELECT T.*,
           MIN(CASE WHEN LAST_UPDATE IS NULL THEN LAST_UPDATE - 100 
                    ELSE LAST_UPDATE END) OVER(
               PARTITION BY T.COMPANY_ID
           ) AS MIN_LAST_UPDATE
      FROM ORDERS T ) T
 WHERE T.MIN_LAST_UPDATE >= ADD_MONTHS(SYSDATE, - 3);
您可以按如下方式使用窗口功能:

SELECT T.* FROM (
    SELECT T.*,
           MIN(CASE WHEN LAST_UPDATE IS NULL THEN LAST_UPDATE - 100 
                    ELSE LAST_UPDATE END) OVER(
               PARTITION BY T.COMPANY_ID
           ) AS MIN_LAST_UPDATE
      FROM ORDERS T ) T
 WHERE T.MIN_LAST_UPDATE >= ADD_MONTHS(SYSDATE, - 3);

我可以在SELECT DISTINCT company_ID[…]中使用子查询和company_ID,但这会完全破坏我的性能-听起来好像缺少索引。此表中定义了哪些索引,您当前的索引碎片级别是什么?这个表在质量上经历了什么类型的搅动?缺少索引是一个问题,但在我的例子中,最好的tipp正在从不存在变为不存在。我不知道SELECT1语法。使用此选项比使用SELECT DISTINCT company_id要好得多,因为这会导致一百万个id,这使得NOT IN检查非常昂贵。我可以在SELECT DISTINCT company_id[…]中使用子查询和company_id,但这会完全破坏我的性能-听起来好像缺少索引。此表中定义了哪些索引,您当前的索引碎片级别是什么?这个表在质量上经历了什么类型的搅动?缺少索引是一个问题,但在我的例子中,最好的tipp正在从不存在变为不存在。我不知道SELECT1语法。使用这个比使用选择不同的公司id要好得多,因为这会导致一百万个id,这使得不在检查非常昂贵!从不存在切换到不存在给了我巨大的性能提升。thx!从“不存在”切换到“不存在”给了我巨大的性能提升。