[MS-SQL] 집계함수(count, sum, avg, min, max), Group by, Having, Compute, Datetime
■ select 구문의실행순서
select 컬럼명 -- 5 from 테이블명-- 1 where 조건절 -- 2 group by 절 -- 3 having 절 -- 4 order by 절 -- 6
■ 집계함수 count(), sum(), avg(), min(), max()
● count()
/* count() 함수- 수를세아리다 : 현재select 에의해서반환되고있는레코드(컬럼)의갯수를반환 문법: count(컬럼명) */ -- 서울에사는회원은몇명?? select COUNT(*) from userTbl where addr = '서울'; -- 아시아와유럽에속한나라의갯수?? 7개 select COUNT(*) from tblCountry where cont in ('AS','EU'); -- or 조건 -- count() 함수의인자값이(*) 이거나(컬럼명) 일떄의차이점 select COUNT(*) from tblgroup; -- 직원수25명 select COUNT(name) from tblGroup; -- 직원의이름이총25개인상황 select COUNT(achieve) from tblGroup; -- 인자값으로컬럼명을줬을때!!! -- null값은카운트에서제외(***) -- 실적보너스1,000,000 원-> 1/n 분배 select 10000000 / 25; -- (X) select 10000000 / COUNT(*) from tblGroup; -- (O) 모든직원에게분배 select 10000000 / COUNT(achieve) from tblGroup; -- 실적null 인사람뺴고분배 -- 실적이있는사원수? select COUNT(achieve) from tblGroup; -- 실적이없는사원수? select COUNT(*) - COUNT(achieve) from tblGroup; select COUNT(*) from tblGroup where achieve is null -- 근무개월수가1년이상2년이하인직원수? select COUNT(workmonth) from tblGroup where workMonth between 12 and 24 --중복값제거 select distinct(cont) from tblCountry; select count(distinct(cont)) from tblcountry;
● sum()
/* sum()함수 문법: sum(컬럼명) 컬럼값의총합을반환 */ select achieve from tblGroup; -- 개인별실적 select SUM(achieve) from tblGroup; -- 총합실적 --Error select SUM(name) from tblGroup; -- 컬럼(name)이 숫자가 아닐경우는 에러가 난다.
● avg()
/* avg() 함수 문법: avg(컬럼명) : 컬럼값의평균을반환하는함수 : null 레코드는제외!!!! (count() 와같다.) */ select AVG(achieve) from tblGroup; -- 개인당평균 select avg(workmonth) from tblGroup; select sum(achieve) as [총실적수], avg(achieve) as [평균실적수] from tblGroup;
● min(), max()
/* max(컬럼명) 함수: 최대값 - 컬럼명중최대값하나를반환시킨다. min(컬럼명) 함수: 최소값 - 컬럼명중최소값하나를반환시킨다. 문자형역시산출가능 */ -- 월급이가장많은액수? select COUNT(salary) from tblGroup; select SUM(salary) from tblGroup; select MAX(salary) from tblGroup; select MIN(salary) from tblGroup; -- 에러! 집계함수는where절에못쓴다. select name from tblGroup where salary = MAX(salary); select MAX(name) from tblGroup; -- 가능 select MIN(name) from tblGroup; -- 가능
■ group by
/* - group by (그룹을묶어서무언가할수있는일을실행하겠다?) - 특정컬럼값이동일한레코드의통계값반환 - 집계함수와같이사용함(***) -> 직계함수의결과를그룹지어서보자 - group by를이용해서select 실행시결과리스트안에는... 1. 집계함수 2. group by의대상컬럼이올수있다. */ -- 전직원의평균근무개월수? -> AVG() select AVG(workmonth) from tblGroup; -- 부서별직원의평균근무개월? -> AVG() + 조건 select distinct(depart) from tblGroup; -- 관리부, 생산부, 영업부, 지원부 select AVG(workmonth) from tblGroup where depart = '관리부'; select AVG(workmonth) from tblGroup where depart = '생산부'; select AVG(workmonth) from tblGroup where depart = '영업부'; select AVG(workmonth) from tblGroup where depart = '지원부'; -- depart 컬럼값이동일한값을갖는레코드끼리묶자!!(그룹화) select AVG(workmonth) as [근무개월], depart from tblGroup group by depart; -- 에러구문, select workmonth from tblGroup group by depart; -- group by depart로 부서를 묶었는데 거기서 workmonth를 가져오라고 하니 -- 근무개월수가 부서별 개인마다 다 다른데 어떤걸불러와야 할지모른다. -- 그러므로 집계함수나 대상컬럼외에는올수없다. -- 각부서별직원수? select depart, COUNT(*)as[부서별직원] from tblGroup group by depart; -- 각부서별최대월급은? select depart, MAX(salary) as [부서별월급] from tblGroup group by depart; -- 대륙별국가수? select cont, COUNT(*) from tblCountry group by cont; -- 사용자아이디별로물품에상관없이총구매갯수? select userid, sum(amount) from buyTbl group by userid; -- 사용자아이디별로물품에상관없이총구매액수? select userid, SUM(price * amount) from buyTbl group by userid; -- 분야별(type) 도서의평균가격?, 도서몇권?, 가장비싼책가격?, 가장싼책가격? select [TYPE], AVG(price) as [평균가격], COUNT(type)as [도서몇권], MAX(price)as [비싼책], MIN(price) as [싼책] from titles group by [type];
■ having
/* - having : group by 의조건절역할 */ --각부서별평균월급? select depart, AVG(salary) from tblgroup group by depart; -- 각부서별평균월급이180만원이상인부서를나타내시오 select depart, AVG(salary) from tblgroup group by depart having AVG(salary) > 180; -- 각부서별평균월급이180만원이상인부서를나타내고, 평균월급정렬 select depart, AVG(salary) from tblgroup group by depart having AVG(salary) > 180 order by AVG(salary) desc; --(가장우선하는전제조건) 12개월근무가넘은사람들에한해서.. -- 평균월급180만원이상인부서별평균월급? 평균월급정렬 select depart, avg(salary) as [월급] from tblgroup where workmonth >= 12 group by depart having avg(salary) > 180 order by avg(salary) desc; -- 위의select와차이점이해!! select depart, avg(salary) as [월급] from tblgroup group by depart having avg(salary) >180 and AVG(workmonth) >= 12 order by avg(salary) desc; -- 관리부, 생산부대상-> 부서별평균월급 select depart, AVG(salary) from tblGroup group by depart having depart = '관리부' or depart = '생산부'; -- 비추천 select depart, AVG(salary) from tblGroup group by depart having depart in('관리부','생산부'); -- 추천구문(0)
■ compute
/* - compute ( 사용도떨어짐^.* ) : select 실행후별도의집계결과를반환 : 집계함수과같이사용 : select의대상은집계함수 */ select * from tblGroup; select AVG(salary) from tblGroup; -- 전체직원의평균월급 select * from tblGroup compute avg(salary); -- 위의두문장을한문장으로표현 -- 일이끝나고난뒤별도의집계합수값을실행() select * from tblGroup compute sum(salary); -- tblgroup을다가져온뒤월급총합을보여준다.
■ Datetime 함수
/* - 날짜시간함수 : Datetime 형 */ select GETDATE() as [현재시간]; create table tblMemo ( seq int identity(1,1) primary key, -- 메모번호 memo nvarchar(1000) not null, -- 메모내용 writedate datetime not null -- 작성시간 ) insert into tblMemo (memo,writedate) values('메모입니다.~', GETDATE()); -- getdate() 직접입력 select * from tblMemo create table tblMemo2 ( seq int identity(1,1) primary key, -- 메모번호 memo nvarchar(1000) not null, -- 메모내용 writedate datetime default(getdate()) not null -- 작성시간 ) insert into tblMemo2(memo) values('메모입력했다잉~'); -- gatdate() 기본값으로자동입력 select * from tblMemo2; insert into tblMemo2(memo) values('메모다잉~'); -- 시간을 두고 F5 입력 ↓ insert into tblMemo2(memo) values('메모다잉~1'); insert into tblMemo2(memo) values('메모다잉~2'); insert into tblMemo2(memo) values('메모다잉~3'); insert into tblMemo2(memo) values('메모다잉~4'); insert into tblMemo2(memo) values('메모다잉~5'); select writedate from tblmemo2; -- 가장최근에쓴메모가언제쓴메모?? select top 1 writedate from tblMemo2 order by writedate desc; select MAX(writedate) from tblmemo2; -- 위아래같은구문
■ 추출 DatePart
/* - 추출(년,월,일) DatePart(year,month,day) */ select DATEPART(YEAR, max(writedate)) from tblMemo2; select DATEPART(MONTH, max(writedate)) from tblMemo2; select DATEPART(DAY, max(writedate)) from tblMemo2; select DATEPART(HOUR, max(writedate)) from tblMemo2; select DATEPART(MINUTE, max(writedate)) from tblMemo2; select DATEPART(SECOND, max(writedate)) from tblMemo2; select DATEPART(YEAR, DAY(writedate)), writedate from tblMemo2; -- 6월에출간된도서명? select * from titles; select * from titles where DATEPART(MONTH, pubdate) = 6; select DATEPART(MONTH,pubdate) from titles; -- 출간일의그달만표시 -- 2000년이후출간도서? 2건 select * from titles where pubdate > '2000-01-01';
■ datetime 연산
/* - datetime 연산 DATEADD(형식,시간,시각) return 시각: 시각+ 시간= 시각 DATEDIFF(형식,시간,시각) return 시간: 시각- 시각= 시간 */ select * from tblMemo2; -- 메모시간+ 100일 select writedate, DATEADD(DAY,100,writedate) from tblMemo2; -- DAY + 100일= writedate에적용 -- 메모시간- 100일 select writedate, DATEADD(DAY,-100,Writedate) from tblMemo2; -- 메모시간+ 100년 select writedate, DATEADD(YEAR,100,Writedate) from tblMemo2; -- 메모를각각적은후얼마나지났는지 -- 원하는건: 현재시각- 기록시각= 시간 select writedate from tblMemo2; select writedate, DATEDIFF(HOUR, writedate, GETDATE()) from tblMemo2; -- DATEDIFF(HOUR,기록시간,현재시간()) : 기록시간- 현재시간을시간으로나타낸다. select writedate from tblMemo2; select LEFT(writedate,4) from tblMemo2;