[SQL 고득점 Kit] - JOIN

link : https://programmers.co.kr/learn/courses/30/parts/17046

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
INTAKE_CONDITION VARCHAR(N) FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_INTAKE VARCHAR(N) FALSE

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_OUTCOME VARCHAR(N) FALSE

1. 없어진 기록 찾기

Problem

천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요.

예시

예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면

ANIMAL_INS
ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A352713 Cat 2017-04-13 16:29:00 Normal Gia Spayed Female
A350375 Cat 2017-03-06 15:01:00 Normal Meo Neutered Male
ANIMAL_OUTS
ANIMAL_ID ANIMAL_TYPE DATETIME NAME SEX_UPON_OUTCOME
A349733 Dog 2017-09-27 19:09:00 Allie Spayed Female
A352713 Cat 2017-04-25 12:25:00 Gia Spayed Female
A349990 Cat 2018-02-02 14:18:00 Spice Spayed Female

ANIMAL_OUTS 테이블에서

  • Allie의 ID는 ANIMAL_INS에 없으므로, Allie의 데이터는 유실되었습니다.
  • Gia의 ID는 ANIMAL_INS에 있으므로, Gia의 데이터는 유실되지 않았습니다.
  • Spice의 ID는 ANIMAL_INS에 없으므로, Spice의 데이터는 유실되었습니다.

따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A349733 Allie
A349990 Spice

code

select o.animal_id, o.name
from animal_ins as i right join animal_outs as o 
                     on i.animal_id = o.animal_id
where i.animal_id is null
order by o.animal_id;

2. 있었는데요 없었습니다

Problem

관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.

예시

예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면

ANIMAL_INS
ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A350276 Cat 2017-08-13 13:50:00 Normal Jewel Spayed Female
A381217 Dog 2017-07-08 09:41:00 Sick Cherokee Neutered Male
ANIMAL_OUTS
ANIMAL_ID ANIMAL_TYPE DATETIME NAME SEX_UPON_OUTCOME
A350276 Cat 2018-01-28 17:51:00 Jewel Spayed Female
A381217 Dog 2017-06-09 18:51:00 Cherokee Neutered Male

SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A381217 Cherokee

code

select i.animal_id, i.name
from animal_ins as i , animal_outs as o
where i.ANIMAL_ID = o.ANIMAL_ID and
      o.datetime < i.datetime
order by i.datetime

3. 오랜 기간 보호한 동물(1)

Problem

아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.

예시

예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면

ANIMAL_INS
ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A354597 Cat 2014-05-02 12:16:00 Normal Ariel Spayed Female
A373687 Dog 2014-03-20 12:31:00 Normal Rosie Spayed Female
A412697 Dog 2016-01-03 16:25:00 Normal Jackie Neutered Male
A413789 Dog 2016-04-19 13:28:00 Normal Benji Spayed Female
A414198 Dog 2015-01-29 15:01:00 Normal Shelly Spayed Female
ANIMAL_OUTS
ANIMAL_ID ANIMAL_TYPE DATETIME NAME SEX_UPON_OUTCOME
A354597 Cat 2014-05-02 12:16:00 Ariel Spayed Female
A373687 Dog 2014-03-20 12:31:00 Rosie Spayed Female

SQL문을 실행하면 다음과 같이 나와야 합니다.

NAME DATETIME
Shelly 2015-01-29 15:01:00
Jackie 2016-01-03 16:25:00
Benji 2016-04-19 13:28:00

※ 입양을 가지 못한 동물이 3마리 이상인 경우만 입력으로 주어집니다.

code

select name, datetime
from animal_ins
where animal_id not in (select animal_id
                        from animal_outs)
order by datetime
limit 3

4. 보호소에서 중성화한 동물

Problem

보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다. 보호소에 들어올 당시에는 중성화1되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물의 아이디와 생물 종, 이름을 조회하는 아이디 순으로 조회하는 SQL 문을 작성해주세요.

예시

예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면

