2017-04-01 10 views
0

한다고 가정 보조 테이블로 표시 간격 이상 합계 나는 두 개의 테이블이 있습니다 intervals은 (는 열 i_mini_max 있습니다) 인덱스 간격을 포함하고 values은 (열 ix와) 인덱스 값이 포함되어 있습니다. 나는 각 간격에 대한 x의 값을 합계를BigQuery에/SQL :

values:  intervals: 
+---+---+ +-------+-------+ 
| i | x | | i_min | i_max | 
+-------+ +---------------+ 
| 1 | 1 | | 1 | 4 | 
| 2 | 0 | | 6 | 6 | 
| 3 | 4 | | 6 | 6 | 
| 4 | 9 | | 6 | 6 | 
| 6 | 7 | | 7 | 9 | 
| 7 | 2 | | 12 | 17 | 
| 8 | 2 | +-------+-------+ 
| 9 | 2 | 
+---+---+ 

: 예를 들면 다음과 같습니다의 것을 제외

SELECT 
    i_min, 
    i_max, 
    (SELECT SUM(x) 
    FROM values 
    WHERE i BETWEEN intervals.i_min AND intervals.i_max) AS sum_x 
FROM 
    intervals 

: 일부 SQL 엔진에서

 result: 
+-------+-------+-----+ 
| i_min | i_max | sum | 
+---------------------+ 
| 1 | 4 | 13 | // 1+0+4+9 
| 6 | 6 | 7 | 
| 6 | 6 | 7 | 
| 6 | 6 | 7 | 
| 7 | 9 | 6 | // 2+2+2 
| 12 | 17 | 0 | 
+-------+-------+-----+ 

을, 이것은 사용하여 수행 할 수있다 BigQuery는 쿼리 유형을 허용하지 않습니다 ("SELECT 절에는 Subselect가 허용되지 않습니다"또는 "LEFT OUTER JOIN은 조인의 양쪽에서 필드가 같은 조건없이 사용할 수 없습니다."). x 사용).

윈도우 함수에서이 작업을 수행하는 방법이 있어야하지만, 필자는 모든 예제에서 파티션을 테이블의 일부로 보았습니다. CROSS JOIN을 사용하지 않는 옵션이 있습니까? 그렇지 않은 경우이 교차 결합을 수행하는 가장 효율적인 방법은 무엇입니까? 내 데이터에

일부 노트 :

  • 두 테이블이 많은 (10⁸-10⁹) 행을 포함합니다.
  • i이 아닌 intervals에 반복이있을 수 있습니다.
  • intervals에있는 두 개의 간격은 모두 동일하거나 완전히 겹치지 않습니다 (중복 없음).
  • 모든 간격의 합집합은 일반적으로 i의 모든 값 집합에 가깝습니다 (따라서이 간격의 파티션을 형성합니다).
  • 간격이 클 수 있습니다 (예 : i_max-i_min < 106).
+1

다음과 같이 더미 데이터/테스트를 재생할 수 있습니다 귀하의 질문을 수정 및 샘플 데이터와 원하는 결과를 알려주십시오. 또한 간격이 겹치고, 작고, 드문 드문 있는지 설명하십시오. . . 이는 솔루션에 영향을 미칠 수 있습니다. –

+0

검색어에 이러한 종류의 기능을 사용하려면 [표준 SQL 사용] (https://cloud.google.com/bigquery/docs/reference/standard-sql/)을 확인하십시오. [이전 가이드] (https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql)도 참조하십시오. –

+0

@GordonLinoff 좋은 지적입니다. – Ted

답변

3

아래 시도 - BigQuery에 표준 SQL

#standardSQL 
SELECT 
    i_min, i_max, SUM(x) AS sum_x 
FROM (
    SELECT i_min, i_max, ROW_NUMBER() OVER() AS line FROM `project.dataset.intervals` 
) AS intervals 
JOIN (SELECT i, x FROM `project.dataset.values` UNION ALL SELECT NULL, 0) AS values 
ON values.i BETWEEN intervals.i_min AND intervals.i_max OR values.i IS NULL 
GROUP BY i_min, i_max, line 
-- ORDER BY i_min 

당신이

#standardSQL 
WITH intervals AS (
    SELECT 1 AS i_min, 4 AS i_max UNION ALL 
    SELECT 6, 6 UNION ALL 
    SELECT 6, 6 UNION ALL 
    SELECT 6, 6 UNION ALL 
    SELECT 7, 9 UNION ALL 
    SELECT 12, 17 
), 
values AS (
    SELECT 1 AS i, 1 AS x UNION ALL 
    SELECT 2, 0 UNION ALL 
    SELECT 3, 4 UNION ALL 
    SELECT 4, 9 UNION ALL 
    SELECT 6, 7 UNION ALL 
    SELECT 7, 2 UNION ALL 
    SELECT 8, 2 UNION ALL 
    SELECT 9, 2 
) 
SELECT 
    i_min, i_max, SUM(x) AS sum_x 
FROM (SELECT i_min, i_max, ROW_NUMBER() OVER() AS line FROM intervals) AS intervals 
JOIN (SELECT i, x FROM values UNION ALL SELECT NULL, 0) AS values 
ON values.i BETWEEN intervals.i_min AND intervals.i_max OR values.i IS NULL 
GROUP BY i_min, i_max, line 
-- ORDER BY i_min 
+0

다시 한번 감사드립니다. 호기심에서 레거시 SQL로이를 수행 할 수 있습니까? – Ted

+0

레거시 SQL의 ON 절에 대한 제한 때문에 표준 SQL에서 일대일로 변환 할 수는 있지만 수행 할 수는 없습니다. 그러나 할 수있다. –