两个状态

时间:2016-12-23 05:47:45

标签: sql oracle

我有一个包的两个状态,即Dropped和Intransit,并且这两个状态都在数据库的不同行中捕获,因此对于Ex。

City1 Pkg1    Status    Change_Date
ABC   1234    Dropped   07-DEC-16 02.52.28.000000 PM
ABC   1234   Intransit  07-DEC-16 05.52.28.000000 PM

所以,我需要在City级别的intransit的平均值减去所有包的丢弃时间。在这个Pkg 1的例子中,差异是3个小时,同样想要达到1000个包平均2.8小时的城市水平。

3 个答案:

答案 0 :(得分:2)

您应该首先尝试创建视图,这将使此单个表实体列出单行包。

考虑表结构是这样的

CREATE TABLE `packageList` (
  `cityId` int(10) NOT NULL,
  `packageId` int(10) NOT NULL,
  `status` varchar(256) NOT NULL,
  `changedate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

所以你的观点应该根据以下的查询

创建

    CREATE VIEW packageStatus AS 
    SELECT 
    pl1.cityId as cityId ,
    pl1.packageId as packageId ,
    pl1.changeDate as DropTIme,
    pl2.changeDate as Picktime 
    FROM 
    `packageList` pl1 , `packageList` pl2 
    WHERE 
    pl1.status = "Droped" AND pl2.status = "Picked" 
    and pl1.packageId = pl2.packageId

之后它将成为Group on的简单查询,只能查看下面的查询


SELECT 
   tt.cityid,avg(DATEDIFF(tt.DropTIme,tt.Picktime))  
FROM 
   (SELECT 
    pl1.cityId as cityId ,
    pl1.packageId as packageId ,
    pl1.changeDate as DropTIme,
    pl2.changeDate as Picktime 
    FROM 
    `packageList` pl1 , `packageList` pl2 
    WHERE 
    pl1.status = "Droped" AND pl2.status = "Picked" 
    and pl1.packageId = pl2.packageId) as tmpTable tt Group BY cityId

答案仅使用查询而不创建视图将如下所示

SELECT 
   cityid,avg(DATEDIFF(DropTIme,Picktime))
FROM (SELECT pl1.cityId as cityId , pl1.packageId as packageId , pl1.changeDate as DropTIme, pl2.changeDate as Picktime FROM packageList pl1 , packageList pl2 WHERE pl1.status = "Droped" AND pl2.status = "Picked" and pl1.packageId = pl2.packageId) as tmpTable Group BY cityId

答案 1 :(得分:0)

只需从上一个change_date中减去change_date:

select city, Pkg, status, Change_Date, 
       change_date - 
           lag(change_date, 1, change_date) over (partition by pkg order by case status when 'Dropped' then 1 else 2 end ) as diff
where status in ('Dropped', 'Intransit')
from the_table;

从另一个中减去一个date的结果是表示这两个值之间的(分数)天数。因此,8小时将导致0.33

order by case status when 'Dropped' then 1 else 2 end在具有不同状态的行(假设只有两个值)之前对状态为Dropped的行进行排序

您可以将上述内容包装到派生表中,以获得平均持续时间:

select avg(diff)
from (
  select city, Pkg, status, Change_Date, 
         change_date - 
             lag(change_date, 1, change_date) over (partition by pkg order by case status when 'Dropped' then 1 else 2 end ) as diff
  where status in ('Dropped', 'Intransit')
  from the_table;
) t;

答案 2 :(得分:-1)

您需要嵌套请求,我认为您在大量软件包上的性能会很差。将所有这些信息放在一行中会更容易:

CityID PkgID状态Intransit Dropped

使用您的数据模型,我认为一个正确的SQL语法将是(未经测试):

Select avg(time), city
From (
    Select (b.dropped - c.transit) as time, a.city as city, a.packageId 
    From myTable a, 
         (Select d.Change_Date as dropped
        From myTable d
        where a.packageId = d.packageId and d.Status = 'Dropped') b,
         (Select e.Change_Date as transit
        From myTable e
        where a.packageId = e.packageId and d.Status = 'Intransit') c
)
Group By city