ANIMAL_INS
ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A367438 Dog 2015-09-10 16:01:00 Normal Cookie Spayed Female
A382192 Dog 2015-03-13 13:14:00 Normal Maxwell 2 Intact Male
A405494 Dog 2014-05-16 14:17:00 Normal Kaila Spayed Female
A410330 Dog 2016-09-11 14:09:00 Sick Chewy Intact Female
ANIMAL_OUTS
ANIMAL_ID ANIMAL_TYPE DATETIME NAME SEX_UPON_OUTCOME
A367438 Dog 2015-09-12 13:30:00 Cookie Spayed Female
A382192 Dog 2015-03-16 13:46:00 Maxwell 2 Neutered Male
A405494 Dog 2014-05-20 11:44:00 Kaila Spayed Female
A410330 Dog 2016-09-13 13:46:00 Chewy Spayed Female
  • Cookie는 보호소에 들어올 당시에 이미 중성화되어있었습니다.
  • Maxwell 2는 보호소에 들어온 후 중성화되었습니다.
  • Kaila는 보호소에 들어올 당시에 이미 중성화되어있었습니다.
  • Chewy는 보호소에 들어온 후 중성화되었습니다.

따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID ANIMAL_TYPE NAME
A382192 Dog Maxwell 2
A410330 Dog Chewy

code

select i.animal_id, i.animal_type, i.name
from animal_ins as i, animal_outs as o
where i.animal_id = o.animal_id and
      i.sex_upon_intake like 'Intact%' and
      (o.sex_upon_outcome like 'Neutered%' or 
       o.sex_upon_outcome like 'Spayed%')

'Database > programmers' 카테고리의 다른 글

[SQL 고득점 Kit] - IS NULL  (0) 2019.10.20
[SQL 고득점 Kit] - GROUP BY  (0) 2019.10.20
[SQL 고득점 Kit] - SUM, MAX, MIN  (0) 2019.10.20
[SQL 고득점 Kit] - SELECT  (0) 2019.10.20

[SQL 고득점 Kit] - GROUP BY

link : https://programmers.co.kr/learn/courses/30/parts/17044

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
INTAKE_CONDITION VARCHAR(N) FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_INTAKE VARCHAR(N) FALSE

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_OUTCOME VARCHAR(N) FALSE

1. 고양이와 개는 몇 마리 있을까

Problem

동물 보호소에 들어온 동물 중 고양이와 개가 각각 몇 마리인지 조회하는 SQL문을 작성해주세요. 이때 고양이가 개보다 먼저 조회해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A373219 Cat 2014-07-29 11:43:00 Normal Ella Spayed Female
A377750 Dog 2017-10-25 17:17:00 Normal Lucy Spayed Female
A354540 Cat 2014-12-11 11:48:00 Normal Tux Neutered Male

고양이는 2마리, 개는 1마리 들어왔습니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_TYPE count
Cat 2
Dog 1

code

select animal_type, count(animal_type) as count
from animal_ins
group by animal_type
order by animal_type

2. 동명 동물 수 찾기

Problem

동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요. 이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A396810 Dog 2016-08-22 16:13:00 Injured Raven Spayed Female
A377750 Dog 2017-10-25 17:17:00 Normal Lucy Spayed Female
A355688 Dog 2014-01-26 13:48:00 Normal Shadow Neutered Male
A399421 Dog 2015-08-25 14:08:00 Normal Lucy Spayed Female
A400680 Dog 2017-06-17 13:29:00 Normal Lucy Spayed Female
A410668 Cat 2015-11-19 13:41:00 Normal Raven Spayed Female
  • Raven 이름은 2번 쓰였습니다.
  • Lucy 이름은 3번 쓰였습니다
  • Shadow 이름은 1번 쓰였습니다.

따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

NAME COUNT
Lucy 3
Raven 2

code

select name, count(name) as count
from animal_ins
group by name
having count != 1 and count != 0;

3. 입양 시각 구하기(1)

problem

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 9시부터 19시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

예시

SQL문을 실행하면 다음과 같이 나와야 합니다.

HOUR COUNT
9 1
10 2
11 13
12 10
13 14
14 9
15 7
16 10
17 12
18 16
19 2

code

select hour(datetime) as HOUR, count(hour(datetime)) as COUNT
from animal_outs
group by hour
having hour between 9 and 19

4. 입양 시각 구하기(2)

Problem

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

예시

SQL문을 실행하면 다음과 같이 나와야 합니다.

HOUR COUNT
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 3
8 1
9 1
10 2
11 13
12 10
13 14
14 9
15 7
16 10
17 12
18 16
19 2
20 0
21 0
22 0
23 0

code

set @hour = -1;

