2017-07-31 108 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) 
相關問題