我有一个包的两个状态,即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小时的城市水平。
答案 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