select (@hour := @hour +1) as HOUR,( select count(*)
                                     from ANIMAL_OUTS
                                     where HOUR(DATETIME) = @hour) as COUNT
from animal_outs
where @hour < 23;

'Database > programmers' 카테고리의 다른 글

[SQL 고득점 Kit] - IS NULL  (0) 2019.10.20
[SQL 고득점 Kit] - JOIN  (0) 2019.10.20
[SQL 고득점 Kit] - SUM, MAX, MIN  (0) 2019.10.20
[SQL 고득점 Kit] - SELECT  (0) 2019.10.20

[SQL 고득점 Kit] - SUM, MAX, MIN

link : https://programmers.co.kr/learn/courses/30/parts/17043

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
INTAKE_CONDITION VARCHAR(N) FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_INTAKE VARCHAR(N) FALSE

1. 최댓값 구하기

problem

가장 최근에 들어온 동물은 언제 들어왔는지 조회하는 SQL 문을 작성해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A399552 Dog 2013-10-14 15:38:00 Normal Jack Neutered Male
A379998 Dog 2013-10-23 11:42:00 Normal Disciple Intact Male
A370852 Dog 2013-11-03 15:04:00 Normal Katie Spayed Female
A403564 Dog 2013-11-18 17:03:00 Normal Anna Spayed Female

가장 늦게 들어온 동물은 Anna이고, Anna는 2013-11-18 17:03:00에 들어왔습니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

시간
2013-11-18 17:03:00

code

select max(datetime) as 시간
from animal_ins;

2. 최솟값 구하기

problem

동물 보호소에 가장 먼저 들어온 동물은 언제 들어왔는지 조회하는 SQL 문을 작성해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A399552 Dog 2013-10-14 15:38:00 Normal Jack Neutered Male
A379998 Dog 2013-10-23 11:42:00 Normal Disciple Intact Male
A370852 Dog 2013-11-03 15:04:00 Normal Katie Spayed Female
A403564 Dog 2013-11-18 17:03:00 Normal Anna Spayed Female

가장 먼저 들어온 동물은 Jack이고, Jack은 2013-10-14 15:38:00에 들어왔습니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

시간
2013-10-14 15:38:00

code

SELECT min(datetime) as 시간
from animal_ins;

3. 동물의 수 구하기

problem

동물 보호소에 동물이 몇 마리 들어왔는지 조회하는 SQL 문을 작성해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A399552 Dog 2013-10-14 15:38:00 Normal Jack Neutered Male
A379998 Dog 2013-10-23 11:42:00 Normal Disciple Intact Male
A370852 Dog 2013-11-03 15:04:00 Normal Katie Spayed Female
A403564 Dog 2013-11-18 17:03:00 Normal Anna Spayed Female

동물 보호소에 들어온 동물은 4마리입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

count
4

※ 컬럼 이름(위 예제에서는 count)은 일치하지 않아도 됩니다.

code

select count(*)
from animal_ins;

4. 중복 제거하기

problem

동물 보호소에 들어온 동물의 이름은 몇 개인지 조회하는 SQL 문을 작성해주세요. 이때 이름이 NULL인 경우는 집계하지 않으며 중복되는 이름은 하나로 칩니다.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A562649 Dog 2014-03-20 18:06:00 Sick NULL Spayed Female
A412626 Dog 2016-03-13 11:17:00 Normal *Sam Neutered Male
A563492 Dog 2014-10-24 14:45:00 Normal *Sam Neutered Male
A513956 Dog 2017-06-14 11:54:00 Normal *Sweetie Spayed Female

보호소에 들어온 동물의 이름은 NULL(없음), *Sam, *Sam, *Sweetie입니다. 이 중 NULL과 중복되는 이름을 고려하면, 보호소에 들어온 동물 이름의 수는 2입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

count
2

※ 컬럼 이름(위 예제에서는 count)은 일치하지 않아도 됩니다.

code

select count (distinct(name))
from animal_ins;

'Database > programmers' 카테고리의 다른 글

[SQL 고득점 Kit] - IS NULL  (0) 2019.10.20
[SQL 고득점 Kit] - JOIN  (0) 2019.10.20
[SQL 고득점 Kit] - GROUP BY  (0) 2019.10.20
[SQL 고득점 Kit] - SELECT  (0) 2019.10.20

[SQL 고득점 Kit] - SELECT

