てくのーと
787 文字
4 分

第6回 SQLコンテスト 振り返り

2023-04-18
2024-07-05

TOPSIC SQL CONTESTの第6回コンテストに参加したので、その振り返りです。

第5回までは存在を知らなかったため、今回が初参加でした。

4つの問題から構成されていて、今回は時間をかければ多くの人が4問目まで解ききることができる比較的簡単な問題だったと思います。

順位の結果は、26位でした。可もなく不可もなくといったところでしょうか。あまりER図などに慣れていなかったので、時間がかかってしまったように思います。

次からの対策として考えているのは、以下のようなものです。

まず問題文からクエリを構成してみること
ER図から先にみたりしていて、無駄に時間をかけてしまっていた。
慎重にやりすぎず、コードテストで試してみること
集中できる時間を取って取り組む
緩い気持ちで始めてしまっており、トイレや、他の作業を合間にはさんでいたのが良くなかった。
次回開催時期は、未定ですが、次回は15位、10位以内ぐらいには入りたいです。

問題の振り返り

問1~3までは基本的な内容なので省略。

問4
私は以下のようなSQL文で通りました。

SELECT l.DISTRICT_CODE AS CODE, d.DISTRICT_NAME AS NAME, l.LATITUDE AS LAT, l.LONGITUDE AS LON
FROM LOCATION_TBL AS l
INNER JOIN DISTRICT AS d ON l.DISTRICT_CODE = d.DISTRICT_CODE
WHERE l.DISTRICT_CODE <> ‘1101’
ORDER BY (
POW(l.LATITUDE - (SELECT LATITUDE FROM LOCATION_TBL AS l2 WHERE l2.DISTRICT_CODE = ‘1101’) ,2)
+
POW(l.LONGITUDE - (SELECT LONGITUDE FROM LOCATION_TBL AS l2 WHERE l2.DISTRICT_CODE = ‘1101’) ,2)
) DESC, l.DISTRICT_CODE ASC;

ただ、サブクエリを利用しているので、データ数が多くなるとパフォーマンスに影響が出る可能性があります。

一方、公式が発表している答えは以下のものです。

SELECT
D.DISTRICT_CODE CODE,
D.DISTRICT_NAME NAME,
T.LATITUDE LAT,
T.LONGITUDE LON
FROM DISTRICT AS D
INNER JOIN LOCATION_TBL AS T
ON D.DISTRICT_CODE = T.DISTRICT_CODE
— 地区コード ‘1101’を表示しない
AND D.DISTRICT_CODE != ‘1101’
— 各レコードと計算するため、‘1101’の緯度、経度を交差結合で取得
CROSS JOIN LOCATION_TBL AS LT
ON LT.DISTRICT_CODE = ‘1101’
ORDER BY
— 直角三角形の斜辺の長さを求める三平方の定理を利用して長さを求める
(POW(LT.LATITUDE - T.LATITUDE, 2) + POW(LT.LONGITUDE - T.LONGITUDE, 2)) DESC
, D.DISTRICT_CODE ASC;

実は、これを見るまでCROSS JOIN(交差結合)の存在を知りませんでした。

テーブルAに対してテーブルBを交差結合する場合、テーブルAの各レコードに対して、テーブルBのそれぞれのレコードがJOINされるます。

つまり、出力されるレコード数は、Aのレコード数×Bのレコード数になります。

今回の場合は、1レコード(DISTRICT_CODE = ‘1101’)だけをCROSS JOINしています。(なので、この場合であれば、INNER JOINでも実装できます。)

正答や他の方の回答が見られるのは、勉強になるのでいいですね。

\てくのーと おすすめ書籍!/

OAuthという名前は知っているけれど、中身のフローは知らないという方におすすめです。
丁寧に書かれているので、理解がスムーズに進みます。
→感想詳細はこちら!