初期審査のあと後半の研究に進む双生児を決定するために、次のクエリーが使用されました。これは 1997 年ごろに MySQL 3.19 を使用して作成されました。
SELECT CONCAT(p1.id, p1.tvab) + 0 AS tvid, CONCAT(p1.christian_name, ' ', p1.surname) AS Name, p1.postal_code AS Code, p1.city AS City, pg.abrev AS Area, IF(td.participation = 'Aborted', 'A', ' ') AS A, p1.dead AS dead1, l.event AS event1, td.suspect AS tsuspect1, id.suspect AS isuspect1, td.severe AS tsevere1, id.severe AS isevere1, p2.dead AS dead2, l2.event AS event2, h2.nurse AS nurse2, h2.doctor AS doctor2, td2.suspect AS tsuspect2, id2.suspect AS isuspect2, td2.severe AS tsevere2, id2.severe AS isevere2, l.finish_date FROM twin_project AS tp /* For Twin 1 */ LEFT JOIN twin_data AS td ON tp.id = td.id AND tp.tvab = td.tvab LEFT JOIN informant_data AS id ON tp.id = id.id AND tp.tvab = id.tvab LEFT JOIN harmony AS h ON tp.id = h.id AND tp.tvab = h.tvab LEFT JOIN lentus AS l ON tp.id = l.id AND tp.tvab = l.tvab /* For Twin 2 */ LEFT JOIN twin_data AS td2 ON p2.id = td2.id AND p2.tvab = td2.tvab LEFT JOIN informant_data AS id2 ON p2.id = id2.id AND p2.tvab = id2.tvab LEFT JOIN harmony AS h2 ON p2.id = h2.id AND p2.tvab = h2.tvab LEFT JOIN lentus AS l2 ON p2.id = l2.id AND p2.tvab = l2.tvab, person_data AS p1, person_data AS p2, postal_groups AS pg WHERE /* p1 gets main twin and p2 gets his/her twin. */ /* ptvab is a field inverted from tvab */ p1.id = tp.id AND p1.tvab = tp.tvab AND p2.id = p1.id AND p2.ptvab = p1.tvab AND /* Just the screening survey */ tp.survey_no = 5 AND /* Skip if partner died before 65 but allow emigration (dead=9) */ (p2.dead = 0 OR p2.dead = 9 OR (p2.dead = 1 AND (p2.death_date = 0 OR (((TO_DAYS(p2.death_date) - TO_DAYS(p2.birthday)) / 365) >= 65)))) AND ( /* Twin is suspect */ (td.future_contact = 'Yes' AND td.suspect = 2) OR /* Twin is suspect - Informant is Blessed */ (td.future_contact = 'Yes' AND td.suspect = 1 AND id.suspect = 1) OR /* No twin - Informant is Blessed */ (ISNULL(td.suspect) AND id.suspect = 1 AND id.future_contact = 'Yes') OR /* Twin broken off - Informant is Blessed */ (td.participation = 'Aborted' AND id.suspect = 1 AND id.future_contact = 'Yes') OR /* Twin broken off - No inform - Have partner */ (td.participation = 'Aborted' AND ISNULL(id.suspect) AND p2.dead = 0)) AND l.event = 'Finished' /* Get at area code */ AND SUBSTRING(p1.postal_code, 1, 2) = pg.code /* Not already distributed */ AND (h.nurse IS NULL OR h.nurse=00 OR h.doctor=00) /* Has not refused or been aborted */ AND NOT (h.status = 'Refused' OR h.status = 'Aborted' OR h.status = 'Died' OR h.status = 'Other') ORDER BY tvid;
これについて簡単に説明します。
CONCAT(p1.id, p1.tvab)
+ 0 AS tvid
id
と
tvab
を連結した値を、数値の順にソートします。結果に
0
を加算すると、MySQL
はその結果を数値として扱います。
カラム id
双生児の組を識別します。これはすべてのテーブルでインデックスとして使用されます。
カラム tvab
双生児の組の中の個人を識別します。この値は
1
または
2
のどちらかになります。
カラム ptvab
tvab
の逆の値です。tvab
が 1
の場合、この値は
2
であり、その逆も同様です。このカラムは、入力量を少なくするためと、MySQL
がクエリーを最適化しやすくするために定義されています。
このクエリーは、特に、同じテーブルを使用した結合
(p1
と
p2
)
でテーブルを検索する方法を示しています。この例では、双生児の一方が
65
歳以前に死亡しているかどうかの確認に使用されています。死亡している場合、その行は返されません。
上で説明したカラムは、双生児関連のすべてのテーブルで定義されています。クエリーの実行速度を向上するために、id,
tvab
の両方 (すべてのテーブル) および
id, ptvab
(person_data
)
にインデックスを設定しています。
当時、当社の本稼働マシンは 200MHz の UltraSPARC でしたが、この古いハードウェアでも、このクエリーは 1 秒未満で約 150 ~ 200 行を返しました。メインテーブルには 7 万行が含まれていました。