link : https://programmers.co.kr/learn/courses/30/parts/17042

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
INTAKE_CONDITION VARCHAR(N) FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_INTAKE VARCHAR(N) FALSE

1. 모든 레코드 조회하기

problem

동물 보호소에 들어온 모든 동물의 정보를 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A349996 Cat 2018-01-22 14:32:00 Normal Sugar Neutered Male
A350276 Cat 2017-08-13 13:50:00 Normal Jewel Spayed Female
A350375 Cat 2017-03-06 15:01:00 Normal Meo Neutered Male
A352555 Dog 2014-08-08 04:20:00 Normal Harley Spayed Female

..이하 생략

code

select *
from Animal_Ins

2. 역순 정렬하기

problem

동물 보호소에 들어온 모든 동물의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 ANIMAL_ID 역순으로 보여주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

NAME DATETIME
Rocky 2016-06-07 09:17:00
Shelly 2015-01-29 15:01:00
Benji 2016-04-19 13:28:00
Jackie 2016-01-03 16:25:00
*Sam 2016-03-13 11:17:00

..이하 생략

code

select name, datetime
from animal_ins
order by animal_id desc;

3. 아픈 동물 찾기

problem

동물 보호소에 들어온 동물 중 아픈 동물1의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A365172 Dog 2014-08-26 12:53:00 Normal Diablo Neutered Male
A367012 Dog 2015-09-16 09:06:00 Sick Miller Neutered Male
A365302 Dog 2017-01-08 16:34:00 Aged Minnie Spayed Female
A381217 Dog 2017-07-08 09:41:00 Sick Cherokee Neutered Male

이 중 아픈 동물은 Miller와 Cherokee입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A367012 Miller
A381217 Cherokee

code

select animal_id, name
from animal_ins
where intake_condition = 'Sick';

4. 어린 동물 찾기

problem

동물 보호소에 들어온 동물 중 젊은 동물의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.

젊은 동물은 INTAKE_CONDITION이 Aged가 아닌 경우를 뜻함

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A365172 Dog 2014-08-26 12:53:00 Normal Diablo Neutered Male
A367012 Dog 2015-09-16 09:06:00 Sick Miller Neutered Male
A365302 Dog 2017-01-08 16:34:00 Aged Minnie Spayed Female
A381217 Dog 2017-07-08 09:41:00 Sick Cherokee Neutered Male

이 중 젊은 동물은 Diablo, Miller, Cherokee입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A365172 Diablo
A367012 Miller
A381217 Cherokee

code

select animal_id, name
from animal_ins
where intake_condition != 'Aged'
order by animal_id;

5. 동물의 아이디와 이름

problem

동물 보호소에 들어온 모든 동물의 아이디와 이름을 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

ANIMAL_ID NAME
A349996 Sugar
A350276 Jewel
A350375 Meo
A352555 Harley
A352713 Gia
A352872 Peanutbutter
A353259 Bj

..이하 생략

code

select animal_id, name
from animal_ins
order by animal_id;

6. 여러 기준으로 정렬하기

problem

동물 보호소에 들어온 모든 동물의 아이디와 이름, 보호 시작일을 이름 순으로 조회하는 SQL문을 작성해주세요. 단, 이름이 같은 동물 중에서는 보호를 나중에 시작한 동물을 먼저 보여줘야 합니다.

예시

예를 들어, ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A349996 Cat 2018-01-22 14:32:00 Normal Sugar Neutered Male
A350276 Cat 2017-08-13 13:50:00 Normal Jewel Spayed Female
A396810 Dog 2016-08-22 16:13:00 Injured Raven Spayed Female
A410668 Cat 2015-11-19 13:41:00 Normal Raven Spayed Female
  1. 이름을 사전 순으로 정렬하면 다음과 같으며, 'Jewel', 'Raven', 'Sugar'
  2. 'Raven'이라는 이름을 가진 개와 고양이가 있으므로, 이 중에서는 보호를 나중에 시작한 고양이를 먼저 조회합니다.

따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME DATETIME
A350276 Jewel 2017-08-13 13:50:00
A396810 Raven 2016-08-22 16:13:00
A410668 Raven 2015-11-19 13:41:00
A349996 Sugar 2018-01-22 14:32:00

code

select animal_id, name, datetime
from animal_ins
order by name, datetime desc

7. 상위 n개 레코드

problem

