BigQuery Return 加入的单个记录值 Table

BigQuery Return Single Record Value(s) from Joined Table

我正在尝试 return 加入(相关)table 中最新记录中的一个字段。我可能使用嵌套的 select 语句完成了此操作,但 BigQuery 不支持该语句。

Table 1: tblIncidents
- incidentId
- incidentName
- clientName
- incidentDescription
- incidentDate
Table 2: tblActivity
- activityId
- incidentId
- activityDate
- activityStatus

给定事件的 tblActivity 中可能有 0 到 n 条记录。

我将展示几个基于 incidentDate 的事件。

此外,如果没有 activity 记录,该字段可以为空,或者我可以设置一个字符串值“no activity”。

我知道这行不通,但在 MS SQL 服务器中会出现类似的情况。我不确定在 BigQuery 中执行此操作的最佳方法。

Select I.incidentId, I.incidentDate, I.clientName, I.incidentName, 
(Select A.activityStatus FROM tblActivity A 
Where A.incidentId = I.incidentId as activityStatus ORDER BY A.activityDate DESC limit 1) as activityStatus,
incidentDescription 
FROM tblIncidents I WHERE clientName = 'a given client name'

提前感谢您对这个方向的任何见解。

有几种方法,但我的第一种方法是使用分析函数 LAST_VALUE() 和适当的 window:

SELECT DISTINCT
    tblIncidents.incidentId
    ,tblIncidents.incidentDate
    ,tblIncidents.clientName
    ,tblIncidents.incidentName

    # partition by incidentID, order by date asc, grab the last value
    # (equivalently, order by date desc, grab the first value)
    ,LAST_VALUE(tblActivity.activityStatus) OVER(partition by tblActivity.incidentId ORDER BY activityDate ASC) as latestActivityStatus
    ,incidentDescription 
FROM tblIncidents
JOIN tblActivity USING(incidentId)
WHERE clientName = 'client1'

正如 MatBailie 在评论中强调的那样,还需要一个 DISTINCT 来避免 JOIN 返回重复项。

如果您不喜欢 DISTINCT,可以像您第一次提到的那样使用子查询并使用 WHERE 子句对其进行过滤。我没有为此使用 JOIN。

Select 
    tblIncidents.incidentId
    ,tblIncidents.incidentDate
    ,tblIncidents.clientName
    ,tblIncidents.incidentName

    # subquery        
    ,(SELECT tblActivity.activityStatus FROM tblActivity 
        WHERE tblActivity.incidentId = tblIncidents.incidentId
        ORDER BY activityDate DESC 
        LIMIT 1
     ) as latestActivityStatus

    ,tblIncidents.incidentDescription 
FROM tblIncidents
WHERE clientName = 'client1'

在这两种情况下,我都在我的查询中定义了 CTE(此处未显示),使用 WITH 称为“tblIncidents”和“tblActivity”。

这两种方法对您有帮助吗?

您可以使用这种方法,它可以避免 DISTINCT 在分析查询结果之上:

with activityMax as (
    select * from (
       select 
          incidentId, 
          activityId, 
          activityStatus,
          row_number() over (partition by incidentId order by activityDate desc) as activity_rnk 
       from tblActivity
    ) where activity_rnk = 1
)

select 
   I.incidentId, 
   I.incidentDate, 
   I.clientName, 
   I.incidentName, 
   A.activityId, 
   coalesce(A.activityStatus, "NO ACTIVITY") as activityStatus
from tblIncidents I
left join activityMax A on I.incidentId = A.incidentId