2017-11-29 6 views
2

フルネームの学生情報テーブルとファーストネームのリストがあります。Bigquery SQL SELECT WHEREフィールドには他のテーブルからの多くの単語が含まれています

full_names    first_names 
---------------   ------------- 
john adam smith   john 
jane anna doe   jane 
michael brown   bob 

私は、そのフルネーム最初の名前の長いリストのいずれかを含む学生を選択します。たとえば、John Adam Smithには単語johnが含まれています。その行を選択します。 Michael Brownは名前と一致しないので、私はそれを望んでいません。

私はこれを行うことができましたが、それはクレイジー非効率 300 +の名前を入力しています。第二のテーブルfirst_namesに名前のリストを作った、第二にあった最初のテーブルから名前を選択しようとした - 私はを試してみた何

SELECT names 
FROM full_names 
WHERE names CONTAIN 'john' 
    OR names CONTAIN 'jane' 
    OR names CONTAIN 'bob' 
... 
(300 more rows) 

SELECT names 
FROM full_names 
WHERE names CONTAINS 
    (SELECT names 
    FROM first_names); 

はしかし、私はエラーを取得する:

Error: ELEMENT can only be applied to result with 0 or 1 row.

は、より良い方法はありますか?

答えて

2

の列に基づいているためであるBigQueryの標準SQL

#standardSQL 
SELECT full_name 
FROM `project.dataset.full_names` a 
CROSS JOIN `project.dataset.first_names` b 
GROUP BY full_name 
HAVING MAX(REGEXP_CONTAINS(full_name, name)) 
あなたが/テスト使用して、上記で遊ぶことができます

あなたの質問からのダミーデータを以下に示します。

#standardSQL 
WITH `full_names` AS (
    SELECT 'john adam smith' full_name UNION ALL 
    SELECT 'jane anna doe' UNION ALL 
    SELECT 'michael brown' 
), `first_names` AS (
    SELECT 'john' name UNION ALL 
    SELECT 'jane' UNION ALL 
    SELECT 'bob' 
) 
SELECT full_name 
FROM `full_names` a 
CROSS JOIN `first_names` b 
GROUP BY full_name 
HAVING MAX(REGEXP_CONTAINS(full_name, name)) 

結果は

full_name  
--------- 
john adam smith 
jane anna doe  

More options:

#standardSQL 
SELECT DISTINCT full_name 
FROM `project.dataset.full_names` a 
JOIN `project.dataset.first_names` b 
ON full_name LIKE CONCAT('%', name, '%') 

OR

SELECT DISTINCT full_name 
FROM `project.dataset.full_names`, UNNEST(SPLIT(full_name, ' ')) part 
JOIN `project.dataset.first_names` 
ON part = name 
+0

ありがとうミハイル!サンプルは正常に動作し、徹底した説明に感謝します。残念ながら、私は支払い階層を最初にアップグレードしなければならないので、私の完全なデータセット上で実行することはできません。それほど問題がなければ、このクエリを小さくする方法はありますか?もう一度、あなたの助けに感謝します! –

+0

あなたはどんな問題がありますか?エラーメッセージ?どうか明らかにしてください。請求は、クエリに含まれるデータの量によって異なります。したがって、コストを最小限に抑えるために使用する列のみを使用する必要があります。 –

+0

「エラー:クエリが第1層のリソース制限を超えました。私は300人の名字と2700万のフルネームを持っています。BQフリー層にまだ300ドルのクレジットが残っているので、なぜこのクエリが進まないのか分かりません。編集:はい、私はコストを最小限に抑える必要がある列を使用しています。 –

0

これを試してみてください:

SELECT names 
FROM 
full_names a 
inner join 
first_names b 
on a.names like CONCAT('%', b.names, '%') ; 

は私が任意のクエリの場合に知らせてください。

+0

おかげであるが、これは私に、 "ジョン" のような行を与えるが、 "ジョンのアダム・スミス" のような行を残します。また、ターゲットと完全に一致するものだけでなく、ターゲットと部分的に一致する行を含めることもできます。 –

+0

@angsty_robotしよう! –

0

テストされていないが、これを試してみてください:列名は、スナップショットの下

Select * from full_names 
    where first_names IN 
    (Select full_names from full_names) 
関連する問題