使用Big Query中两个来源的数据-计划的报告数据和实时数据来创建Google Data Studio GPS报告

时间:2019-02-12 16:22:53

标签: sql google-bigquery google-data-studio

我想在这篇文章前加上前缀,说我是SQL新手,是BigQuery的新手,也是第一次发贴,所以在此先感谢!

我目前正在Google Data Studio中重新创建一个报表,该报表最初是为公交公司在Excel中构建的,它将每日的时间表与我们每天从第三方软件收到的数据进行比较。 “计划”数据表包括路线名称,位置名称,计划时间和GPS坐标。我们从第三方软件收到的“实时”数据包括:日期,每40秒的时间戳以及该时间戳的GPS坐标。请注意,没有“路线名称”,这是稍后我的问题的关键。

第三方CSV数据每天作为单独的CSV文件上传到Google Cloud Data Storage存储桶,该存储桶又作为一个单一的实时数据表与Google BigQuery连接,可以与Schedule数据进行比较桌子。

此报告的目的是能够将上载的实时数据表与计划数据进行比较,以创建Google Data Studio报告,我们的物流团队可以检查该报告以回答以下两个主要问题:1)守时公共汽车-当天的时间准时,如果晚了,要多少钱。 2)公交车的位置-每个时间戳相对于计划的GPS坐标的公交车的确切GPS位置在哪里。我理想的报告应该具有过滤器,以选择不同的公交路线并选择有问题的日期。

我的第一个查询在于如何构建此报告。我设想我将需要对我的数据执行一次连接,明确地说,两个LEFT联接将回答我的两个关键问题,如下所示:1)通过GPS坐标通过左联接进行守时性计算,以及2)通过左坐标进行守时性计算。通过时间戳加入。

如果该大纲很明确,并且我建议使用两个LEFT联接是正确的,出于以下讨论的原因,我怀疑可能不是这样,那么我们继续第二阶段。对于到现在为止已经读过并且认为我需要对自己的方法进行更改的任何人来说,这都是一个很好的检查点。

继续前进,何时以及如果我加入我的两个桌子,我最初观察到以下技术方面的考虑,我将需要一些帮助:

1)实时数据中的时间戳每40秒获取一次。因此,我不一定在确切的时间戳上有总线的数据,例如我的日程安排中的公交车本应位于09:00:00的x位置,但是,我的实时数据中最接近的时间戳可能是09:00:04。如何匹配该数据以选择正确的数据点。最初,我考虑过减少有效数字的数量,但是,然后我考虑了该实例,在本示例中将观察到该实例,在40秒后,我还将在09:00:44拥有一个数据点。如果有效数字减少了-09:00,将有两个匹配的数据点,它们将被视为相同。任何想法?也许和MIN左起。

2)要匹配的GPS坐标。我尝试使用ST_CLOSESTPOINT地理功能,但我不完全了解ST_CLOSESTPOINT(geography_1,geography_2 [,spheroid = FALSE])。 spheroid = FALSE是什么?(https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions)。

3)第三,也是我目前最棘手的问题,我的实时数据表已链接到Google数据存储桶,其中包含超过CSV文件的价值,适用于9条不同路线的公交车-每辆公交车每条CSV文件天。而且,如第2段所述,我的实时数据中没有“路线名称”,只是GPS坐标和时间戳上的一堆。我需要考虑一种方法,以便能够通过我的Schedule数据表在这些不同的CSV文件之间进行区分,以使其能够在Google Data Studio中使用前面提到的两个过滤器来工作,首先选择公交路线,然后选择日期。正是这一点使我怀疑LEFT联接是否合适,因为对于已联接的数据将无法实现此功能。当前,在具有大型实时数据集的情况下,与我的Schedule数据表的联接与该数据集的最接近的随机匹配,而无法按日等进行选择。

这是一个很大的项目,有点超出我的舒适范围,还有一个冗长的详细问题,但是任何指导都将不胜感激,因为我是SQL和BigQuery的新手。

非常感谢!

// JOIN 1 - via ST_CLOSESTPOINT to determine punctuality of the bus


SELECT
r1.Direction,
r1.ScheduledLocation,
r1.ScheduledNextLocation,
r1.ScheduledTime,
r1.ScheduledCoordinates,
r1.ScheduledXCoordinates,
r1.ScheduledYCoordinates,
r1.ScheduledFullCoordinates,
r2.RealTime,
r2.RealTimeDate,
r2.RealTimeXCoordinates,
r2.RealTimeYCoordinates,
r2.RealTimeFullCoordinates,

