Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.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 如何在没有过程的情况下使用一系列日期连接表_Sql_Database_Oracle_Join - Fatal编程技术网

Sql 如何在没有过程的情况下使用一系列日期连接表

Sql 如何在没有过程的情况下使用一系列日期连接表,sql,database,oracle,join,Sql,Database,Oracle,Join,我有两张桌子,我们称之为A桌和B桌:- 表A如下所示: A.Num1 | A.Num2 | A.Date 12345 | 38170 | 28/05/2013 12345 | 38170 | 29/05/2013 12345 | 38170 | 31/05/2013 12345

我有两张桌子,我们称之为A桌和B桌:-

表A如下所示:

   A.Num1       |   A.Num2      |   A.Date      
   12345        |   38170       |   28/05/2013      
   12345        |   38170       |   29/05/2013      
   12345        |   38170       |   31/05/2013      
   12345        |   38170       |   01/06/2013      
   12345        |   38170       |   03/06/2013      
   12345        |   38170       |   04/06/2013  
   12345        |   38170       |   04/06/2013          
   12345        |   38170       |   07/06/2013  
    B.Num1      |   B.Num2      |   B.Status    |   B.Date
    12345       |   38170       |   New         |   28/05/2013  
    12345       |   38170       |   Closed      |   31/05/2013  
    12345       |   38170       |   Reopened    |   04/06/2013
表2b如下所示:

   A.Num1       |   A.Num2      |   A.Date      
   12345        |   38170       |   28/05/2013      
   12345        |   38170       |   29/05/2013      
   12345        |   38170       |   31/05/2013      
   12345        |   38170       |   01/06/2013      
   12345        |   38170       |   03/06/2013      
   12345        |   38170       |   04/06/2013  
   12345        |   38170       |   04/06/2013          
   12345        |   38170       |   07/06/2013  
    B.Num1      |   B.Num2      |   B.Status    |   B.Date
    12345       |   38170       |   New         |   28/05/2013  
    12345       |   38170       |   Closed      |   31/05/2013  
    12345       |   38170       |   Reopened    |   04/06/2013
我需要这样一个表作为输出-它应该基本上包含表A中的所有行+表B中的状态

    Num1        |   Num2        |   Status      |   Date
    12345       |   38170       |   New         |   28/05/2013      
    12345       |   38170       |   New         |   29/05/2013      
    12345       |   38170       |   Closed      |   31/05/2013      
    12345       |   38170       |   Closed      |   01/06/2013      
    12345       |   38170       |   Closed      |   03/06/2013      
    12345       |   38170       |   Reopened    |   04/06/2013  
    12345       |   38170       |   Reopened    |   04/06/2013      
    12345       |   38170       |   Reopened    |   07/06/2013      
此外,最好通过简单的SQL语句,而不是过程

提前谢谢。请评论任何澄清

因德鲁

使现代化 当表B中的两行状态发生更改但日期相同时,联接中的值不一致

例如:

我有两张表,比如A和B。它们是相当大的表,它们记录了特定的信息。表A通过每隔几天扫描一次数据来创建文档,但缺少状态列 若有更改,则表B将获得一个新条目,其中包含status列。 我需要匹配这两个,并为表a中对应于B的每个条目派生一个状态

表B 表A 期望输出 相反,我得到的是:使用杰弗里·坎普的回答

Id  | Num1  | Num2  | CreatedOn   | Status
55  | 11552 | 38170 | 28/05/2013  | Closed
99  | 11552 | 38170 | 30/05/2013  | Closed
145 | 11552 | 38170 | 31/05/2013  | Reopened
192 | 11552 | 38170 | 31/05/2013  | Reopened
223 | 11552 | 38170 | 04/06/2013  | Closed
这是:使用回复2-Mark Bannister

Id  | Num1  | Num2  | CreatedOn   | Status
55  | 11552 | 38170 | 28/05/2013  | New
99  | 11552 | 38170 | 30/05/2013  | New
145 | 11552 | 38170 | 31/05/2013  | Reopened
192 | 11552 | 38170 | 31/05/2013  | Reopened
223 | 11552 | 38170 | 04/06/2013  | Closed
显然,记录Id-55可以是新的,也可以是关闭的,因为表B中有两个条目是在2013年5月28日的同一天出现的。但逻辑是它是从“新建->关闭->重新打开”开始的
那么有什么方法可以做到这一点呢?

对于初学者来说,这是一种过于简单的方法:

SELECT A.Num1
      ,A.Num2
      ,NVL(
         (SELECT DISTINCT
                 FIRST_VALUE(B.Status)
                 OVER (ORDER BY B.Date DESC)
          FROM   B
          WHERE  B.Num1 = A.Num1
          AND    B.Num2 = A.Num2
          AND    B.Date <= A.Date
         ),'New') AS Status
      ,A.Date
FROM A;
不过,可能有一种更好的方法可以更快地工作。

试试:

select a.Num1, a.Num2, a."Date", b.Status
from TableA a
join (select TableB.*, 
             lead("Date",1) over (partition by Num1, Num2 
                                  order by "Date") NextDate
      from TableB) b
  on a.Num1 = b.Num1 and 
     a.Num2 = b.Num2 and 
     a."Date" >= b."Date" and 
     a."Date" < coalesce(b.NextDate,a."Date"+1)

SQLFiddle。< /P>但是,考虑到您期望的输出,您如何逻辑地将“新”的状态值与TEH日期“29/05/2013”联系起来?我会考虑不同的设计,因为日期范围的加入会导致性能不佳,请不要冒险进入表的语义。我可以向您保证,这是所需的输入和输出!同意,但我被卡住了。该系统已经实施。现在更改架构不是一个选项…新建、关闭和重新打开是唯一可能的状态吗?根据您的链接,它可以工作。但我不确定这是否是Oracle SQL语法。我收到一个错误“无效SQL语句”,为什么日期在引号中?@rtindru:您使用的是哪个版本的Oracle?如果您查看链接的左上角,您应该会看到这是在Oracle11g中运行的;它在Oracle 11中绝对有效。我认为它应该在Oracle10以及Jeffrey方法适用的任何Oracle版本中都有效。如果您可以包含错误消息的全部详细信息,则可以确定原因。Date在引号中,因为Date在Oracle中是保留字-我希望数据库中的实际列名不是保留字。啊,好吧,列名不是Date。我只是把它缩短了。我会再查一查,然后给你回电话。我认为它的甲骨文11.1这是一个很好的方法,我怀疑它的性能比我的好。b子查询基本上是将a添加到日期,以便每行代表一个日期范围。如果某些记录失败,您需要隔离它们,或者为它们运行子查询以查看出了什么问题。这种方法过于简单,可能只适用于一次只对一条记录感兴趣的情况,但对于报告,您应该使用Bannister的方法。

select a.Num1, a.Num2, a."Date", b.Status
from TableA a
join (select TableB.*, 
             lead("Date",1) over (partition by Num1, Num2 
                                  order by "Date") NextDate
      from TableB) b
  on a.Num1 = b.Num1 and 
     a.Num2 = b.Num2 and 
     a."Date" >= b."Date" and 
     a."Date" < coalesce(b.NextDate,a."Date"+1)