๐ ๋ณธ ํฌ์คํ ์์ ์ฌ์ฉ๋๋ ํ ์ด๋ธ์ ์๋ฃ์ ์ถ์ฒ๋ HackerRank ์์ ๋ฐํ๋๋ค. ๋ ๋ค์ํ SQL ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์๋ ค๋ฉดHackerRank ์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํด ๋ณด์ธ์!
์ด๋ฒ ํฌ์คํ ์์๋ MySQL์ ํ์ฉํด Median๊ฐ์ ์ถ๋ ฅํด๋ณด๋ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ ค ํ๋ค. Median์ด๋, ์ ์๋ค์ํผ ์ค์๊ฐ์ ์๋ฏธํ๋ฉฐ ๋ณดํต ๋ฐ์ดํฐ ๋ถํฌ๊ฐ ์น์ฐ์ณ์ ธ ์์ ๋ ๋ฐ์ดํฐ์ ๋ํฏ๊ฐ์ผ๋ก ์์ฃผ ์ค์ ํ๋ ์ฒ๋์ด๋ค. ์ด๋ฐ ์ค์๊ฐ์ SQL๋ก ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด์. ๋ฌธ์ ์ ์๋ณธ์ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ์. ๋ฌธ์ ์ ์๊ตฌ์ฌํญ์ ๋ค์๊ณผ ๊ฐ๋ค.
A median is defined as a number separating the higher half of a data set from the lower half. Query themedianof theNorthern Latitudes(LAT_N) fromSTATIONand round your answer to 4 decimal places.
(STATION์ด๋ผ๋ ํ ์ด๋ธ์ LAT_N ์นผ๋ผ์ ์ค์๊ฐ์ ์ถ๋ ฅํ๋ผ. ์ด ๋ ์ถ๋ ฅ๊ฐ์ ์์์ 5๋ฒ์งธ ์๋ฆฌ์์ ๋ฐ์ฌ๋ฆผํ์ฌ ์์ 4๋ฒ์ฌ ์๋ฆฌ๊น์ง ์ถ๋ ฅ์์ผ๋ผ.)
ํ ์ด๋ธ ํํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
SQL์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ์ง๊ณํจ์๋ก๋ MAX(์ต๋๊ฐ)
, MIN(์ต์๊ฐ)
, AVG(ํ๊ท ๊ฐ)
๋ฑ์ด ์๋ค. ๊ทธ๋์ ๋ฌธ์ ๋ฅผ ์ฒ์ ํ ๋น์ MEDIAN() ์ด๋ผ๋ ๋ฉ์๋๋ฅผ ์ ๊ณตํ์ง ์์๊น? ์ถ์ด์ ๊ตฌ๊ธ๋ง์ ํด๋ณด๋ ์ญ์๋ ์์๋ค..
๊ทธ๋ ๋ค๋ฉด ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์ค์๊ฐ์ ์ถ๋ ฅํ๋๋ก ํด์ฃผ์ด์ผ ํ๋๋ฐ ๋ฌธ์ ํด๊ฒฐ ์์ด๋์ด๋ฅผ ๋ ์ฌ๋ฆด ๋ ์ ๋ฒ์ ํ์ด๋ณด์๋ ๋ฌธ์ ์์ ํํธ๋ฅผ ์ป์๋ค. ๋ฐ๋ก SET
์ด๋ผ๋ ์ฟผ๋ฆฌ๋ฅผ ์ด์ฉํด ์๋ก์ด ๋ณ์๋ฅผ ์ ์ํด์ฃผ๊ณ ์ด๋ฅผ ์ด์ฉํด ํ
์ด๋ธ ํ(Row)์ index๋ฅผ ๋ํ๋ด๋ ํ์ ์นผ๋ผ์ ๋ง๋ค์ด์ผ ํ๋ค๋ ๊ฒ! ์ฐ์ ์ ๋ต SQL ๊ตฌ๋ฌธ์ ์ดํด๋ณด์.
SET @rowIndex=-1;
SELECT ROUND(AVG(lat_n), 4) AS Median
FROM (SELECT @rowIndex:=@rowIndex+1 AS RowNumber,
lat_n
FROM station
ORDER BY lat_n) sub
WHERE RowNumber IN (FLOOR(@rowIndex / 2), CEIL(@rowIndex / 2))
์, ์ด์ ์ ๋ต SQL ๊ตฌ๋ฌธ์ ํ๋์ฉ ๋ฏ์ด๋ณด์. ์ฐ์ , ์ค์๊ฐ์ ์ค์ ํ๋ ๊ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ์ ๋, ๊ฐ์ด๋ฐ ์๋ฒ์ ์๋ ์ซ์๋ฅผ ์ค์๊ฐ์ด๋ผ๊ณ ํ๋ค.(์ด ๋, ์ ๋ ฌ๊ธฐ์ค์ ์ค๋ฆ์ฐจ์์ด๋ ๋ด๋ฆผ์ฐจ์์ด๋ ์๊ด์์) ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ SET
์ ํ์ฉํด ํ
์ด๋ธ ํ์ ์ซ์๋ฅผ ์ธ์ฃผ์. ์ด ๋ -1
์ด๋ผ๊ณ ์ค์ ํ๋ ์ด์ ๋ ์ดํ์ ์ค์๊ฐ์ ์ฐพ์ ๋ ๋ฐ์ดํฐ ๊ฐ์๊ฐ ํ์/์ง์์ ๋ฐ๋ผ ์ค์ ๋ฐฉ๋ฒ์ด ๋ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ด๋ค.(์ด ๋ถ๋ถ์ ํ๋จ์์ ์ดํด๋ณด์.)
SET @rowIndex=-1;
SELECT @rowIndex:=@rowIndex+1,
lat_n
FROM station
ORDER BY lat_n
์ SQL๊ตฌ๋ฌธ์ผ๋ก ์ฐ์ LAT_N
๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ์ ๋ ํ
์ด๋ธ์ ํ ์ซ์๋ฅผ ๋งค๊ธฐ๊ณ LAT_N
๊ฐ์ ์ถ๋ ฅํ๋ฉด ๋ค์๊ณผ ๊ฐ์์ง๋ค.
์ด์ ์ ๊ฒฐ๊ณผ์์ ์ค์๊ฐ์ ์ฐพ์์ฃผ๋ฉด ๋๋๋ฐ, ์ ๋ต SQL ๊ตฌ๋ฌธ์ WHERE
์ ์ด ํ ๋ฒ์ ์ดํด๊ฐ ํ ์๋ฟ์ง ์์ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ ์์๋ฅผ ํ ๋ฒ๋ค์ด๋ณด์. ํ์ ์ฒซ ๋ฒ์งธ Index๋ 0์ผ๋ก ์ค์ ํ์ ๋์ด๋ค. ์ฐ์ ๋ฐ์ดํฐ ๊ฐ์๊ฐ ์ง์๊ฐ์ผ ๋์ด๋ค.
RowNumber | Value |
0 | 100 |
1 | 200 |
2 | 300 |
3 | 400 |
์์์ ์ค์๊ฐ์ RowNumber๊ฐ 1๊ณผ 2์ผ ๋์ Value๋ฅผ ํ๊ท ๋ธ ๊ฐ์ธ 250์ด ๋๋ค. ๋ฐ๋ผ์ ๋ง์ง๋ง RowNumber์ธ 3
์ 2
๋ก ๋๋๊ฒ ๋๋ฉด 1.5
๊ฐ ๋๊ณ ์ด๋ฅผ FLOOR(๋ด๋ฆผ ์ฒ๋ฆฌ)
ํ๋ฉด 1
, CEIL(์ฌ๋ฆผ ์ฒ๋ฆฌ)
ํ๋ฉด 2
๊ฐ ๋๊ฒ ๋๋ค. ๋ฐ๋ผ์ ์ฌ๋ฆผ, ๋ด๋ฆผ์ฒ๋ฆฌํ ๊ฐ๊ฐ์ RowNumber์ ํด๋นํ๋ Value 2๊ฐ๋ฅผ ํ๊ท ๊ฐ์ ๋ด๊ฒ ๋๋ฉด ์ค์๊ฐ์ด ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฐ๋๋ก ๋ฐ์ดํฐ ๊ฐ์๊ฐ ํ์์ผ ๋๋ฅผ ์ดํด๋ณด์.
RowNumber | Value |
0 | 100 |
1 | 200 |
2 | 300 |
3 | 400 |
4 | 500 |
์์์ ์ค์๊ฐ์ 300
์ด ๋๋ค. ๋ง์ง๋ง RowNumber์ธ 4
๋ฅผ 2
๋ก ๋๋๊ฒ ๋๋ฉด 2
๋ก ๋๋์ด๋จ์ด์ง๋ค. ๊ทธ๋ฐ๋ฐ ์ด์ฐจํผ ์ ์์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ FLOOR
, CEIL
์ฒ๋ฆฌ ํ์ฌ๋ ๋์ผํ๊ฒ ์ ์์ธ 2๊ฐ ๋์ค๊ฒ ๋๋ค. ๋ํ RowNumber = 2
์ธ Value์ธ 300
2๊ฐ์ ๊ฐ์ ํ๊ท ๊ฐ์ ๋ด์ด๋ ๋์ผํ๊ฒ 300
์ด ๋๋ค.
๋ฐ๋ผ์ ๋ฐ์ดํฐ ๊ฐ์์ ์๊ด์์ด ์ฒซ ๋ฐ์ดํฐ ํ์ Index๊ฐ 0์ผ๋ก ์์ํ ๋, ๋ง์ง๋ง ํ Index๋ฅผ ๊ฐ์ง๊ณ ์ค์๊ฐ์ ๊ณ์ฐํด๋ผ ์ ์๋ค. ๋ง์ฝ ํ์์ ์ค๋ช ์ผ๋ก๋ ์ดํด๊ฐ ์ ๊ฐ์ง ์๋๋ค๋ฉด ๊ผญ ๋ ธํธ์ ํ๊ธฐํด์๋ผ๋ ์ดํดํ์! ๋จธ๋ฆฟ์์ผ๋ก ์๊ฐ๋ง ํ๋ ๊ฒ๊ณผ ์์ผ๋ก ์จ๋ณด์์ ์๊ฐ์ผ๋ก ํ์ธํ๋ ๊ฒ์ ๋ถ๋ช ๋ค๋ฅด๋ค!
๊ฒฐ๊ตญ ์์ ๊ฐ์ ๊ณผ์ ๋ค์ ๊ฑฐ์ณ ์ด์ ์ ๋ณด์ฌ์ฃผ์๋ ์ ๋ต SQL ๊ตฌ๋ฌธ์ด ๋์ค๊ฒ ๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ฃผ์ํด์ผ ํ ์ ์ WHERE
๊ตฌ๋ฌธ์ ๋ง์ง๋ง ํ Index๋ฅผ ์ ์ํด์ค ๋ RowNumber
์ด ์๋ @rowIndex
์ธ ์ด์ ๋ ์๋ธ์ฟผ๋ฆฌ ๊ตฌ๋ฌธ์์ @rowIndex := @rowIndex+1
๋ก ๊ณ์์ ์ผ๋ก ๋ํด์ฃผ์๊ณ ๊ฒฐ๊ตญ ๋ง์ง๋ง์ ์ต์ข
์ ์ผ๋ก ํ ๋น๋ @rowIndex
๋ณ์์๋ ๋ง์ง๋ง ํ์ Index๊ฐ ๋ด๊ฒจ์๊ธฐ ๋๋ฌธ์ด๋ค.
SET @rowIndex=-1;
SELECT ROUND(AVG(lat_n), 4) AS Median
FROM (SELECT @rowIndex:=@rowIndex+1 AS RowNumber,
lat_n
FROM station
ORDER BY lat_n) sub
WHERE RowNumber IN (FLOOR(@rowIndex / 2), CEIL(@rowIndex / 2))
[์ฐธ์กฐ]