동물 보호소에 가장 먼저 들어온 동물의 이름을 조회하는 SQL 문을 작성해주세요.

예시

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A399552 Dog 2013-10-14 15:38:00 Normal Jack Neutered Male
A379998 Dog 2013-10-23 11:42:00 Normal Disciple Intact Male
A370852 Dog 2013-11-03 15:04:00 Normal Katie Spayed Female
A403564 Dog 2013-11-18 17:03:00 Normal Anna Spayed Female

이 중 가장 보호소에 먼저 들어온 동물은 Jack입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

NAME
Jack

※ 보호소에 가장 먼저 들어온 동물은 한 마리인 경우만 테스트 케이스로 주어집니다.

code

select name
from animal_ins
order by datetime
limit 1;

'Database > programmers' 카테고리의 다른 글

[SQL 고득점 Kit] - IS NULL  (0) 2019.10.20
[SQL 고득점 Kit] - JOIN  (0) 2019.10.20
[SQL 고득점 Kit] - GROUP BY  (0) 2019.10.20
[SQL 고득점 Kit] - SUM, MAX, MIN  (0) 2019.10.20

[BOJ] 16927. 배열돌리기2 - Simulation

제출일 : 2019-10-20

문제 풀이 시간 : 15M

난이도 : ★

Problem

link : https://www.acmicpc.net/problem/16927

Input

첫째 줄에 배열의 크기 N, M과 수행해야 하는 회전의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

Output

입력으로 주어진 배열을 R번 회전시킨 결과를 출력한다.

Constraints

  • 2 ≤ N, M ≤ 300
  • 1 ≤ R ≤ 10^9
  • min(N, M) mod 2 = 0
  • 1 ≤ Aij ≤ 10^8

Solution & Inpression

시뮬레이션 문제

배열돌리기1 문제에서 회전수 R이 커진 문제

최적화 문제로 각각의 사각형마다 회전후 제자리가 되는 부분을 제외하고 돌리는 방법으로 문제를 해결하였다.

그래도 메모리와 시간은 폭발하는데.......

쉽지 않다....

Code

언어 : JAVA

메모리 : 105,660 kb

실행시간 : 1,388 ms

import java.util.Scanner;

public class Main {
    static int N, M, SR, S;
    static int[][] matrix, copy;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        N = sc.nextInt(); // 배열의 크기 N*M
        M = sc.nextInt();
        SR = sc.nextInt(); // 회전 수 R

        // min(N, M) mod 2 = 0
        S = Math.min(N, M) / 2; // 1회전에서 돌려야하는 사각형의 개수

        matrix = new int[N][M];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                matrix[i][j] = sc.nextInt();
            }
        }
        spin();
        print();
    }

    private static void print() {
        for (int[] is : matrix) {
            for (int i : is) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }

    static void spin() {
        for (int s = 0; s < S; s++) {
            int T = s;
            int B = N - 1 - s;
            int R = M - 1 - s;
            int L = s;
            int r = SR % (2 * (R-L+1) + 2 * (B-T+1) - 4);
            //System.out.println(r);
            while (r-- != 0) {
                int tmp = matrix[s][s];
                for (int i = L; i < R; i++)
                    matrix[T][i] = matrix[T][i + 1];
                for (int i = T; i < B; i++)
                    matrix[i][R] = matrix[i + 1][R];
                for (int i = R; i > L; i--)
                    matrix[B][i] = matrix[B][i - 1];
                for (int i = B; i > T; i--)
                    matrix[i][L] = matrix[i - 1][L];
                matrix[T + 1][L] = tmp;

            }
        }
    }
}

[BOJ] 16926. 배열돌리기1 - Simulation

제출일 : 2019-10-20

문제 풀이 시간 : 3H

난이도 : ★★★

Problem

link : https://www.acmicpc.net/problem/16926

Input

첫째 줄에 배열의 크기 N, M과 수행해야 하는 회전의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

Output

입력으로 주어진 배열을 R번 회전시킨 결과를 출력한다.

Constraints

  • 2 ≤ N, M ≤ 300
  • 1 ≤ R ≤ 1,000
  • min(N, M) mod 2 = 0
  • 1 ≤ Aij ≤ 10^8

Solution & Inpression

시뮬레이션 문제

시뮬레이션은 어렵다.

