🌍ansi 표준, ansi sql
미국국가표준협회(ansi)가 정한 sql 표준이다.

🤔왜?

호환성
mysql에서 작성한 구문이 sqlserver, oracle에서 돌아가야 한다.

주요 ansi 함수

집계 함수
count()
sum()
avg()
max()/min()

-- 집계함수
select avg(salary) as avg_salary
from new_employees;

-- round 반올림 소수점 n 자리까지
select round(avg(salary),2) as avg_salary
from new_employees;

select count(*)as d_count
from new_employees;

-- select count(*)as d_count, name
-- from new_employees;
-- 버전에 따라 안되는 쿼리들이 있다. (논리적, 물리적)

샘플데이터
사원 5명의 평균급여
평균값을 소수점 2번째에서 반올림(round)했다.
전체 사원의 숫자를 셈(count)했다.


문자열 함수
concat()
upper()/lower()
trim()
substring()

-- 문자열 결합, 대문자 처리

select concat('Mr/Ms ', name) as formal_name
from new_employees;

select concat(upper('Mr/Ms '), name) as formal_name
from new_employees;

select concat(lower('Mr/Ms '), name) as formal_name
from new_employees;

-- 문자열
-- 문자열 추출
select*, substring(name, 1, 2)
from new_employees;

-- 문자열 추출, 문자열 결합
select*, concat( substring(name, 1, 2), '*') as formal_name
from new_employees;

name 칼럼의 값에 임의의 문자열을 결합(concat)했다.
name 칼럼에서 1~2번째까지 글자를 추출하고 임의의 문자열을 결합했다.


논리 조건 함수
case
coalesce()

-- 논리 조건
-- case when then else
select*,
	case when employees.gender = 'M' then '남자' else '여자' end as formal_gender
from employees.employees;
-- 다른 db의 table을 불러올 수 있다.

조건문(case)을 통해 gender 칼럼의 값을 한글로 보여주는 새 칼럼을 만든 모습


날짜
current_date
current_time
current_timestamp
extrat()

-- 날짜 시간
select current_date as today;
select current_time as now;

-- 날짜 차이 계산
-- datediff 두 날짜 차이 계산
select*,
	datediff(current_date, hire_date)/365 as years_working
from new_employees;

-- floor 소수점 버림
select*,
	floor(datediff(current_date, hire_date)/365) as years_working
from new_employees;

select 문을 통해 오늘 날짜(current_date)를 나타냈다.
current_date와 hire_date의 차이(datddiff)를 구하고, 그 값을 연도로 표시한뒤, 소수점 값을 버렸다(floor).


형변환
cast()

-- 형 변환
-- dicimal => 형변환 => 문자열 (char) 고정길이
select*, cast( floor(salary) as char) as salary_text
from new_employees;

select*, concat( cast( floor(salary) as char),'원' ) as salary_text
from new_employees;

select*, concat( cast( floor(salary) as char),'원' ) as formal_salary
from new_employees;

select*, concat( substring(cast( floor(salary) as char),1,3),'만원' ) as salary_text
from new_employees;

salay 칼럼의 값에서 소수점을 버리고(floor), 문자열(char)로 형변환(cast)했다. 그 다음 1~3번째 글자만 추출(substring)하고, 임의의 문자열을 결합(concat)했다.



👍sql 함수를 잘 조합해서 정제된 정보를 만들 수 있다면
☕java 단의 코딩이 간결해질 수 있다.


⭐ join
두 개 이상의 테이블에서 데이터를 결합

크게 2가지로 구분
inner join, outer join

outer join 은 다시 2가지로 구분
outer join (left join, right join)

⭐ inner join
on 조건 없이 사용할때 inner join 을 cross join이라고 부른다.
즉, cross join은 inner join의 한 형태다. 잘 쓰이지는 않는다.

inner join을 쓸때
on이라는 조건을 설정한다.
on tb_student.no = tb_grade.no


이렇게 매번 칼럼명을 작성하는 것은 불편하다.
이때는 별칭을 사용하면 된다.

 

👍대부분의 경우 join(inner join) 과 left join 만을 사용한다.

 

💀 join 활용시 주의사항

1.on 지정 필수
2.외래키와 기본키를 매핑해야 무결성 보장
3.성능저하를 고려해 인덱스 생성 권장

-- inner join 사용법
select*
from tb_grade;
select*
from tb_student;

select*
from tb_student
join tb_grade;
-- on 조건이 없어서 크로스 조인이 됐고 레코드가 30개나 뽑혀버렸다.

select*
from tb_student
inner join tb_grade
on tb_student.grade = tb_grade.grade;
-- 2개 테이블을 결합해 의미있는 결과값을 뽑아냈다.

select tb_student.no, tb_student.name, tb_student.grade, tb_grade.score
from tb_student
inner join tb_grade
on tb_student.grade = tb_grade.grade;
-- 중복 칼럼을 없애고 필요한 칼럼만을 취사선택했다.

