2017-10-11 93 views
2

我有一個數據庫中的幾個字段看起來像這樣:SQL - 如何找到使用起始日期缺少活動天數日期和結束日期

trip_id 

start_date 
end_date 

start_station_name 
end_station_name 

我需要編寫一個查詢,顯示所有沒有活動的站我寫了下面的查詢,但它沒有給出正確的輸出:

select 
    start_station_name, 
    extract(date from start_date) as dt, 
    count(*) 
from 
    trips_table 
where 
    (
     start_date >= timestamp('2015-01-01') 
     and 
     start_date < timestamp('2016-01-01') 
    ) 
group by 
    start_station_name, 
    dt 
order by 
    count(*) 

有人可以幫助提出正確的查詢嗎?提前致謝!

+0

什麼END_DATE? – Strawberry

+1

爲什麼MySQL標籤? – Strawberry

+0

我摘下了mysql標籤。我需要在google-bigquery中編寫它。 end_date與start_date的工作方式相同,所以如果有任何活動,那麼我們不會在那一天計算它 –

回答

1

下面是BigQuery的標準SQL

它假定起始日期日期和結束日期是DATE類型的
它還假定在start_date和end_date之間的所有天是「專用」,以站start_station_name領域,其中最有可能不是預期的,但問題是這裏缺少這樣的細節,例如假設

#standardSQL 
WITH days AS (
    SELECT day 
    FROM UNNEST(GENERATE_DATE_ARRAY('2015-01-01', '2015-12-31')) AS day 
), 
stations AS (
    SELECT DISTINCT start_station_name AS station 
    FROM `trips_table` 
) 
SELECT s.* 
FROM (SELECT * FROM stations CROSS JOIN days) AS s 
LEFT JOIN (SELECT * FROM `trips_table`, 
      UNNEST(GENERATE_DATE_ARRAY(start_date, end_date)) AS day) AS a 
ON s.day = a.day AND s.station = a.start_station_name 
WHERE a.day IS NULL 

您可以測試/ PL下面簡單/虛擬數據

唉它
#standardSQL 
WITH `trips_table` AS (
    SELECT 1 AS trip_id, DATE '2015-01-01' AS start_date, DATE '2015-12-01' AS end_date, '111' AS start_station_name UNION ALL 
    SELECT 2, DATE '2015-12-10', DATE '2015-12-31', '111' 
), 
days AS (
    SELECT day 
    FROM UNNEST(GENERATE_DATE_ARRAY('2015-01-01', '2015-12-31')) AS day 
), 
stations AS (
    SELECT DISTINCT start_station_name AS station 
    FROM `trips_table` 
) 
SELECT s.* 
FROM (SELECT * FROM stations CROSS JOIN days) AS s 
LEFT JOIN (SELECT * FROM `trips_table`, 
      UNNEST(GENERATE_DATE_ARRAY(start_date, end_date)) AS day) AS a 
ON s.day = a.day AND s.station = a.start_station_name 
WHERE a.day IS NULL 
ORDER BY station, day 

,輸出類似下面

station day 
111  2015-12-02 
111  2015-12-03 
111  2015-12-04 
111  2015-12-05 
111  2015-12-06 
111  2015-12-07 
111  2015-12-08 
111  2015-12-09 
0

爲此,使用遞歸:嘗試這個SQL SERVER

WITH sample AS (
    SELECT CAST('2015-01-01' AS DATETIME) AS dt 
    UNION ALL 
    SELECT DATEADD(dd, 1, dt) 
    FROM sample s 
    WHERE DATEADD(dd, 1, dt) < CAST('2016-01-01' AS DATETIME) 
) 
SELECT * FROM sample 
Where CAST(sample.dt as date) NOT IN (
    SELECT CAST(start_date as date) 
    FROM tablename 
    WHERE start_date >= '2015-01-01 00:00:00' 
    AND start_date < '2016-01-01 00:00:00' 
) 
Option(maxrecursion 0) 

如果你想用它測站數據,那麼你可以使用左連接爲:

WITH sample AS (
    SELECT CAST('2015-01-01' AS DATETIME) AS dt 
    UNION ALL 
    SELECT DATEADD(dd, 1, dt) 
    FROM sample s 
    WHERE DATEADD(dd, 1, dt) < CAST('2016-01-01' AS DATETIME) 
) 
SELECT * FROM sample 
left join tablename 
on CAST(sample.dt as date) = CAST(tablename.start_date as date) 
where sample.dt>= '2015-01-01 00:00:00' and sample.dt< '2016-01-01 00:00:00') 
Option(maxrecursion 0) 

對於MySQL,看到這個小提琴。我認爲這會幫助你.... SQL Fiddle Demo

+0

我不認爲google bigquery支持這種語法。 – trincot

+0

對不起,這是我的錯,我不應該把mysql放在標籤中。 –

相關問題