查询多个表的组合(新增)

时间:2015-04-03 12:11:26

标签: sql-server

我对同一主题有疑问,但是暂停了。我不知道如何关闭那篇文章。所以我再次在这里发布,因为我有一个解决方案。

我的新问题是,还有其他方法可以重现我的查询。


这是原始问题:

这是一个表组合问题。我们有2-N源表。每个表都有一个处理器ID,一个事件名称和一个事件时间。我们需要将所有源表组合到一个目标表中。

组合规则是:一个源表中的任何事件必须与所有其他源表中的最新(相对于该表)事件组合。如果一个源表中的事件在其他一个源表中没有任何最新事件,则NULL将被添加到目标表中。

我的解决方案(三个源表的示例。它就像硬编码一样,所以我想尝试更简单的方法来编写代码,对于我有20个源表的情况):

create table #Ev1 (Pid INT, Ev1Name VARCHAR(20), Ev1Time DateTime)
INSERT INTO #Ev1 VALUES
     (1,   'ev11', '2015-06-01 02:00:00')
    ,(1,   'ev12', '2015-06-02 10:00:00')
    ,(1,   'ev13', '2015-06-03 18:00:00')


create table #Ev2 (Pid INT, Ev2Name VARCHAR(20), Ev2Time DateTime)
INSERT INTO #Ev2 VALUES 
     (1,   'ev21', '2015-06-01 6:20:00')
    ,(1,   'ev22', '2015-06-01 10:33:00') 
    ,(1,   'ev23', '2015-06-01 14:58:00')

create table #Ev3 (Pid INT, Ev3Name VARCHAR(20), Ev3Time DateTime)
INSERT INTO #Ev3 VALUES 
     (1,   'ev31', '2015-06-01 3:07:00')
    ,(1,   'ev32', '2015-06-01 4:12:00')
    ,(1,   'ev33', '2015-06-01 14:41:00')

 Select 
   Ev1.Pid
  ,Ev1.Ev1Name
  ,Ev1.Ev1Time
  ,(select top 1 Ev21.Ev2Name from #Ev2 Ev21
    where Ev21.Ev2Time <= Ev1.Ev1Time ORDER BY Ev21.Ev2Time DESC) As Ev2Name
  ,(select top 1 Ev21.Ev2Time from #Ev2 Ev21
    where Ev21.Ev2Time <= Ev1.Ev1Time ORDER BY Ev21.Ev2Time DESC) As Ev2Time  
  ,(select top 1 Ev31.Ev3Name from #Ev3 Ev31
    where Ev31.Ev3Time <= Ev1.Ev1Time ORDER BY Ev31.Ev3Time DESC) As Ev3Name
  ,(select top 1 Ev31.Ev3Time from #Ev3 Ev31
    where Ev31.Ev3Time <= Ev1.Ev1Time ORDER BY Ev31.Ev3Time DESC) As Ev3Time   
 INTO #FINAL                                          
 FROM #Ev1 Ev1
 INNER JOIN #Ev2 Ev2
 ON Ev1.Pid = Ev2.Pid
  INNER JOIN #Ev3 Ev3
 ON Ev1.Pid = Ev3.Pid
 )
 INSERT INTO #FINAL 
Select 
   Ev2.Pid
  ,(select top 1 Ev11.Ev1Name from #Ev1 Ev11
    where Ev11.Ev1Time <= Ev2.Ev2Time ORDER BY Ev11.Ev1Time DESC) As Ev1Name
  ,(select top 1 Ev11.Ev1Time from #Ev1 Ev11
    where Ev11.Ev1Time <= Ev2.Ev2Time ORDER BY Ev11.Ev1Time DESC) As Ev1Time
  ,Ev2.Ev2Name
  ,Ev2.Ev2Time 
  ,(select top 1 Ev31.Ev3Name from #Ev3 Ev31
    where Ev31.Ev3Time <= Ev2.Ev2Time ORDER BY Ev31.Ev3Time DESC) As Ev3Name
  ,(select top 1 Ev31.Ev3Time from #Ev3 Ev31
    where Ev31.Ev3Time <= Ev2.Ev2Time ORDER BY Ev31.Ev3Time DESC) As Ev3Time  

 FROM #Ev1 Ev1
 INNER JOIN #Ev2 Ev2
 ON Ev1.Pid = Ev2.Pid
 INNER JOIN #Ev3 Ev3
 ON Ev1.Pid = Ev3.Pid

 INSERT INTO #FINAL 
Select 
   Ev3.Pid
  ,(select top 1 Ev11.Ev1Name from #Ev1 Ev11
    where Ev11.Ev1Time <= Ev3.Ev3Time ORDER BY Ev11.Ev1Time DESC) As Ev1Name
  ,(select top 1 Ev11.Ev1Time from #Ev1 Ev11
    where Ev11.Ev1Time <= Ev3.Ev3Time ORDER BY Ev11.Ev1Time DESC) As Ev1Time
  ,(select top 1 Ev21.Ev2Name from #Ev2 Ev21
    where Ev21.Ev2Time <= Ev3.Ev3Time ORDER BY Ev21.Ev2Time DESC) As Ev2Name
  ,(select top 1 Ev21.Ev2Time from #Ev2 Ev21
    where Ev21.Ev2Time <= Ev3.Ev3Time ORDER BY Ev21.Ev2Time DESC) As Ev2Time    
  ,Ev3.Ev3Name
  ,Ev3.Ev3Time 

 FROM #Ev1 Ev1
 INNER JOIN #Ev2 Ev2
 ON Ev1.Pid = Ev2.Pid
 INNER JOIN #Ev3 Ev3
 ON Ev1.Pid = Ev3.Pid