select s.no, s.name, s.grade, g.score
from tb_student as s
inner join tb_grade as g
on s.grade = g.grade;
-- 별칭을 사용해서 코드량을 줄였다.

조건(on)을 설정하지 않으면 무의미한 데이터 범벅이 나온다.
올바른 조건을 입력하면 간결하고 의미있는 결과값을 뽑아낼 수 있다.


⭐ outer join
아우터조인에는 2가지 left join 과 right join 이 있다.

left join (left outer join)
left join은 조건에 맞지 않는 데이터도 포함한다.

right join (right outer join)
right join은 조건에 맞지 않는 데이터가 없으면 왼쪽 테이블은 null 처리

-- outer join 연습
use shcool;

-- 레프트 조인
select s.no, s.name, s.grade, g.score
from tb_student as s
left join tb_grade as g on s.grade = g.grade;

-- 라이트 조인
select s.no, s.name, s.grade, g.score
from tb_student as s
right join tb_grade as g on s.grade = g.grade;

left join 결과창
right join 결과창


⭐union
두 테이블의 모든 데이터를 포함
조건이 맞지 않은 경우 null 처리

how?
left join과 right join을 union으로 결합

use school;

select s.no, s.name, s.gender, g.score, g.grade
from tb_student as s
left join tb_grade as g
on s.grade = g.grade
union
select s.no, s.name, s.gender, g.score, g.grade
from tb_student as s
right join tb_grade as g
on s.grade = g.grade
where s.grade is null;
-- 유니온 결과값 기본

select s.no, s.name, s.gender, g.score, g.grade
from tb_student as s
left join tb_grade as g
on s.grade = g.grade
union
select s.no, s.name, s.gender, g.score, g.grade
from tb_student as s
right join tb_grade as g
on s.grade = g.grade
where s.grade is not null;
-- 유니온 결과값 null값 제거

union 결과창
null값이 나오지 않도록 설정한 결과창



⭐Java.time 패키지
시간과 관련된 클래스들을 모아뒀다.

java1.1때 만들어진 Date, Calendar 클래스는
여러 문제점을 안고 있었다.

이에 따라 java8에서 새로운 클래스들이 만들어졌다.

java.time의 주요 클래스


LocalDate 날짜만

LocalTime 시간만
LocalDateTime 날짜 + 시간
Period 날짜 간격
Duration 시간 간격

 

예제)

구버전 시간 클래스

Date now = new Date();
System.out.println("현재시간" + now);

//Calendar cal = new Calendar(); //new 못때리게 개발자가 막아놨다.
Calendar cal = Calendar.getInstance();
cal.set(2025,4,14); //0부터 시작(4= 5월)
System.out.println("설정날짜"+ cal.getTime());

 

예제2)

특정날짜의 요일 확인

//2000년 5월13일이 무슨 요일일까?
LocalDate birthday = LocalDate.of(2000, 5, 13);
System.out.println("00-05-13요일"+birthday.getDayOfWeek());

 

예제3)

100일 후 날짜 계산

//현재 날짜로부터 100일 후의 날짜는?
LocalDate now = LocalDate.now();
LocalDate after100 = now.plusDays(100);
System.out.println("100일후"+after100);

 

예제4)

나이 계산

//나이계산하기
LocalDate birth = LocalDate.of(2000, 5, 13);
LocalDate today = LocalDate.now();

//기간계산
Period age = Period.between(birth, today);

//나이를 연도 단위로 추출
System.out.println("나이는" + age.getYears());

 

예제5)

시간 차이 계산

LocalTime start = LocalTime.of(9, 0); //오전 9시
LocalTime end = LocalTime.of(11, 30); //오전 11:30

Duration dr = Duration.between(start, end);
System.out.println("시차는" + dr.toHours()+"시간");
System.out.println("시차는" + dr.toMinutes()+"분");
System.out.println("시차는" + dr.toSeconds()+"초");

LocalDate election = LocalDate.of(2025, 6, 3);
System.out.println(election.getDayOfWeek());

 

예제6)

시간 표시방식 변경

LocalDateTime now = LocalDateTime.now();
System.out.println("현재일시"+now);
//2025-05-14T10:02:13
/*
이걸 한국식 날짜포맷으로 바꿀 수는 없을까?

2025년 05월 14일 12시 00분
이런 식으로 패턴을 지정할 수 있다.

yyyy 4자리 년
mm 2자리 월
dd 2자리 일
hh 2자리 시간
mm 2자리 분

DateTimeFormatter
 */
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy년 MM월dd일 HH시mm분");
now.format(dtf);
//내가 정의한 포맷으로 현재 시간을 표시해준다.
System.out.println("현재일시" + now.format(dtf));

 

+ Recent posts