문제에 주어진대로 천천히 따라 코딩을 하면 되지만 2차원 배열의 인덱스 조작이 햇갈린다..

Code

언어 : JAVA

메모리 : 105,112 kb

실행시간 : 1,464 ms

import java.util.Scanner;

public class Main {
    static int N, M, R, S;
    static int[][] matrix, copy;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        N = sc.nextInt(); // 배열의 크기 N*M
        M = sc.nextInt();
        R = sc.nextInt(); // 회전 수 R

        // min(N, M) mod 2 = 0
        S = Math.min(N, M) / 2; // 1회전에서 돌려야하는 사각형의 개수

        matrix = new int[N][M];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                matrix[i][j] = sc.nextInt();
            }
        }
        for (int i = 0; i < R; i++) {
            spin();
        }

        print();
    }

    private static void print() {
        for (int[] is : matrix) {
            for (int i : is) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }

    static void spin() {
        for (int s = 0; s < S; s++) {
            int T = s;
            int B = N - 1 - s;
            int R = M - 1 - s;
            int L = s;

            int tmp = matrix[s][s];
            for (int i = L; i < R; i++)    matrix[T][i] = matrix[T][i + 1];
            for (int i = T; i < B; i++)    matrix[i][R] = matrix[i + 1][R];
            for (int i = R; i > L; i--)    matrix[B][i] = matrix[B][i - 1];
            for (int i = B; i > T; i--)    matrix[i][L] = matrix[i - 1][L];
            matrix[T + 1][L] = tmp;

        }
    }
}

[BOJ] 15685. 드래곤커브 - Simulation

제출일 : 2019-10-19

문제 풀이 시간 : 3H

난이도 : ★★★★

Problem

link : https://www.acmicpc.net/problem/15685

Input

첫째 줄에 드래곤 커브의 개수 N(1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 드래곤 커브의 정보가 주어진다. 드래곤 커브의 정보는 네 정수 x, y, d, g로 이루어져 있다. x와 y는 드래곤 커브의 시작 점, d는 시작 방향, g는 세대이다. (0 ≤ x, y ≤ 100, 0 ≤ d ≤ 3, 0 ≤ g ≤ 10)

입력으로 주어지는 드래곤 커브는 격자 밖으로 벗어나지 않는다. 드래곤 커브는 서로 겹칠 수 있다.

방향은 0, 1, 2, 3 중 하나이고, 다음을 의미한다.

  • 0: x좌표가 증가하는 방향 (→)
  • 1: y좌표가 감소하는 방향 (↑)
  • 2: x좌표가 감소하는 방향 (←)
  • 3: y좌표가 증가하는 방향 (↓)

Output

첫째 줄에 크기가 1×1인 정사각형의 네 꼭짓점이 모두 드래곤 커브의 일부인 것의 개수를 출력한다.

Example

input

3
3 3 0 1
4 2 1 3
4 2 2 1

output

4

Solution & Inpression

시뮬레이션 문제

시뮬레이션은 역시 어렵다.

90도 시계방향으로 회전하는 것을 벡터의 회전이라 생각했고

  • x' = xcos(90)-ysin(90)
  • y' = xsin(90)+ycos(90)

라는 공식에 의해 새로운 좌표는 x'=-y, y'=x가 된다.

또 문제를 풀때 기억해야 할 부분은 끝에 점이 붙는것과 붙은 선분은 시작점에서부터 먼점에 있는 선분부터 시작이라는것이다.

햇갈려....

Code

언어 : JAVA

메모리 : 14,984 kb

실행시간 : 124 ms

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    static int N;
    static ArrayList<Dragon> list;
    static int[][] map = new int[101][101];

    static class Dragon {
        ArrayList<int[]> point;

        public Dragon(int[] p, int dir, int g) {
            this.point = new ArrayList<>();
            this.point.add(p);
            if (dir == 0)
                this.point.add(new int[] { p[0], p[1] + 1 });
            else if (dir == 1)
                this.point.add(new int[] { p[0] - 1, p[1] });
            else if (dir == 2)
                this.point.add(new int[] { p[0], p[1] - 1 });
            else
                this.point.add(new int[] { p[0] + 1, p[1] });
            while (g-- != 0) {
                spin();
            }
        }

        void spin() {

            // x' = xcos(90)-ysin(90)
            // y' = xsin(90)+ycos(90)

            // sin(90) = 1;
            // cos(90) = 0;

            // x' = -y
            // y' = x
            int size = point.size();
            for (int i = size - 1; i > 0; i--) {
                int[] cen = point.get(i - 1);
                int[] cur = point.get(i);
                int[] end = point.get(point.size() - 1);

                int tx = cur[0] - cen[0];
                int ty = cur[1] - cen[1];

                int nx = end[0] - ty;
                int ny = end[1] + tx;

                point.add(new int[] { nx, ny });
            }

        }

    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        N = sc.nextInt(); // 드래곤 커브의 개수 N(1 ≤ N ≤ 20)
        list = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            int c = sc.nextInt();
            int r = sc.nextInt();
            list.add(new Dragon(new int[] { r, c }, sc.nextInt(), sc.nextInt()));
        }

        for (int i = 0; i < N; i++) {
            ArrayList<int[]> l = list.get(i).point;
            for (int j = 0; j < l.size(); j++) {
                map[l.get(j)[0]][l.get(j)[1]] = 1;
            }
        }

        int ans = 0;
        for (int i = 0; i < 101; i++) {
            for (int j = 0; j < 101; j++) {
                if (map[i][j] == 1)
                    if (check(i, j))
                        ans++;
            }
        }
        System.out.println(ans);
    }

    private static boolean check(int i, int j) {
        int[] dr = { 1, 0, 1 };
        int[] dc = { 0, 1, 1 };

        for (int k = 0; k < 3; k++) {
            int r = i + dr[k];
            int c = j + dc[k];
            if (!range(r, c)) {
                return false;
            } else {
                if (map[r][c] == 0) {
                    return false;
                }
            }
        }
        return true;
    }

    private static boolean range(int r, int c) {
        if (0 <= r && r < 101 && 0 <= c && c < 101)
            return true;
        return false;
    }
}

