Как я могу получить дополнение в этом SQL-запросе?

#sql #google-bigquery

#sql #google-bigquery

Вопрос:

У меня есть база данных bigquery, которая имеет некоторую широту и долготу. Над этой базой данных я запускаю запрос, используя CTE и функцию ST_COVERS bigquery. Общий подмножество составляет 518 строк, а точки, которые применяются к цепочке CTE, равны 423. Как я могу получить оставшиеся строки? Я пытался объединить, объединить все, левое соединение, внутреннее соединение и другие вещи, но я не могу получить всего 518 строк.

PD: я не отправляю запрос, потому что он довольно длинный (вероятно, его можно сильно оптимизировать), но я могу опубликовать его, если это действительно необходимо.

РЕДАКТИРОВАТЬ: это запрос (или наиболее важные его части). С помощью этого запроса я могу получить все lat,lon точки, которые находятся в пределах некоторых полигонов. То, что я ищу, — это также получить lat,lon точки, которые находятся за пределами всех полигонов, и присвоить им тег «NA» в sector столбце.

 WITH staging AS(
  SELECT id,
         lat,
         lon
  FROM
       lat_lon_table),

 area_1 AS(
 SELECT id,
        lat,
        lon,
        "area_1" AS sector,
        ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#some lat lon coordinates))"),
        ST_GEOPOINT(lat,lon)) as `covers`
 FROM
     staging),

 area_2 AS(
 SELECT id,
        lat,
        lon,
        "area_2" AS sector,
        ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"),
        ST_GEOPOINT(lat,lon)) as `covers`
 FROM
     staging),

 area_3 AS(
 SELECT id,
        lat,
        lon,
        "area_3" AS sector,
        ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"),
        ST_GEOPOINT(lat,lon)) as `covers`
 FROM
     staging),

 area_4 AS(
 SELECT id,
        lat,
        lon,
        "area_4" AS sector,
        ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"),
        ST_GEOPOINT(lat,lon)) as `covers`
 FROM
     staging),

 union_all AS(
 SELECT * FROM area_1
 UNION ALL(SELECT * FROM area_2)
 UNION ALL(SELECT * FROM area_3)
 UNION ALL(SELECT * FROM area_4))

 SELECT 
     id,
     lat,
     lon,
     sector
 FROM
     union_all
 WHERE
     covers = TRUE
  

Комментарии:

1. Не публикуйте весь запрос целиком — только его существенную часть и уточните, каков ожидаемый результат

2. ОК… Я постараюсь сделать все возможное

Ответ №1:

Попробуйте ниже

 #standardSQL
WITH staging AS(
  SELECT id, lat, lon FROM lat_lon_table
), area_1 AS(
  SELECT id, lat, lon, "area_1" AS sector,
    ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#some lat lon coordinates))"), ST_GEOGPOINT(lat,lon)) as `covers`
  FROM staging
), area_2 AS (
  SELECT id, lat, lon, "area_2" AS sector,
    ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)) as `covers`
  FROM staging
), area_3 AS (
  SELECT id, lat, lon, "area_3" AS sector,
    ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)) as `covers`
  FROM staging
), area_4 AS (
  SELECT id, lat, lon, "area_4" AS sector,
    ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)) as `covers`
  FROM staging
), union_all AS (
  SELECT * FROM area_1 UNION ALL
  SELECT * FROM area_2 UNION ALL
  SELECT * FROM area_3 UNION ALL
  SELECT * FROM area_4
)
SELECT id, lat, lon, sector FROM union_all 
WHERE covers = TRUE
UNION ALL
SELECT id, lat, lon, 'NA' FROM lat_lon_table 
WHERE NOT id IN (SELECT DISTINCT id FROM union_all WHERE covers = TRUE)
  

Комментарии:

1. Большое вам спасибо, @Михаил Берлянт! Это сработало :). Есть предложения о том, как я могу улучшить запрос?

2. когда я ответил — я думаю, я что-то имел в виду, но я сосредоточился на точном вопросе и не хотел ничего менять в вашем первоначальном запросе. ОК. Я скоро проверю, и если у вас есть какие-то идеи, опубликую их как отдельный ответ

Ответ №2:

Есть предложения о том, как я могу улучшить запрос?

Попробуйте ниже — он менее подробный, простой в обслуживании и должен быть дешевле и быстрее (не тестировался)

 #standardSQL
WITH staging AS(
  SELECT id, lat, lon FROM lat_lon_table
), areas AS(
  SELECT id, lat, lon, 
    IF(ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#some  lat lon coordinates))"), ST_GEOGPOINT(lat,lon)), 'area_1', 'NA') AS area_1, 
    IF(ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)), 'area 2', 'NA') AS area_2,
    IF(ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)), 'area_3', 'NA') AS area_3,
    IF(ST_COVERS(ST_GEOGFROMTEXT("POLYGON((#other lat lon coordinates))"), ST_GEOGPOINT(lat,lon)), 'area_4', 'NA') AS area_4
  FROM staging
), union_all AS (
  SELECT id, lat, lon, 'area_1' AS sector FROM areas WHERE area_1 = 'area_1' UNION ALL
  SELECT id, lat, lon, 'area_2' FROM areas WHERE area_2 = 'area_2' UNION ALL
  SELECT id, lat, lon, 'area_3' FROM areas WHERE area_3 = 'area_3' UNION ALL
  SELECT id, lat, lon, 'area_4' FROM areas WHERE area_4 = 'area_4' UNION ALL
  SELECT id, lat, lon, 'NA' FROM areas WHERE (area_1, area_2, area_3, area_4) = ('NA', 'NA', 'NA', 'NA') 
)
SELECT * FROM union_all