SQL(Sosuu reQuest Language)
18523 단어 SQL
입문
이 글은 회사 내 Advent Calendar 2013의 12/11점짜리 글입니다.
회사 기밀을 특별히 다루는 정보가 없어서 공개하려고 합니다.
말랑말랑한 내용이라 편하게 읽었으면 좋겠어요.
한편, 이미지는 12/9 초롱군의 보도문외한분들이 Surface Pro로 그림을 그려보세요.를 읽고 문외한이 마우스로 그림을 그릴 때의 질과 개인적으로 비교했을 때의 것이다.
자꾸 내 그림이 사악한 분위기를 풍기는 것 같아.역시 서피스 프로 대단해!(.마음에 들어.)☆
갈라질 수 없는 굳세고 변함없는 그리움
며칠 전 고등학교 시절 친구와 술을 마시러 갔을 때 한 말이다.
그 친구 얼마 전에 결혼했어요.
축의금에는 30011엔의 신비한 금액이 있다고 한다.
일반적으로 지폐의 장수를 두 부분으로 나누지 않기 위해
나는 3만 엔과 5만 엔이 비교적 많다고 생각한다.
그럼 직감이 좋은 사람이 눈치채겠지.
예.“소수”.
30000은 2로 찢어지잖아!
절대로 다른 수로 나누면 안 되는 수,'소수'로 두 사람을 축하합시다!
이렇게 부드러운 숫자.
소수.너무 좋아요.
음...?30011 진짜 소수야?
여기 한번 알아볼게요.
이곳에서 시작된 이 기획은
SQL(Sosuu reQuest Language)
어차피 하려면...
30011이 소수인지 아닌지 조사하는 게 너무 아쉬워요.
소수 일람표를 만들어서 어떤 숫자도 알아낼 수 있도록 하세요!
그래서 나는 소수의 일람표를 만들기로 했다.
이번의 경우 대략 어릴 때부터 10000개의 소수 일람을 하면 충분하지 않을까.
부족하면 늘었으면 좋겠어요.
아무튼 한번 해봤어요.
어떤 숫자가 소수인지 아닌지
"그 숫자가 자신보다 작은 소수로 갈라진 것이 있는지 조사해 보세요.
만약 깨진 것이 하나도 없다면, 이 숫자는 소수이다. "
사용자 정의 모양새를 정의합니다.
그래서
며칠 전 고등학교 시절 친구와 술을 마시러 갔을 때 한 말이다.
그 친구 얼마 전에 결혼했어요.
축의금에는 30011엔의 신비한 금액이 있다고 한다.
일반적으로 지폐의 장수를 두 부분으로 나누지 않기 위해
나는 3만 엔과 5만 엔이 비교적 많다고 생각한다.
그럼 직감이 좋은 사람이 눈치채겠지.
예.“소수”.
30000은 2로 찢어지잖아!
절대로 다른 수로 나누면 안 되는 수,'소수'로 두 사람을 축하합시다!
이렇게 부드러운 숫자.
소수.너무 좋아요.
음...?30011 진짜 소수야?
여기 한번 알아볼게요.
이곳에서 시작된 이 기획은
SQL(Sosuu reQuest Language)
어차피 하려면...
30011이 소수인지 아닌지 조사하는 게 너무 아쉬워요.
소수 일람표를 만들어서 어떤 숫자도 알아낼 수 있도록 하세요!
그래서 나는 소수의 일람표를 만들기로 했다.
이번의 경우 대략 어릴 때부터 10000개의 소수 일람을 하면 충분하지 않을까.
부족하면 늘었으면 좋겠어요.
아무튼 한번 해봤어요.
어떤 숫자가 소수인지 아닌지
"그 숫자가 자신보다 작은 소수로 갈라진 것이 있는지 조사해 보세요.
만약 깨진 것이 하나도 없다면, 이 숫자는 소수이다. "
사용자 정의 모양새를 정의합니다.
그래서
어떤 숫자가 소수인지 아닌지
"그 숫자가 자신보다 작은 소수로 갈라진 것이 있는지 조사해 보세요.
만약 깨진 것이 하나도 없다면, 이 숫자는 소수이다. "
사용자 정의 모양새를 정의합니다.
그래서
…
이 앞의 결과표를 사용하여 검증...?
...최초의 첫 번째는 어떡하지?
그럼...최초의 하나는'2'이니 결과용 책상 위에 미리 놓으세요!
그러니까 아무 생각 없이 쓰기 시작해.
--素数一覧結果用テーブル
CREATE TABLE #PrimeNumbers
(
SEQ int
, PrimeNumber bigint
)
--最初の素数である2は入れておく
INSERT INTO #PrimeNumbers VALUES(1, 2)
DECLARE
@RequiredPrimeNumberCount int = 10000
, @PrimeNumberCount int = 1
, @Number bigint = 3
, @TestNumber bigint
, @HasFound bit
--取得できた素数のカウントが要求された件数に達するまでループする
WHILE @PrimeNumberCount < @RequiredPrimeNumberCount
BEGIN
--FLG初期化
SET @HasFound = 0
--これまでに見つけた素数で割れるかを順に検証する為にカーソルを回す
DECLARE Cur CURSOR FOR
SELECT
PrimeNumber
FROM #PrimeNumbers
ORDER BY
SEQ
OPEN Cur
FETCH NEXT FROM Cur INTO @TestNumber
-- ココから検証
--割り切れる数が見つかるか、素数カーソルを最後まで回しきったら検証終了
WHILE @HasFound = 0 AND @@FETCH_STATUS = 0
BEGIN
IF @Number % @TestNumber = 0
BEGIN
--割り切れちゃったらFLGを立てる
SET @HasFound = 1
END
FETCH NEXT FROM Cur INTO @TestNumber
END
CLOSE Cur
DEALLOCATE Cur
--検証した結果、割り切れる数が見つからなかった場合は素数の件数をカウントアップして、結果用テーブルにINSERT
IF @HasFound = 0
BEGIN
SET @PrimeNumberCount += 1
INSERT INTO #PrimeNumbers VALUES(@PrimeNumberCount, @Number)
END
--そして、また次の数字の検証へ…
SET @Number += 1
END
--全件取得
SELECT
*
FROM #PrimeNumbers
ORDER BY
SEQ
--30011の確認
SELECT
*
FROM #PrimeNumbers
WHERE
PrimeNumber = 30011
DROP TABLE #PrimeNumbers
완성!
확실히 30011은 소수!!
너무 좋아!!!
아니, 대단한 건 아니지..
나는 결과를 얻게 되어 매우 기쁘다
처리 시간: 00:21:03(hhss)
...기다릴 때 배꼽으로 차를 끓이는 수준이다.
제대로 참을 수 있는 연기를 어떻게...
관건은 어떻게 검증을 가속화하는가이다.
원래 순환 중에 커서가 느려지는 것은 당연하다.
수량이 갈수록 많아지다.
커서 사용하지 않기...
만약 네가 그 숫자를 제거할 수 있는 소수를 찾을 수 있다면, 그것은 소수가 아니다.
...어?WHERE로 하면 되잖아...?
그래서
여기 아주 무거운 조회가 있죠? --これまでに見つけた素数で割れるかを順に検証する為にカーソルを回す
DECLARE Cur CURSOR FOR
SELECT
PrimeNumber
FROM #PrimeNumbers
ORDER BY
SEQ
OPEN Cur
FETCH NEXT FROM Cur INTO @TestNumber
-- ココから検証
--割り切れる数が見つかるか、素数カーソルを最後まで回しきったら検証終了
WHILE @HasFound = 0 AND @@FETCH_STATUS = 0
BEGIN
IF @Number % @TestNumber = 0
BEGIN
--割り切れちゃったらFLGを立てる
SET @HasFound = 1
END
FETCH NEXT FROM Cur INTO @TestNumber
END
CLOSE Cur
DEALLOCATE Cur
이 부분은... SELECT
@HasFound = 1
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
그렇구나!
비주얼도 상당히 상큼하네요.
처음 그거 뭐였지?
결과는...
처리 시간: 00:00:58(hhss)
좋아요.
이렇게 되면 라면을 만드는 것보다 결과가 더 빨리 돌아올 것이다!
하면, 만약, 만약...
검증 예
"그 숫자가 자신보다 작은 소수로 갈라진 것이 있는지 조사해 보세요.
만약 깨진 것이 하나도 없다면, 이 숫자는 소수이다. "
갔습니다.
...깨진 것이 하나도 없다면...?
…EXISTS!!!
왜 처음에 커서를 썼을까요?
나는 정말 바보다.
WHERE 때 결과를 시계로 전부 스캔했어요.
EXISTS를 사용하면 하나를 얻을 때 처리에서 벗어날 수 있기 때문에 성능 향상을 기대할 수 있습니다.
그래서... SELECT
@HasFound = 1
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
이 부분은...
SELECT
@HasFound = 1
WHERE EXISTS
(
SELECT
*
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
)
그렇구나!!!
결과는...
처리 시간: 00:00:07(hhss)
뜻밖에!
아까 조회한 8배속 정도였나요!!
여기까지 왔다!!!
왜 처음부터 그런 방법을 썼을까...
할 줄 모르고 해봤어요.
프롬 자구SELECT ○○ WHERE EXISTS~
를 사용하지 않으면 됩니다.
이번에 이런 발견이 있을 줄은 생각지도 못했다.
이 기사를 쓸 수 있어서 정말 다행이다.
결국 이런 조회를 마쳤습니다.
GetPrimeNumbers.sqlCREATE TABLE #PrimeNumbers
(
SEQ int
, PrimeNumber bigint
)
INSERT INTO #PrimeNumbers VALUES(1, 2)
DECLARE
@RequiredPrimeNumberCount int = 10000
, @PrimeNumberCount int = 1
, @Number bigint = 3
, @HasFound bit
WHILE @PrimeNumberCount < @RequiredPrimeNumberCount
BEGIN
SET @HasFound = 0
SELECT
@HasFound = 1
WHERE EXISTS
(
SELECT
*
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
)
IF @HasFound = 0
BEGIN
SET @PrimeNumberCount += 1
INSERT INTO #PrimeNumbers VALUES(@PrimeNumberCount, @Number)
END
SET @Number += 1
END
SELECT
*
FROM #PrimeNumbers
ORDER BY
SEQ
DROP TABLE #PrimeNumbers
이렇게 하면 소수의 일람표를 얻을 수 있다!
아주 긴 길.
아이고, 원래 축하 선물의 30011엔이 수수한 금액인지 알아보고 있었어요.
결국...
30011은 3246번째 소수!
총결산
이번에 나는 이 느낌을 했다
--これまでに見つけた素数で割れるかを順に検証する為にカーソルを回す
DECLARE Cur CURSOR FOR
SELECT
PrimeNumber
FROM #PrimeNumbers
ORDER BY
SEQ
OPEN Cur
FETCH NEXT FROM Cur INTO @TestNumber
-- ココから検証
--割り切れる数が見つかるか、素数カーソルを最後まで回しきったら検証終了
WHILE @HasFound = 0 AND @@FETCH_STATUS = 0
BEGIN
IF @Number % @TestNumber = 0
BEGIN
--割り切れちゃったらFLGを立てる
SET @HasFound = 1
END
FETCH NEXT FROM Cur INTO @TestNumber
END
CLOSE Cur
DEALLOCATE Cur
SELECT
@HasFound = 1
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
검증 예
"그 숫자가 자신보다 작은 소수로 갈라진 것이 있는지 조사해 보세요.
만약 깨진 것이 하나도 없다면, 이 숫자는 소수이다. "
갔습니다.
...깨진 것이 하나도 없다면...?
…EXISTS!!!
왜 처음에 커서를 썼을까요?
나는 정말 바보다.
WHERE 때 결과를 시계로 전부 스캔했어요.
EXISTS를 사용하면 하나를 얻을 때 처리에서 벗어날 수 있기 때문에 성능 향상을 기대할 수 있습니다.
그래서...
SELECT
@HasFound = 1
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
이 부분은...
SELECT
@HasFound = 1
WHERE EXISTS
(
SELECT
*
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
)
그렇구나!!!결과는...
처리 시간: 00:00:07(hhss)
뜻밖에!
아까 조회한 8배속 정도였나요!!
여기까지 왔다!!!
왜 처음부터 그런 방법을 썼을까...
할 줄 모르고 해봤어요.
프롬 자구
SELECT ○○ WHERE EXISTS~
를 사용하지 않으면 됩니다.이번에 이런 발견이 있을 줄은 생각지도 못했다.
이 기사를 쓸 수 있어서 정말 다행이다.
결국 이런 조회를 마쳤습니다.
GetPrimeNumbers.sqlCREATE TABLE #PrimeNumbers
(
SEQ int
, PrimeNumber bigint
)
INSERT INTO #PrimeNumbers VALUES(1, 2)
DECLARE
@RequiredPrimeNumberCount int = 10000
, @PrimeNumberCount int = 1
, @Number bigint = 3
, @HasFound bit
WHILE @PrimeNumberCount < @RequiredPrimeNumberCount
BEGIN
SET @HasFound = 0
SELECT
@HasFound = 1
WHERE EXISTS
(
SELECT
*
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
)
IF @HasFound = 0
BEGIN
SET @PrimeNumberCount += 1
INSERT INTO #PrimeNumbers VALUES(@PrimeNumberCount, @Number)
END
SET @Number += 1
END
SELECT
*
FROM #PrimeNumbers
ORDER BY
SEQ
DROP TABLE #PrimeNumbers
이렇게 하면 소수의 일람표를 얻을 수 있다!
아주 긴 길.
아이고, 원래 축하 선물의 30011엔이 수수한 금액인지 알아보고 있었어요.
결국...
30011은 3246번째 소수!
총결산
이번에 나는 이 느낌을 했다
CREATE TABLE #PrimeNumbers
(
SEQ int
, PrimeNumber bigint
)
INSERT INTO #PrimeNumbers VALUES(1, 2)
DECLARE
@RequiredPrimeNumberCount int = 10000
, @PrimeNumberCount int = 1
, @Number bigint = 3
, @HasFound bit
WHILE @PrimeNumberCount < @RequiredPrimeNumberCount
BEGIN
SET @HasFound = 0
SELECT
@HasFound = 1
WHERE EXISTS
(
SELECT
*
FROM #PrimeNumbers MAIN
WHERE
@Number % MAIN.PrimeNumber = 0
)
IF @HasFound = 0
BEGIN
SET @PrimeNumberCount += 1
INSERT INTO #PrimeNumbers VALUES(@PrimeNumberCount, @Number)
END
SET @Number += 1
END
SELECT
*
FROM #PrimeNumbers
ORDER BY
SEQ
DROP TABLE #PrimeNumbers
이번에 나는 이 느낌을 했다
마지막이 더 멋있네.
조회가 생각보다 많아요.
이런 어리석은 사용법도 있군요.자리라고 생각하시면 좋을 것 같습니다.
이번에는 아무것도 찾지 않고 생각난 이 알고리즘으로 소수 판정을 했는데 찾아보니 더 똑똑한 방법이 많은 것 같다.
위키백과-질수판정
일련번호표탄성 강도 체를 만들어 조회하는 것도 재미있다.
며칠 후에 도전해 보세요.
또 "이렇게 재미있고 어리석은 조회를 썼어요!"하면, 만약, 만약...
반드시 정보를 공유하세요!
여기까지 읽어줘서 고마워!
추가
참고로 실제로는 조회Project Euler입니다.이런 신비한 도전에서 시작된다.
관심이 있다면 SQL과 C#에 도전해 보세요.
또 7번째 문제인'10001개의 소수를 구하기'문제에서 정확하기 때문에
이번 조회에서 얻은 결과집은 틀림없이 정확할 것이다!
게다가
어렵기 때문에, 겸사겸사 분해소 인수에 대한 조회를 써 보았다
그것을 쓰는 공백이 너무 좁다.
Reference
이 문제에 관하여(SQL(Sosuu reQuest Language)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sei_myopia/items/5e66760874360d200630텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)