문제 https://www.acmicpc.net/problem/1912 1912번: 연속합 첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다. www.acmicpc.net n개의 정수로 이루어진 임의의 수열이 주어진다. 우리는 이 중 연속된 몇 개의 수를 선택해서 구할 수 있는 합 중 가장 큰 합을 구하려고 한다. 단, 수는 한 개 이상 선택해야 한다. 예를 들어서 10, -4, 3, 1, 5, 6, -35, 12, 21, -1 이라는 수열이 주어졌다고 하자. 여기서 정답은 12+21인 33이 정답이 된다. 입력 첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지..
문제 https://www.acmicpc.net/problem/1904 1904번: 01타일 지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다. 어느 날 짓궂은 동주가 지원이 www.acmicpc.net 지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다. 어느 날 짓궂은 동주가 지원이의 공부를 방해하기 위해 0이 쓰여진 낱장의 타일들을 붙여서 한 쌍으로 이루어진 00 타일들을 만들었다. 결국 현재 1 하나만으로 이루어진 타일 또는 0타일을 두 개 붙인 한 쌍의 00타일들만이 남게 되었다. ..
문제 https://www.acmicpc.net/problem/1874 1874번: 스택 수열 1부터 n까지에 수에 대해 차례로 [push, push, push, push, pop, pop, push, push, pop, push, push, pop, pop, pop, pop, pop] 연산을 수행하면 수열 [4, 3, 6, 8, 7, 5, 2, 1]을 얻을 수 있다. www.acmicpc.net 스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다. 1부터 n까지의 수..
1. union / union all 두 집합을 중복을 제거하고 합집합 형태로 조회, union all은 중복제거 x select A.* from (select column1 , column2 from A_table union select column3 , column4 from B_table) A; 2. || , concat 문자열 합치기 select 'My name is ' || name; from name_table; --Tom Holland-- select concat('Hi ', name, ' is my name'); from name_table; --Hi Tom Holland is my name-- 3. substring 문자열 자르기 substring(문자열, 시작점, 시작점부터 개수) se..
CASECASE 특정 조건이 충족되었을 때 SQL코드를 실행하기 위해 CASE를 사용한다. 프로그래밍 언어에서 흔히 쓰이는 IF/ELSE 문과 비슷하다. 일반적인 CASE문과 CASE 표현식으로 쓸 수 있다. 두 방법 모두 결과는 같다. -- 기본 문법 CASE WHEN condition1 THEN result1 WHEN condition2 THEN result2 ELSE some_other_result END SELECT a, CASE WHEN a = 1 THEN 'one' WHEN a = 2 THEN 'two' ELSE 'other' AS label END FROM test; -- CASE 표현식 CASE expression WHEN value1 THEN result1 WHEN value2 THEN ..
n개의 정수로 이루어진 임의의 수열이 주어진다. 우리는 이 중 연속된 몇 개의 수를 선택해서 구할 수 있는 합 중 가장 큰 합을 구하려고 한다. 단, 수는 한 개 이상 선택해야 한다.
예를 들어서 10, -4, 3, 1, 5, 6, -35, 12, 21, -1 이라는 수열이 주어졌다고 하자. 여기서 정답은 12+21인 33이 정답이 된다.
입력
첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
출력
첫째 줄에 답을 출력한다.
코드
import sys
input=sys.stdin.readline
n=int(input())
array=list(map(int, input().split()))
for i in range(1,n):
array[i]=max(array[i], array[i-1]+array[i])
print(max(array))
문제 해결
연속합을 2중 포문으로 일일히 계산하기보다 연속된 수의 합을 갱신하는 방향으로 코드를 작성하였다.
지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다.
어느 날 짓궂은 동주가 지원이의 공부를 방해하기 위해 0이 쓰여진 낱장의 타일들을 붙여서 한 쌍으로 이루어진 00 타일들을 만들었다. 결국 현재 1 하나만으로 이루어진 타일 또는 0타일을 두 개 붙인 한 쌍의 00타일들만이 남게 되었다.
그러므로 지원이는 타일로 더 이상 크기가 N인 모든 2진 수열을 만들 수 없게 되었다. 예를 들어, N=1일 때 1만 만들 수 있고, N=2일 때는 00, 11을 만들 수 있다. (01, 10은 만들 수 없게 되었다.) 또한 N=4일 때는 0011, 0000, 1001, 1100, 1111 등 총 5개의 2진 수열을 만들 수 있다.
우리의 목표는 N이 주어졌을 때 지원이가 만들 수 있는 모든 가짓수를 세는 것이다. 단 타일들은 무한히 많은 것으로 가정하자.
입력
첫 번째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 1,000,000)
출력
첫 번째 줄에 지원이가 만들 수 있는 길이가 N인 모든 2진 수열의 개수를 15746으로 나눈 나머지를 출력한다.
코드
import sys
input = sys.stdin.readline
n = int(input())
dp = [0] * 1000001
dp[1] = 1
dp[2] = 2
for k in range(3,n+1):
dp[k] = (dp[k-1]+ dp[k-2])%15746
print(dp[n])
스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다.
1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다. 이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자. 임의의 수열이 주어졌을 때 스택을 이용해 그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하라.
입력
첫 줄에 n (1 ≤ n ≤ 100,000)이 주어진다. 둘째 줄부터 n개의 줄에는 수열을 이루는 1이상 n이하의 정수가 하나씩 순서대로 주어진다. 물론 같은 정수가 두 번 나오는 일은 없다.
출력
입력된 수열을 만들기 위해 필요한 연산을 한 줄에 한 개씩 출력한다. push연산은 +로, pop 연산은 -로 표현하도록 한다. 불가능한 경우 NO를 출력한다.
코드
import sys
n=int(sys.stdin.readline())
stack, res, find=[],[],True
now=1
for _ in range(n):
num=int(sys.stdin.readline())
while now<=num:
stack.append(now)
res.append('+')
now+=1
if stack[-1]==num:
stack.pop()
res.append('-')
else:
find =False
if find:
for i in res:
print(i)
else:
print("NO")
select
A.*
from
(select
column1 ,
column2
from
A_table
union
select
column3 ,
column4
from
B_table) A;
2. || , concat
문자열 합치기
select
'My name is ' || name;
from
name_table;
--Tom Holland--
select
concat('Hi ', name, ' is my name');
from
name_table;
--Hi Tom Holland is my name--
3. substring
문자열 자르기 substring(문자열, 시작점, 시작점부터 개수)
select
substring('Tom Holland', 1 ,3);
--Tom--
4. to_date
문자열을 date로 변환
select
to_date('2023-03-30', 'yyyy-mm-dd');
5. to_char
숫자나 date를 문자열로 변환
select
to_char(now(), 'yyyy-mm-dd');
--2023-03-31--
'FM999,999,999' 포멧을 사용하여 숫자를 천 단위마다 컴마를 넣어 조회할 수 있다.
*포멧의 수치는 출력될 값의 예상 수치보다 높게 잡아야하며 .을 넣어서 소수점자리도 맞출 수 있다.
select
to_char(1000000, 'FM999,999,999');
--1,000,000--
6. coalesce
null값 치환
select
coalesce(name, '이름없음')
from
name_table
--name의 값이 null일 경우 '이름없음'으로 조회--
select
name ,
count(*)
from
name_table
group by
name;
--name 컬럼을 그룹화하여 name별 개수 count--
select
sum(A.cnt)
from
(select
name ,
count(*) as cnt
from
name_table
group by
lcl.jimok)as A;
--총합계--
select
round(avg(A.cnt))
from
(select
name ,
count(*) as cnt
from
name_table
group by
lcl.jimok)as A;
--평균 값을 반올림(2번째 인자로 소수점자리 지정 가능)--
select
max(A.cnt),
min(A.cnt)
from
(select
name ,
count(*) as cnt
from
name_table
group by
lcl.jimok)as A;
--최댓값과 최솟값--
select
name
from
name_table
--Tom Holland--
--Petter Parker--
--Spider-Man--
위와 같이 조회되는 값을 아래와 같이 조회 가능
select
array_to_string(array_agg(name), ',')
from
name_table
--Tom Holland,Petter Parker,Spider-Man--
-- 기본 문법
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE some_other_result
END
SELECT a,
CASE
WHEN a = 1 THEN 'one'
WHEN a = 2 THEN 'two'
ELSE 'other' AS label
END
FROM test;
-- CASE 표현식
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE some_other_result
END
SELECT a,
CASE a
WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'other'
END
FROM test;
-- 일반 CASE 문
SELECT customer_id,
CASE
WHEN (CUSTOMER_ID <= 100) THEN 'Premium'
WHEN (CUSTOMER_ID BETWEEN 100 AND 200) THEN 'Plus'
ELSE 'Normal'
END AS customer_class
FROM customer
-- CASE 표현식
SELECT customer_id,
CASE customer_id
WHEN 2 THEN 'Winner'
WHEN 5 THEN 'Second Place'
ELSE 'Normal'
END AS raffle_results
FROM customer
SELECT
SUM(CASE rental_rate
WHEN 0.99 THEN 1
ELSE 0
END) AS bargains,
SUM(CASE rental_rate
WHEN 2.99 THEN 1
ELSE 0
END) AS regular,
SUM(CASE rental_rate
WHEN 4.99 THEN 1
ELSE 0
END) AS premium
FROM film;
CASE 연습문제
--- 영화 테이블에서 등급별 영화 개수 구하기
SELECT
SUM(CASE rating
WHEN 'R' THEN 1
ELSE 0
END) AS r,
SUM(CASE rating
WHEN 'PG' THEN 1
ELSE 0
END) AS pg,
SUM(CASE rating
WHEN 'PG-13' THEN 1
ELSE 0
END) AS pg13
FROM film
COALESCE
더 큰 덩어리로 합치다라는 뜻
처음으로 NULL이 아닌 값을 만나면 그 값을 리턴하는 함수
따라서 NULL값을 가질 수 있는 데이터를 쿼리할 때 유용하다.
SELECT COALESCE (1, 2) -> 1
SELECT COALESCE (NULL, 2, 3) -> 2
-- 할인율 컬럼이 NULL이 가능한 경우
SELECT item, (price - COALESCE(discount, 0))
AS final FROM table
CAST
CAST 연산자는 데이터 유형을 바꿔준다.
-- CAST 함수 문법
SELECT CAST('5' AS INTEGER)
SELECT CAST(date AS TIMESTAMP) FROM table
-- PostgreSQL CAST 연산자 문법
SELECT '5'::INTEGER
-- inventory_id 컬럼을 정수에서 문자열로 바꾸고 길이 재기
SELECT CHAR_LENGTH(CAST(inventory_id AS VARCHAR))
FROM rental
NULLIF
NULLIF 함수는 두 개의 인자를 받고 양쪽이 같으면 NULL을 반환하고 아니면 첫 번째 인자를 반환하는 함수이다.
NULL 값이 에러의 원인이 되거나 원하지 않는 결과가 나오는 경우에 유용하게 사용될 수 있다.
A부서 총합과 B부서 총합을 나눠서 부서별 비율을 구하는 쿼리인데, B부서 인원이 0명이 되면 0으로 나누기 에러가 난다.
SELECT (
SUM(CASE WHEN department = 'A' THEN 1 ELSE 0 END) /
SUM(CASE WHEN department = 'B' THEN 1 ELSE 0 END)
) AS department_ratio
FROM depts
NULLIF를 사용 할 경우 B부서 인원이 0이 되면 NULL을 반환하기 때문에 NULL로 나누기를 하면 값이 NULL로 바뀌고 에러가 나지 않는다.
SELECT (
SUM(CASE WHEN department = 'A' THEN 1 ELSE 0 END) /
NULLIF(SUM(CASE WHEN department = 'B' THEN 1 ELSE 0 END), 0)
) AS department_ratio
FROM depts
VIEWS
View는 SQL에서 하나 이상의 테이블(또는 다른 뷰)에서 원하는 모든 데이터를 선택하여, 그들을 사용자 정의하여 나타낸 것 이다.
뷰는 저장된 쿼리이며 가상의 테이블로 접근할 수 있다.
뷰는 단순히 쿼리를 저장한 것이고 실제로 데이터를 물리적으로 저장하는 것은 아니다.
뷰를 통해 SQL 이용의 편의성을 높일 수 있다.
뷰를 통해 원본 데이터를 조회하는 대신 데이터의 일부분만 보여주게 할 수 있기 때문에 권한관리와 보안에도 장점이 있다.
-- VIEW 생성
CREATE VIEW view_name AS SELECT clause;
-- VIEW 생성 또는 수정
-- view_name이란 뷰가 이미 있으면 수정하고 없으면 생성한다.
CREATE OR REPLACE VIEW view_name AS SELECT clause;
-- VIEW 이름 변경
ALTER VIEW view_name RENAME to renamed_view_name
-- VIEW 삭제
DROP VIEW view_name;
CREATE VIEW customer_info AS
SELECT first_name, last_name, address
FROM customer
INNER JOIN address
ON customer.address_id = address.address_id
SELECT * FROM customer_info
-- SELECT에 district 컬럼 추가
CREATE OR REPLACE VIEW customer_info AS
SELECT first_name, last_name, address, district
FROM customer
INNER JOIN address
ON customer.address_id = address.address_id
특정 조건이 충족되었을 때 SQL코드를 실행하기 위해 CASE를 사용한다.
프로그래밍 언어에서 흔히 쓰이는 IF/ELSE 문과 비슷하다.
일반적인 CASE문과 CASE 표현식으로 쓸 수 있다. 두 방법 모두 결과는 같다.
-- 기본 문법
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE some_other_result
END
SELECT a,
CASE
WHEN a = 1 THEN 'one'
WHEN a = 2 THEN 'two'
ELSE 'other' AS label
END
FROM test;
-- CASE 표현식
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE some_other_result
END
SELECT a,
CASE a
WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'other'
END
FROM test;
-- 일반 CASE 문
SELECT customer_id,
CASE
WHEN (CUSTOMER_ID <= 100) THEN 'Premium'
WHEN (CUSTOMER_ID BETWEEN 100 AND 200) THEN 'Plus'
ELSE 'Normal'
END AS customer_class
FROM customer
-- CASE 표현식
SELECT customer_id,
CASE customer_id
WHEN 2 THEN 'Winner'
WHEN 5 THEN 'Second Place'
ELSE 'Normal'
END AS raffle_results
FROM customer
SELECT
SUM(CASE rental_rate
WHEN 0.99 THEN 1
ELSE 0
END) AS bargains,
SUM(CASE rental_rate
WHEN 2.99 THEN 1
ELSE 0
END) AS regular,
SUM(CASE rental_rate
WHEN 4.99 THEN 1
ELSE 0
END) AS premium
FROM film;
CASE 연습문제
--- 영화 테이블에서 등급별 영화 개수 구하기
SELECT
SUM(CASE rating
WHEN 'R' THEN 1
ELSE 0
END) AS r,
SUM(CASE rating
WHEN 'PG' THEN 1
ELSE 0
END) AS pg,
SUM(CASE rating
WHEN 'PG-13' THEN 1
ELSE 0
END) AS pg13
FROM film
COALESCE
더 큰 덩어리로 합치다라는 뜻
처음으로 NULL이 아닌 값을 만나면 그 값을 리턴하는 함수
따라서 NULL값을 가질 수 있는 데이터를 쿼리할 때 유용하다.
SELECT COALESCE (1, 2) -> 1
SELECT COALESCE (NULL, 2, 3) -> 2
-- 할인율 컬럼이 NULL이 가능한 경우
SELECT item, (price - COALESCE(discount, 0))
AS final FROM table
CAST
CAST 연산자는 데이터 유형을 바꿔준다.
-- CAST 함수 문법
SELECT CAST('5' AS INTEGER)
SELECT CAST(date AS TIMESTAMP) FROM table
-- PostgreSQL CAST 연산자 문법
SELECT '5'::INTEGER
-- inventory_id 컬럼을 정수에서 문자열로 바꾸고 길이 재기
SELECT CHAR_LENGTH(CAST(inventory_id AS VARCHAR))
FROM rental
NULLIF
NULLIF 함수는 두 개의 인자를 받고 양쪽이 같으면 NULL을 반환하고 아니면 첫 번째 인자를 반환하는 함수이다.
NULL 값이 에러의 원인이 되거나 원하지 않는 결과가 나오는 경우에 유용하게 사용될 수 있다.
A부서 총합과 B부서 총합을 나눠서 부서별 비율을 구하는 쿼리인데, B부서 인원이 0명이 되면 0으로 나누기 에러가 난다.
SELECT (
SUM(CASE WHEN department = 'A' THEN 1 ELSE 0 END) /
SUM(CASE WHEN department = 'B' THEN 1 ELSE 0 END)
) AS department_ratio
FROM depts
NULLIF를 사용 할 경우 B부서 인원이 0이 되면 NULL을 반환하기 때문에 NULL로 나누기를 하면 값이 NULL로 바뀌고 에러가 나지 않는다.
SELECT (
SUM(CASE WHEN department = 'A' THEN 1 ELSE 0 END) /
NULLIF(SUM(CASE WHEN department = 'B' THEN 1 ELSE 0 END), 0)
) AS department_ratio
FROM depts
VIEWS
View는 SQL에서 하나 이상의 테이블(또는 다른 뷰)에서 원하는 모든 데이터를 선택하여, 그들을 사용자 정의하여 나타낸 것 이다.
뷰는 저장된 쿼리이며 가상의 테이블로 접근할 수 있다.
뷰는 단순히 쿼리를 저장한 것이고 실제로 데이터를 물리적으로 저장하는 것은 아니다.
뷰를 통해 SQL 이용의 편의성을 높일 수 있다.
뷰를 통해 원본 데이터를 조회하는 대신 데이터의 일부분만 보여주게 할 수 있기 때문에 권한관리와 보안에도 장점이 있다.
-- VIEW 생성
CREATE VIEW view_name AS SELECT clause;
-- VIEW 생성 또는 수정
-- view_name이란 뷰가 이미 있으면 수정하고 없으면 생성한다.
CREATE OR REPLACE VIEW view_name AS SELECT clause;
-- VIEW 이름 변경
ALTER VIEW view_name RENAME to renamed_view_name
-- VIEW 삭제
DROP VIEW view_name;
CREATE VIEW customer_info AS
SELECT first_name, last_name, address
FROM customer
INNER JOIN address
ON customer.address_id = address.address_id
SELECT * FROM customer_info
-- SELECT에 district 컬럼 추가
CREATE OR REPLACE VIEW customer_info AS
SELECT first_name, last_name, address, district
FROM customer
INNER JOIN address
ON customer.address_id = address.address_id