次のビュー「user_details_merged」を作成しました。
SELECT DISTINCT
coalesce(own.user_name, join_user_name.user_name) AS user_name,
coalesce(own.email, join_mail.email) AS email,
coalesce(own.first_name, join_name.first_name) AS first_name,
coalesce(own.last_name, join_name.last_name) AS last_name
FROM
user_details AS own
LEFT JOIN user_details AS join_user_name ON
own.user_name IS NULL AND (
(join_user_name.email = own.email AND own.email IS NOT NULL)
OR (join_user_name.first_name = own.first_name AND join_user_name.last_name = own.last_name
AND own.first_name IS NOT NULL AND own.last_name IS NOT NULL))
LEFT JOIN user_details AS join_mail ON
own.email IS NULL AND (
(join_mail.user_name = own.user_name AND own.user_name IS NOT NULL)
OR (join_mail.first_name = own.first_name AND join_mail.last_name = own.last_name
AND own.first_name IS NOT NULL AND own.last_name IS NOT NULL))
LEFT JOIN user_details AS join_name ON
own.first_name IS NULL AND own.last_name IS NULL AND (
(join_name.email = own.email AND own.email IS NOT NULL)
OR (join_name.user_name = own.user_name AND own.user_name IS NOT NULL))
ORDER BY user_name ASC,email ASC, first_name ASC, last_name ASC
これにより、次の列がマージされます。
user_name | email | first_name | last_name
a b NULL NULL
NULL b c d
a NULL e f
NULL x y z
に
user_name | email | first_name | last_name
a b NULL NULL
NULL b c d
a NULL e f
NULL x y z
a b c d
a b e f
私が欲しいのは:
user_name | email | first_name | last_name
NULL x y z
a b c d
a b e f
より多くの情報を持つ同じデータを持つ行がある場合、ROWSを含むNULLはありませんが、より多くの情報を持つ他の行がない場合は、/ NULLxyz/を保持します。
ここでのこの2番目のビューは、私が必要としていることを正確に実行します。
SELECT DISTINCT a.user_name,a.email,a.first_name,a.last_name FROM
user_details_merged a
LEFT JOIN user_details_merged b
ON
(
(
a.user_name IS NOT NULL OR
NOT EXISTS (SELECT user_name FROM user_details_merged b WHERE b.user_name IS NOT NULL AND
b.email=ISNULL(a.email,b.email) AND
b.first_name=isnull(a.first_name,b.first_name) AND
b.last_name=isnull(a.last_name,b.last_name))
)
AND
(
a.email IS NOT NULL OR
NOT EXISTS (SELECT email FROM user_details_merged b WHERE b.email IS NOT NULL AND
b.user_name=ISNULL(a.user_name,b.user_name) AND
b.first_name=isnull(a.first_name,b.first_name) AND
b.last_name=isnull(a.last_name,b.last_name))
)
AND
(
(a.first_name IS NOT NULL AND a.last_name IS NOT NULL) OR
NOT EXISTS (SELECT email FROM user_details_merged b WHERE b.email IS NOT NULL AND
b.user_name=ISNULL(a.user_name,b.user_name) AND
b.email=ISNULL(a.email,b.email))
-- AND b.first_name=isnull(a.first_name,b.first_name) AND b.last_name=isnull(a.last_name,b.last_name))
)
AND NOT (a.first_name = b.first_name AND a.last_name = b.last_name AND a.email = b.email AND a.user_name = b.user_name)
)
WHERE coalesce(b.user_name,b.email,b.first_name,b.last_name) IS NOT NULL
主な問題は、データの取得元であるuser_detailsビューが、さまざまなテーブルの多くの和集合で構成されていることです。ユーザー名と電子メールのみを含むものと、電子メールと名/姓などのみを含むものがあります。そのため、一意のキーがなく、UNIONSのためにビューのインデックスを作成できません。そのため、1時間以内に最後のビューを実行することは不可能です。現在の回避策は、user_details_mergedビューのデータを一時テーブルに格納し、上記の2番目のビューでこのテーブルのデータを使用できるようにするプロシージャです。そうすれば、8000行の実行時間を7秒に短縮できます。
他に何か提案はありますか?
どうもありがとうございます ;)