2017-07-31 71 views
2

我只需要在表格中找到唯一的汽车保险计算。在这种情况下,行如果在同一天内由一家公司在相同的汽车上接连不到五分钟内完成计算,则行不是唯一的。用于排除具有相似值但不相同的行的SQL查询

问题是,所有这些都是用不同的id一一完成的,唯一可以从DataBase中得到的是计算的时间和日期,制作它们的公司名称,型号,品牌和生产年份汽车。

更具体地讲,表我是这样的:

| Time_Date | company | year | model | brand | 
|--------------|---------|------|-------|--------| 
|20.08.16 15:31| A | 2014 | Teana | Nissan | 
|20.08.16 15:34| A | 2014 | Teana | Nissan | 
|20.08.16 15:38| A | 2014 | Teana | Nissan | 
|20.08.16 16:02| A | 2014 | Teana | Nissan | 
|20.08.16 15:36| B | 2014 | Teana | Nissan | 
|20.08.16 15:37| B | 2014 | Teana | Nissan | 
|21.08.16 15:33| A | 2015 | Teana | Nissan | 

,我需要得到什么:

| Time_Date | company | year | model | brand | 
|--------------|---------|------|-------|--------| 
|20.08.16 15:31| A | 2014 | Teana | Nissan | 
|20.08.16 16:02| A | 2014 | Teana | Nissan | 
|20.08.16 15:36| B | 2014 | Teana | Nissan | 
|21.08.16 15:33| A | 2015 | Teana | Nissan | 

数据库我用的是Vertica的。 请问,任何人都可以提出解决方案?这似乎不是一个大问题,但我有点坚持:(

PS

如果在15:31的记录,再有就是在15:34与同一家公司,一年,模型记录它不应该在决赛桌上,如果在此之后还有另一个计算,在最后一场计算后的不到五分钟内,类似于15:31,它不应该进入决赛桌,所以在这种情况下15:31,15:34,15:38是相同的,16:02是不同

+0

没有模式,我不能写查询你的,但这应该帮助:https://blog.jooq.org/2015/05/12/use-this-neat-window-function-trick-to-calculate-time-differences-in-a-time-series/ – Donnie

+1

嗨,欢迎来到所以。标记问题时请小心。 Vertica <> sql server,正确的答案将特定于您的数据库。 –

+0

记录时间15.38不在最终结果中。为什么?从15:31开始超过5分钟。如果我们拥有与15:31相同的记录,但时间为16:02,它会显示在结果中(我认为它应该提供要求)?提供的示例数据无法正确显示问题。简单地说,这个问题缺乏必要的细节来解决;包括适当的样本数据。 – xQbert

回答

0

Rextester没有Vertica的环境,让我无法测试以下

这里的。工作SQL Server版本http://rextester.com/FWK58234(需要边缘的情况下进行测试多一点)

的语法似乎是“接近”的SQL Server与只需要在DATEDIFF函数(如下的添加)

周围添加MI蜱

使用公用表格表达式(CTE)和分析LAG(回顾先前记录值)来确定每个公司年度模型品牌分区的datediff。然后排除所有那些日期时间差异的记录< = 5,但保留所有含有空格的记录(意味着它是滞后系列中的第一条记录)以及那些大于5分钟的记录,因为它们表示唯一记录。

注意:我的示例结果各不相同,因为我添加了其他数据来帮助边缘测试。

WITH CTE as (
    SELECT Time_date 
     , company 
     , year 
     , Model 
     , Brand 
     , datediff('mi',Lag(time_Date,1,NULL) over (partition by company, year, Model, Brand ORDER BY time_date asc),Time_Date) as MinuteDiff 
    FROM foo) 

    SELECT Time_date, company, year, Model, Brand, MinuteDiff 
    FROM CTE 
    --We need those with a NULL Minute Difference since they denote the 1st entry for a company, year model brand 
    --we also need those with a minute difference > 5 
    WHERE MinuteDiff > 5 or minutediff is null 
    ORDER BY Company, Year, Model, Brand, Time_date 

*注意:如果TIME_DATE纪录存在了一家公司,一年模式和品牌等,有一个条目,每5分钟3天的过程中,只有1个记录将被退回。在一个单一的差距将返回2条记录(裸露的差距是1号或最后一个条目)

+0

非常感谢,这对我有效。我也提出了一个解决方案,但它不如你的解决方案,谈论记忆。我认为,我可以按照公司,年份,品牌,型号和两个条件按时参加比赛:首次比其他时间少,timediff少于五分钟。所以我可以有一个重复行的列表,并将它们从我的表格中排除出来:) – Nibuton

