2017-08-21 7 views
0

であるのは、同じクエリで{id、date}あたりの行数と{id、date、columnX}あたりの合計数を取得する方法はありますか?このようなテーブルを持つ例えば同じクエリで合計とカウントの合計が

、:

id   date   columnX 
1  2017-04-20   a 
1  2017-04-20   a 
1  2017-04-18   b 
1  2017-04-17   c 
2  2017-04-20   a 
2  2017-04-20   a 
2  2017-04-20   c 
2  2017-04-19   b 
2  2017-04-19   b 
2  2017-04-19   b 
2  2017-04-19   b 
2  2017-04-19   c 

結果として、私は次の表を取得したい:

id   date  columnX   count>1 count_total 
1  2017-04-20  a    2   2 
2  2017-04-20  a    2   3 
2  2017-04-19  b    4   5 

私は、パーティションでそれを行うが、奇妙な結果を受け取ることを試みました。私は、ロールアップ機能が使用されるかもしれないと聞いてきましたが、それは私のためのオプションではないレガシーSQLにのみ適用されるようです。

答えて

2

私が正しく理解していれば、あなたはウィンドウ関数を使用することができますが:

select id, date, columnx, cnt, 
     (case when cnt > 1 then cnt else 0 end) as cnt_gt_1, 
     total_cnt 
from (select id, date, columnx, count(*) as cnt 
      sum(count(*)) over (partition by id, date) as total_cnt 
     from t 
     group by id, date, columnx 
    ) x 
where cnt > 1; 
+0

ありがとうございました!問題を解決します。しかし、あなたのクエリの 'where cnt> 1'はTotalからそれらを削除していたので、別のクエリ(select * from cnt> 1)を追加する必要がありました。 – hamsy

1

別の可能性:

SELECT 
    id, 
    date, 
    data.columnX columnX, 
    data.count_ count_bigger_1, 
    count_total 
FROM(
    SELECT 
    id, 
    date, 
    ARRAY_AGG(columnX) data, 
    COUNT(1) count_total 
    FROM 
    `your_table_name` 
    GROUP BY 
    id, date 
), 
UNNEST(ARRAY(SELECT AS STRUCT columnX, count(1) count_ FROM UNNEST(data) columnX GROUP BY columnX HAVING count(1) > 1)) data 

あなたは、シミュレートされたデータを使ってテストすることができます。

WITH data AS(
    SELECT 1 AS id, '2017-04-20' AS date, 'a' AS columnX UNION ALL 
    SELECT 1 AS id, '2017-04-20' AS date, 'a' AS columnX UNION ALL 
    SELECT 1 AS id, '2017-04-18' AS date, 'b' AS columnX UNION ALL 
    SELECT 1 AS id, '2017-04-17' AS date, 'c' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-20' AS date, 'a' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-20' AS date, 'a' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-20' AS date, 'c' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-19' AS date, 'b' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-19' AS date, 'b' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-19' AS date, 'b' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-19' AS date, 'b' AS columnX UNION ALL 
    SELECT 2 AS id, '2017-04-19' AS date, 'c' AS columnX 
) 

SELECT 
    id, 
    date, 
    data.columnX columnX, 
    data.count_ count_bigger_1, 
    count_total 
FROM(
    SELECT 
    id, 
    date, 
    ARRAY_AGG(columnX) data, 
    COUNT(1) count_total 
    FROM 
    data 
    GROUP BY 
    id, date 
), 
UNNEST(ARRAY(SELECT AS STRUCT columnX, count(1) count_ FROM UNNEST(data) columnX GROUP BY columnX HAVING count(1) > 1)) data 

このソリューションでは、回避します分析関数(入力に応じてかなり高価になる可能性があります)と大容量データのume。

私はあなたがあなたの例に行

1  2017-04-20   x 
1  2017-04-20   x 

下の2つのより多くのを追加し、あなたを与える前の2つの答えでは何の解決策をチェックすることをお勧めします

1


それは以下のようになります:

id   date  columnX   count>1 count_total 
1  2017-04-20  a    2   4 
1  2017-04-20  x    2   4 
2  2017-04-20  a    2   3 
2  2017-04-19  b    4   5  

id = 1とdate = 2017-04-20の2つの行と、両方ともcount_total = 4を持つことに注意してください。
これがわからないかどうかわかりませんトン - あなたもとにかくあなたの質問

で、このシナリオとはみなされない場合でも、私は、出力のあなたの期待以上のようなより一般的なケースをサポートするためには

xが繰り返される
Row id date  x.columnX x.countX count_total 
1 1 2017-04-20 x   2   4  
        a   2   
2 2 2017-04-20 a   2   3  
3 2 2017-04-19 b   4   5  

以下のようにするの必要があることを感じますフィールドとそれぞれの値は、クエリ以下

が正確に行い、そのカウントはそれぞれのCOLUMNXを表し、あなたがそれをテストする/再生することができます

#standardSQL 
SELECT id, date, 
    ARRAY(SELECT x FROM UNNEST(x) AS x WHERE countX > 1) AS x, 
    count_total 
FROM (
    SELECT id, date, SUM(countX) AS count_total, 
    ARRAY_AGG(STRUCT<columnX STRING, countX INT64>(columnX, countX) ORDER BY countX DESC) AS X  
    FROM (
    SELECT id, date, 
     columnX, COUNT(1) countX 
    FROM `yourTable` 
    GROUP BY id, date, columnX 
) 
    GROUP BY id, date 
    HAVING count_total > 1 
) 

このダミーデータ

#standardSQL 
WITH `yourTable` AS(
    SELECT 1 AS id, '2017-04-20' AS date, 'a' AS columnX UNION ALL 
    SELECT 1, '2017-04-20', 'a' UNION ALL 
    SELECT 1, '2017-04-20', 'x' UNION ALL 
    SELECT 1, '2017-04-20', 'x' UNION ALL 
    SELECT 1, '2017-04-18', 'b' UNION ALL 
    SELECT 1, '2017-04-17', 'c' UNION ALL 
    SELECT 2, '2017-04-20', 'a' UNION ALL 
    SELECT 2, '2017-04-20', 'a' UNION ALL 
    SELECT 2, '2017-04-20', 'c' UNION ALL 
    SELECT 2, '2017-04-19', 'b' UNION ALL 
    SELECT 2, '2017-04-19', 'b' UNION ALL 
    SELECT 2, '2017-04-19', 'b' UNION ALL 
    SELECT 2, '2017-04-19', 'b' UNION ALL 
    SELECT 2, '2017-04-19', 'c' 
) 
SELECT id, date, 
    ARRAY(SELECT x FROM UNNEST(x) AS x WHERE countX > 1) AS x, 
    count_total 
FROM (
    SELECT id, date, SUM(countX) AS count_total, 
    ARRAY_AGG(STRUCT<columnX STRING, countX INT64>(columnX, countX) ORDER BY countX DESC) AS X  
    FROM (
    SELECT id, date, 
     columnX, COUNT(1) countX 
    FROM `yourTable` 
    GROUP BY id, date, columnX 
) 
    GROUP BY id, date 
    HAVING count_total > 1 
)