SELECT distinct * FROM #FINAL 
ORDER BY Pid,Ev1Time, Ev2Time, Ev3Time  


--select * from #Ev1    
--select * from #Ev2
--select * from #Ev3
drop table #Ev1
drop table #Ev2
drop table #Ev3
drop table #FINAL

结果:

╔═════╦═════════╦═════════════════════════╦═════════╦═════════════════════════╦═════════╦═════════════════════════╗
║ Pid ║ Ev1Name ║         Ev1Time         ║ Ev2Name ║         Ev2Time         ║ Ev3Name ║         Ev3Time         ║
╠═════╬═════════╬═════════════════════════╬═════════╬═════════════════════════╬═════════╬═════════════════════════╣
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ NULL    ║ NULL                    ║ NULL    ║ NULL                    ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ NULL    ║ NULL                    ║ ev31    ║ 2015-06-01 03:07:00.000 ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ NULL    ║ NULL                    ║ ev32    ║ 2015-06-01 04:12:00.000 ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ ev21    ║ 2015-06-01 06:20:00.000 ║ ev32    ║ 2015-06-01 04:12:00.000 ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ ev22    ║ 2015-06-01 10:33:00.000 ║ ev32    ║ 2015-06-01 04:12:00.000 ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ ev22    ║ 2015-06-01 10:33:00.000 ║ ev33    ║ 2015-06-01 14:41:00.000 ║
║   1 ║ ev11    ║ 2015-06-01 02:00:00.000 ║ ev23    ║ 2015-06-01 14:58:00.000 ║ ev33    ║ 2015-06-01 14:41:00.000 ║
║   1 ║ ev12    ║ 2015-06-02 10:00:00.000 ║ ev23    ║ 2015-06-01 14:58:00.000 ║ ev33    ║ 2015-06-01 14:41:00.000 ║
║   1 ║ ev13    ║ 2015-06-03 18:00:00.000 ║ ev23    ║ 2015-06-01 14:58:00.000 ║ ev33    ║ 2015-06-01 14:41:00.000 ║
╚═════╩═════════╩═════════════════════════╩═════════╩═════════════════════════╩═════════╩═════════════════════════╝

1 个答案:

答案 0 :(得分:0)

以下查询给出相同的结果,除了没有NULL的行。如果我们在每个源表的开头添加一个默认行,则此查询可以生成NULL的行。

- 添加了行:(1,'ev00','1915-01-01 00:00:00')

Select 
  Ev1.Pid
 ,Ev1Name
 ,Ev1Time
 ,Ev2Name
 ,Ev2Time  
 ,Ev3Name
 ,Ev3Time      
INTO #FINAL                                      
FROM #Ev1 Ev1
INNER JOIN #Ev2 Ev2
 ON Ev1.Pid = Ev2.Pid
AND Ev2Time = (SELECT MAX(Ev2Time) FROM #Ev2 Ev21 WHERE Ev21.Ev2Time <= Ev1.Ev1Time)
INNER JOIN #Ev3 Ev3
 ON Ev1.Pid = Ev3.Pid
AND Ev3Time = (SELECT MAX(Ev3Time) FROM #Ev3 Ev31 WHERE Ev31.Ev3Time <= Ev1.Ev1Time)


insert INTO #FINAL 
  Select 
    Ev2.Pid
   ,Ev1Name
   ,Ev1Time
   ,Ev2Name
   ,Ev2Time  
   ,Ev3Name
   ,Ev3Time                                            
  FROM #Ev1 Ev1
  INNER JOIN #Ev2 Ev2
    ON Ev1.Pid = Ev2.Pid
   AND Ev1Time = (SELECT MAX(Ev1Time) FROM #Ev1 Ev11 WHERE Ev11.Ev1Time <= Ev2.Ev2Time)
  INNER JOIN #Ev3 Ev3
    ON Ev1.Pid = Ev3.Pid
   AND Ev3Time = (SELECT MAX(Ev3Time) FROM #Ev3 Ev31 WHERE Ev31.Ev3Time <= Ev2.Ev2Time)

 insert INTO #FINAL 
   Select 
     Ev3.Pid
    ,Ev1Name
    ,Ev1Time
    ,Ev2Name
    ,Ev2Time  
    ,Ev3Name
    ,Ev3Time                                            
   FROM #Ev3 Ev3
   INNER JOIN #Ev1 Ev1
     ON Ev1.Pid = Ev3.Pid
    AND Ev1Time = (SELECT MAX(Ev1Time) FROM #Ev1 Ev11 WHERE Ev11.Ev1Time <= Ev3.Ev3Time)
   INNER JOIN #Ev2 Ev2
     ON Ev1.Pid = Ev2.Pid
   AND Ev2Time = (SELECT MAX(Ev2Time) FROM #Ev2 Ev21 WHERE Ev21.Ev2Time <= Ev3.Ev3Time)

select distinct * from #final    

drop table #Ev1
drop table #Ev2
drop table #Ev3
drop table #final