+0

我真的想过自我加入,但我无法弄清楚如何使它工作。这就是为什么我结束了上述。起初,我认为这是过分的看你的数据集,我认为这是休息一天,但重新阅读文本后,我意识到你有5分钟的滚动变化。我们需要考虑。那时候我意识到我们需要某种方式来回顾先前记录time_date,按time_date排序并由公司和汽车分区;因此滞后()。 – xQbert

0

尝试此查询

;With cte( Time_Date , company , year , model , brand ) 
AS 
(

SELECT '20.08.16 15:31', 'A' , 2014 , 'Teana' , 'Nissan' UNION ALL 
SELECT '20.08.16 15:34', 'A' , 2014 , 'Teana' , 'Nissan' UNION ALL 
SELECT '20.08.16 15:38', 'A' , 2014 , 'Teana' , 'Nissan' UNION ALL 
SELECT '20.08.16 15:36', 'B' , 2014 , 'Teana' , 'Nissan' UNION ALL 
SELECT '20.08.16 15:37', 'B' , 2014 , 'Teana' , 'Nissan' UNION ALL 
SELECT '21.08.16 15:33', 'A' , 2015 , 'Teana' , 'Nissan' 
) 
SELECT Time_Date, company, [year], model, brand FROM 
    (
SELECT DISTINCT *, ROW_NUMBER()OVER(PARTITION BY company,model,[year] ORDER by Time_Date,company) dst FROM cte 
)Dt 
Where dst=1 
Order by [year] 

结果

Time_Date  company year model brand 
------------------------------------------ 
20.08.16 15:31 A  2014 Teana Nissan 
20.08.16 15:36 B  2014 Teana Nissan 
21.08.16 15:33 A  2015 Teana Nissan 
+0

矫枉过正在我看来。并且不能解决5分钟变化问题。 – xQbert

+0

当'Row_Number'是'Select' –

+0

@ Srini131的一部分时''Distinct'无用。你好!谢谢您的回答!我在日常工作中使用窗口函数来解决重复问题,就像你一样,但是这种情况是不同的,我编辑了一个问题的文本,所以如果你有这方面的想法,我会很感激。 – Nibuton

0

这是你想要的吗?

SELECT MIN(Time_Date) AS Time_Date, company, year, model, brand 
FROM Vertica.dbo.yourTable 
GROUP BY company, year, model, brand 
+0

其他人在我打字时回答。我为重复道歉。继续... – DataDad

+0

@xQbert,我写的查询会给你一个明确的公司名称,年份,型号,品牌和最短Time_Date ... – DataDad

+0

我认为我们都是错的。我们没有人正在处理5分钟的滞后问题。 – xQbert

0

这是很容易使用(Vertica的)解析函数CONDITIONAL_TRUE_EVENT来实现。

首先,我创建了包含您的数据的临时表mutable

CREATE LOCAL TEMPORARY TABLE mytable (time_date, company, year, model, brand) 
ON COMMIT PRESERVE ROWS AS 
    SELECT '2016-08-20 15:31:00'::timestamp(0),'A',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-20 15:34:00'::timestamp(0),'A',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-20 15:38:00'::timestamp(0),'A',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-20 16:02:00'::timestamp(0),'A',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-20 15:36:00'::timestamp(0),'B',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-20 15:37:00'::timestamp(0),'B',2014,'Teana','Nissan' UNION ALL 
    SELECT '2016-08-21 15:33:00'::timestamp(0),'A',2015,'Teana','Nissan' ; 

然后你只需要:

SELECT 
    MIN(time_date) AS time_date, 
    company, year, model, brand 
FROM (
    SELECT 
     time_date, company, year, model, brand, 
     CONDITIONAL_TRUE_EVENT(time_date - LAG(time_date) > '5 minutes') 
      OVER (ORDER BY time_date) AS cce 
    FROM mytable 
    ) a 
GROUP BY cce, company, year, model, brand 
; 
     time_date  | company | year | model | brand 
---------------------+---------+------+-------+-------- 
2016-08-20 15:31:00 | A  | 2014 | Teana | Nissan 
2016-08-20 16:02:00 | A  | 2014 | Teana | Nissan 
2016-08-20 15:36:00 | B  | 2014 | Teana | Nissan 
2016-08-21 15:33:00 | A  | 2015 | Teana | Nissan 
(4 rows) 
相关问题