SQL查询以排除具有相似但不相同的值的行

时间:2017-07-31 15:58:00

标签: sql vertica

我需要在表格中找到唯一的汽车保险计算。在这种情况下, 行不是唯一的,如果计算在同一天内由一家公司在同一天内一个接一个地在不到五分钟内完成

问题是,所有这些都是逐个完成的,具有不同的ID,我只能从DataBase获得的是计算的时间和日期,制作它们的公司名称,模型,品牌和生产年份汽车。

更具体地说,表格I看起来像这样:

|   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。 请问,有人建议解决方案吗?这似乎不是一个大问题,但我有点卡住:(

P.S。

如果在15:31有记录,那么在15:34有一个同一公司,年份,模型的记录它不应该在决赛桌中,如果之后还有另外一个计算少于五在类似于15:31的最后一次计算之后的几分钟,它也不应该在决赛桌中。所以在这种情况下15:31,15:34,15:38是相同的,16:02是不同的。

4 个答案:

答案 0 :(得分:0)

Rextester没有Vertica环境,所以我无法测试以下内容。

这是一个有效的SQL Server版本http://rextester.com/FWK58234(边缘情况需要进行更多测试)

语法似乎"关闭"到SQL Server,只需要在datediff函数中添加周围的刻度(下面添加)

使用公用表表达式(CTE)和Analytic LAG(回顾先前记录值)来确定每个公司年度模型品牌分区的日期值。然后消除日期时间差<= 5的所有记录,但保留所有具有null datediff的记录(暗示它是滞后系列中的第一个记录)和那些大于5分钟的记录,因为它们表示唯一记录。 / p>

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

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记录,以便在3天的课程中每5分钟输入一次,则只会返回1条记录。一个单一的差距将返回2个记录(将差距作为第一个或最后一个条目)

答案 1 :(得分: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

答案 2 :(得分:0)

这是你想要的吗?

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

答案 3 :(得分: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)