2017-12-08 29 views
1

ユーザーセッションはシステム上で追跡され、次の形式で格納されます。同じセッションIDに対して複数のレコードを取得することがあります。条件付き重複行の削除

Row session_id        user_actions  
1 8a88d75c-6385-4e36-8d10-e22ac4d976a3 118,139,141 
2 8a88d75c-6385-4e36-8d10-e22ac4d976a3 118,139,141,142,143,146 
3 e85731b6-4472-40fb-ab2b-33ebd1278ba9 211,114,117,118,141,142,143,146 
4 e85731b6-4472-40fb-ab2b-33ebd1278ba9 211,114,117 

私は一つだけ、各セッションIDのための複数のレコードのを維持するためにDISTINCT(session_idでSQLクエリを実行するために使用されます。しかし、一番下の行が同じセッションに対してより多くのアクションを記録していても、クエリがトップの行を選択することに気がつきました。だから次の表を見ると、私のクエリはRow 1を維持する& 3のようになります。

Row session_id        user_actions  
1 8a88d75c-6385-4e36-8d10-e22ac4d976a3 118,139,141 
3 e85731b6-4472-40fb-ab2b-33ebd1278ba9 211,114,117,118,141,142,143,146 

一方、私はこのように行2と3を保ちたいと思います。

Row session_id        user_actions  
2 8a88d75c-6385-4e36-8d10-e22ac4d976a3 118,139,141,142,143,146 
3 e85731b6-4472-40fb-ab2b-33ebd1278ba9 211,114,117,118,141,142,143,146 

SQLクエリで実行する必要はありますか?ありがとうございました!以下は

+0

DBの構造を教えてください。セッションIDを格納するテーブルと、具体的なセッションIDに関連付けられたアクションを格納するテーブルが2つあります。そうですか、違う構造ですか? – Vyacheslav

+0

@Vyacheslavこんにちは、私は2つの行を持つ1つのテーブルがあります。 session_idとuser_actions – Efe

答えて

2

は、あなたがテストすることができます/

#standardSQL 
WITH `project.dataset.table` AS (
    SELECT 1 row, '8a88d75c-6385-4e36-8d10-e22ac4d976a3' session_id, '118,139,141' user_actions UNION ALL 
    SELECT 2, '8a88d75c-6385-4e36-8d10-e22ac4d976a3', '118,139,141,142,143,146' UNION ALL 
    SELECT 3, 'e85731b6-4472-40fb-ab2b-33ebd1278ba9', '211,114,117,118,141,142,143,146' UNION ALL 
    SELECT 4, 'e85731b6-4472-40fb-ab2b-33ebd1278ba9', '211,114,117' 
) 
SELECT row, session_id, user_actions 
FROM (
    SELECT 
    row, session_id, user_actions, 
    ROW_NUMBER() OVER(PARTITION BY session_id 
     ORDER BY ARRAY_LENGTH(SPLIT(user_actions)) DESC 
    ) = 1 win 
    FROM `project.dataset.table` 
) 
WHERE win 
ORDER BY row 

結果が

で以下のようにあなたの質問からダミーデータを使用して、上記と遊ぶBigQueryの標準SQL

#standardSQL 
SELECT row, session_id, user_actions 
FROM (
    SELECT 
    row, session_id, user_actions, 
    ROW_NUMBER() OVER(PARTITION BY session_id 
     ORDER BY ARRAY_LENGTH(SPLIT(user_actions)) DESC 
    ) = 1 win 
    FROM `project.dataset.table` 
) 
WHERE win 

ためのオプションの一つであります

row session_id        user_actions  
2 8a88d75c-6385-4e36-8d10-e22ac4d976a3 118,139,141,142,143,146 
3 e85731b6-4472-40fb-ab2b-33ebd1278ba9 211,114,117,118,141,142,143,146 

もう1つのオプションは次のとおりです

#standardSQL 
WITH `project.dataset.table` AS (
    SELECT 1 row, '8a88d75c-6385-4e36-8d10-e22ac4d976a3' session_id, '118,139,141' user_actions UNION ALL 
    SELECT 2, '8a88d75c-6385-4e36-8d10-e22ac4d976a3', '118,139,141,142,143,146' UNION ALL 
    SELECT 3, 'e85731b6-4472-40fb-ab2b-33ebd1278ba9', '211,114,117,118,141,142,143,146' UNION ALL 
    SELECT 4, 'e85731b6-4472-40fb-ab2b-33ebd1278ba9', '211,114,117' 
) 
SELECT session_id, 
    ARRAY_AGG(user_actions ORDER BY ARRAY_LENGTH(SPLIT(user_actions)) DESC LIMIT 1)[SAFE_OFFSET(0)] user_actions 
FROM `project.dataset.table` 
GROUP BY session_id 

この1つは少しクリーンになりますO)()は、例えば、いくつかのアクションが一列に欠落している場合は、例えば、場合に重複除外エントリは異なるコードを組み合わせて上記で拡張することができ

はなく、別のそして、など)

更新:

パーティションに注文からarray_lengthを計算する費用を分離するために、次の試してみてください:

#standardSQL 
SELECT row, session_id, user_actions 
FROM (
    SELECT 
    row, session_id, user_actions, 
    ROW_NUMBER() OVER(PARTITION BY session_id ORDER BY len DESC) = 1 win 
    FROM (
    SELECT *, ARRAY_LENGTH(SPLIT(user_actions)) len 
    FROM `project.dataset.table` 
) 
) 
WHERE win 
+0

パーティション!あなたにミハイルありがとう! – Efe

+0

私はそれをテストし、このメッセージを受け取りました。「PARTITION BYに使用されたソート演算子が多すぎるメモリを使用しました。 – Efe

+0

私の答えで両方のバージョンでこのメッセージが表示されましたか? –

関連する問題