PowerSet (부분집합)

부분집합을 구하는 3가지 방법

1. 조합을 이용한 방법

n개중 r개를 선택하는 조합알고리즘을 이용하여

for문으로 r을 0부터 n까지 선택한 결과.

2. 재귀함수를 이용하는 방법

  1. 현재 인덱스를 포함하는 경우
  2. 현재 인덱스를 포함하지 않는 경우

위 2가지 경우를 재귀호출하여 인덱스가 모든 배열을 순회했을때 결과.

3. 비트연산을 이용하는 방법

집합의 개수가 4개라면 0000~1111을 순회하며 해당 비트가 1인지를 확인하는 방법

code

public class Main {
    static boolean[] visit;

    public static void main(String[] args) {
        int N = 4;
        visit = new boolean[N];

        for (int i = 0; i <= N; i++) {
            combination(N, i, 0, 0); //N개중 i개를 뽑은 모든경우
        }
        System.out.println("----------------------");

        powerSet(visit.length, 0);
        System.out.println("----------------------");

        bit(N);

    }
    //조합
    private static void combination(int n, int r, int depth, int start) {
        if (depth == r) {
            // print
            for (int i = 0; i < visit.length; i++) {
                if (visit[i])
                    System.out.print(i + " ");
            }
            System.out.println();
            return;
        }
        for (int i = start; i < n; i++) {
            if (visit[i] == false) {
                visit[i] = true;
                combination(n, r, depth + 1, i);
                visit[i] = false;
            }
        }
    }

    // 재귀호출을 이용한 방법
    static void powerSet(int n, int idx) {
        if (idx == n) {
            // print
            for (int i = 0; i < visit.length; i++) {
                if (visit[i])
                    System.out.print(i + " ");
            }
            System.out.println();
            return;
        }

        // 현재 인덱스를 포함하는 경우
        visit[idx] = true;
        powerSet(n, idx + 1);

        // 현재 인덱스를 포함하지 않는 경우
        visit[idx] = false;
        powerSet(n, idx + 1);
    }

    // Bit연산을 이용하는 방법
    static void bit(int n) {
        for (int i = 0; i < 1 << n; i++) {// n이 4일때, 0000~1111
            for (int j = 0; j < n; j++) { // 0001, 0010, 0100, 1000
                // 각 자리 논리합(AND)의 결과가 0이 아닐경우
                // (해당bit를 포함함을 의미)
                if ((i & 1 << j) != 0)
                    System.out.print(j + " ");
            }
            System.out.println();
        }
    }

}