ST_CLOSESTPOINT(r1.ScheduledFullCoordinates, r2.RealTimeFullCoordinates) as ClosestPoint

FROM `SCHEDULE DATA SOURCE` r1

LEFT JOIN `REAL-TIME DATA SOURCE` r2 ON r1.ScheduledTime = r2.RealTime 



// JOIN 2 - via Timestamp to determine GPS location of the bus
SELECT  
r1.Direction,
r1.ScheduledLocation,
r1.ScheduledNextLocation,
r1.ScheduledTime,
r1.ScheduledCoordinates,
r1.ScheduledXCoordinates,
r1.ScheduledYCoordinates,
r1.ScheduledFullCoordinates,
r2.RealTime,
r2.RealTimeXCoordinates,
r2.RealTimeYCoordinates,
r2.RealTimeFullCoordinates

FROM `SCHEDULE DATA SOURCE` r1

LEFT JOIN `REAL-TIME DATA SOURCE` r2 ON r1.ScheduledTime = r2.RealTime

1 个答案:

答案 0 :(得分:0)

除了解析之外,您可以执行的其他操作是使用分析功能。我假设每个总线路线的数据都足够小。如果您在同一查询中有多条公交路线,请添加PARTITION BY。

我使用r1作为示例计划的时间/位置,并使用r2作为实时时间/位置。然后,我将它们合并并添加sched标志,表示这是计划的还是实时的。然后按时间排序所有事件,并为每个事件添加上一个和下一个位置。现在,您只能过滤预定的事件-您将为每个事件拥有下一个和上一个位置。我的代码有些简化,因为它可能选择上一个或下一个预定事件,而不是上一个或下一个实际事件。但是,如果经常收集真实事件,则不太可能发生。

最后,大约ST_CLOSESTPOINT-该函数用于查找一个复杂形状中最接近另一复杂形状的点。我认为在处理点时不需要它,因此它只返回单个可用点,即它的第一个参数。您需要的是ST_DISTANCE来计算到实点的距离。我计算了到上一个真实事件和到下一个真实事件的两个距离,然后选择一个更接近的距离。

with r1 as (
    select time(10, 0, 0) as sched_tm, ST_GeogPoint(10, 10) as sched_loc union all
    select time(10, 10, 0) as sched_tm, ST_GeogPoint(11, 11) as sched_loc union all
    select time(10, 20, 0) as sched_tm, ST_GeogPoint(12, 13) as sched_loc 
), r2 as (
    select time(10, 0, 10) as real_tm, ST_GeogPoint(10.1, 10) as real_loc union all
    select time(10, 0, 50) as real_tm, ST_GeogPoint(10.2, 10) as real_loc union all
    select time(10, 9, 40) as real_tm, ST_GeogPoint(10.9, 11) as real_loc union all
    select time(10, 10, 20) as real_tm, ST_GeogPoint(11.1, 11) as real_loc union all
    select time(10, 20, 0) as real_tm, ST_GeogPoint(12, 13) as real_loc 
), r12 as (
    select TRUE as sched, sched_tm tm, sched_loc as loc from r1 
    union all 
    select FALSE as sched, real_tm tm, real_loc as loc from r2
), r12_sort as (
    select sched, tm, loc, 
           LAG(loc, 1) OVER(ORDER BY tm) as prev_loc, 
           LEAD(loc, 1) OVER(ORDER BY tm) as next_loc 
    from r12 
)
select sched, tm as sched_tm, loc, prev_loc, next_loc, 
     LEAST(coalesce(st_distance(loc, prev_loc), 1e9),
           coalesce(st_distance(loc, next_loc), 1e9)) as distance
from r12_sort
where sched

结果是这样的:

Line sched  sched_tm  loc           prev_loc        next_loc         distance   
1    true   10:00:00  POINT(10 10)  null            POINT(10.1 10)   10950.579731746193
2    true   10:10:00  POINT(11 11)  POINT(10.9 11)  POINT(11.1 11)   10915.213347763152
3    true   10:20:00  POINT(12 13)  POINT(11.1 11)  POINT(12 13)     0.0