如何统计两个有共同字段的表,但有时其中一个没有匹配的记录

问题描述 投票:0回答:1

让我解释一下我想要实现的目标(我使用 Bigquery):

我有两个表,一个称为 requests,另一个称为 incidents,在请求表中,有应用程序的记录,保存每个请求及其状态代码 200、500、404 等。在事件表中,有还有每个应用程序的事件记录。

我需要制作一个包含每个应用程序名称的报告,然后统计 200 个请求的数量,统计非 200 个请求的数量,最后统计每个应用程序的事件数量。

我设法进行了一个有效的查询,但有一种“罕见”的情况,即应用程序可能会发生事件,但请求表中没有记录(没有 200 个请求,没有 500 个请求,什么都没有),所以在这种情况下我的查询不会返回事件计数,因为它无法在同一应用程序的请求表中找到记录。我需要帮助才能仍然显示特定的应用程序名称,请求计数为 0 且事件计数正确,但无法实现这一点,这是我的查询:

SELECT
  directoryName AS directoryProviderId, -- this is the app name
  COUNTIF(operationStatus = 200) AS successfulOps,
  COUNTIF(operationStatus <> 200) AS failedOps,
  (
    SELECT
      COUNT(*) AS incidentCount
    FROM
      `incidents` i
    WHERE
      r.directoryName=i.directoryProviderId
      -- Only get incidents from yesterday (starts from yesterday at 00:00 until yesterday at 23:59 Lima time)
      AND DATETIME(TIMESTAMP_MILLIS(i.timestamp), "America/Lima") >= DATE_SUB(CURRENT_DATE('America/Lima'), INTERVAL 1 DAY)
      AND DATETIME(TIMESTAMP_MILLIS(i.timestamp), "America/Lima") < CURRENT_DATE('America/Lima')
  ) AS incidents
FROM
  `requests` AS r
WHERE
  -- Only get requests from yesterday (starts from yesterday at 00:00 until yesterday at 23:59 Lima time)
  DATETIME(TIMESTAMP_MILLIS(r.timestamp), "America/Lima") >= DATE_SUB(CURRENT_DATE('America/Lima'), INTERVAL 1 DAY)
  AND DATETIME(TIMESTAMP_MILLIS(r.timestamp), "America/Lima") < CURRENT_DATE('America/Lima')
GROUP BY
  directoryName

requests 表具有以下列: requestId(字符串),操作状态(整数),时间戳(整数),目录名称(字符串)

事件表具有以下列: eventId(字符串)、directoryProviderId(字符串)、时间戳(整数)

sql google-bigquery
1个回答
0
投票

您可以分别对请求和事件表的事件进行计数。然后加入并取非空值。

参见示例。
测试数据

with requests as 
   (select 'request1' requestId,200 operationStatus
        ,unix_millis(timestamp(cast('2024-04-30 01:00:00' as datetime),'America/Lima'))timestamp
       ,'App1' directoryName
    union all
    select 'request1' requestId,200 operationStatus
        ,unix_millis(timestamp(cast('2024-04-30 02:00:00' as datetime),'America/Lima'))timestamp
        ,'App2' directoryName
   )
,incidents 
   as(
      select 'fail1'incidentId,'App1' directoryProviderId
     ,unix_millis(timestamp(cast('2024-04-30 01:00:00' as datetime)
     ,'America/Lima'))timestamp
   union all
      select 'fail1'incidentId,'App3' directoryProviderId,unix_millis(timestamp(cast('2024-04-30 01:00:00' as datetime),'America/Lima'))timestamp
   )

查询

   select coalesce(i.directoryProviderId,r.directoryProviderId)
     ,coalesce(r.successfulOps,0) as successfulOps
     ,coalesce(r.failedOps,0) as failedOps
     ,coalesce(i.incidentCount,0) as incidentCount
   from(
     SELECT
        directoryName AS directoryProviderId, -- this is the app name
        COUNTIF(operationStatus = 200) AS successfulOps,
        COUNTIF(operationStatus <> 200) AS failedOps,
     FROM `requests` AS r
   WHERE
  -- Only get requests from yesterday (starts from yesterday at 00:00 until yesterday at 23:59 Lima time)
        DATETIME(TIMESTAMP_MILLIS(r.timestamp), "America/Lima") >= DATE_SUB(CURRENT_DATE('America/Lima'), INTERVAL 1 DAY)
     AND DATETIME(TIMESTAMP_MILLIS(r.timestamp), "America/Lima") < CURRENT_DATE('America/Lima')
   GROUP BY   directoryName
   ) r
   full  join 
     (
    SELECT directoryProviderId,
      COUNT(*) AS incidentCount
    FROM `incidents` i
    WHERE
      -- Only get incidents from yesterday (starts from yesterday at 00:00 until yesterday at 23:59 Lima time)
      DATETIME(TIMESTAMP_MILLIS(i.timestamp), "America/Lima") >= DATE_SUB(CURRENT_DATE('America/Lima'), INTERVAL 1 DAY)
      AND DATETIME(TIMESTAMP_MILLIS(i.timestamp), "America/Lima") < CURRENT_DATE('America/Lima')
    group by directoryProviderId
  ) AS i
  on i.directoryProviderId= r.directoryProviderId
© www.soinside.com 2019 - 2024. All rights reserved.