일을 하다보면.. 그러기 싫지만 강제로 DB에 접속해서 쿼리로 업데이트를 해야할때가 많다.

그럴때마다 나는 그냥 쫄아있는 상태로 손을 벌벌 떨면서 ... update table set column = 0 where flag = 1; 과 같은걸 날리고 데이터를 확인하고는 했다.

하지만 그럴때 덜 쫄 수 있는 방법이 있다. 방법은 트랜잭션을 사용하는 것이다. 

R을 제외한 CUD를 칠때는 다음과 같은 방법을 쓴다.

1. 정상적으로 작업했을 때 나오는 카운트 수를 본다. 

select count(*) as c from table where flag = 1;

그럼 쿼리가 실행되면서 몇건인지가 나온다. 그 몇 건을 봐둔다. 

2. 다음과 같은 문구를 미리 작성해둔다. 주석도 포함해서

# start transaction;

# update table set column = 0 where flag = 1; 

# rollback;

# commit;

3. 주석을 하나씩 풀어가면서 진행한다. 우선 트랜잭션을 실행시킨다. 

start transaction; (실행)

# update table set column = 0 where flag = 1; 

# rollback;

# commit;

4. 원래 돌리려고 했던 업데이트 문 실행
update table set column = 0 where flag = 1; 

5. 이때 affected rows가 맨 첨에 날린 카운트수와 일치하는지 본다. 시간 차이가 있겠으나 뭐 얼추 비슷한 값이 나올것이다. 

6. 만약 이상함을 감지했다면 당황하지 않아도 된다. rollback 시키기

rollback;

이렇게 하면 내가 update문을 치기 전으로 돌아간다. 트랜잭션을 걸어놓았으니까 말이다. 

7. 정상적이었다면? commit하기!

commit;을 실행시켜준다. 그러면 끝이당.

'개발개발 > mySql' 카테고리의 다른 글

insert와 bulk insert 무엇을 써야할까요?  (1) 2018.10.04
mysql 월/주차 구하기  (1) 2018.01.06
left join 시 속도 문제  (0) 2016.12.20
SELECT 정렬하기 정리  (0) 2016.12.13
order by varchar to int  (0) 2016.11.24

서론

월/주차 별로 통계를 내야하는 페이지가 있었다. 

내가 만들고 싶었던 것 =  11월 4주차, 11월 5주차 와 같이 월/주차를 구해서 표현하고, 통계를 내고 싶었다.


첨에는 week() 함수, weekofyear()함수를 사용해서 group by 해서 통계페이지를 냈다. 

그런데 52, 27등으로 표현되는 주차를 어떻게 12월 5주차, 1월 2주차 등으로 보여줄지 모르겠어서 (조금) 헤맸다.

막 꼬여가지고 13월 1주차 나오고 그랬다.. 


결론은 

이렇게 짰다.

월 구하기

월은 month()를 이용해서 구할 수 있다.
select month(구하고자 하는 날짜 컬럼) from 테이블;

주차 구하기

주차는 weekofyear()를 사용해서 구할 수 있다. 
다만, 내가 원하는 주차는 단순히 '53주차' 가 아니라 12월 28일이 12월의 4주차인지 5주차인지 1주차인지에 해당하는 것이었다. 그래서 다음과 같이 쿼리를 짰다.
select weekofyear(구하고자 하는 날짜) - weekofyear(구하고자 하는 달의 첫째날) + 1 from 테이블

요런식으로 weekofyear(대상 날짜) - weekofyear(해당 달의 첫째날) + 1(해당 날짜의 주차 - 해당 달의 첫째날 의 주차 + 1) 로 계산하면 문제없이 원하는 m주차를 뽑아 낼 수 있다.


최종본

내가 최종적으로 원한 것은 월, 주차 별로 통계를 뽑아내는 것이었다. 그래서 concat한 뒤에 group by를 해서 뽑아냈다. 

select  concat(month(구하고자 하는 날짜), '월 ', weekofyear(구하고자 하는 날짜) - weekofyear(해당 달의 첫째날) +1, '주차' ) as monthWeek from 테이블 

group by monthWeek;


후일담

뭐 일단은 만들어두긴 했는데, 나중에 보고나니 '통계를 내는 부분' 은 좋은 쿼리가 아니다. 그 이유는 인덱스를 타지도 않고 concat해놓은 스트링으로 새로운 컬럼을 만들어서 group by를 시켰으니 뭐 explain 떠보지 않더라도 완전 안좋을 거라는 예감이 폴폴폴폴폴폴 난다... 나중에 눈치봐서 저 쿼리를 개선하도록 해봐야겠다. 몰래.. 몰래.. ^_^ ;; 

'개발개발 > mySql' 카테고리의 다른 글

insert와 bulk insert 무엇을 써야할까요?  (1) 2018.10.04
DB를 쿼리로 업데이트 할때  (0) 2018.09.16
left join 시 속도 문제  (0) 2016.12.20
SELECT 정렬하기 정리  (0) 2016.12.13
order by varchar to int  (0) 2016.11.24

1. 오름차순 정렬하기

  • select (칼럼) from (테이블) order by (정렬할 칼럼) asc
  • select (칼럼) from (테이블) order by (정렬할 칼럼) 

2. 내림차순 정렬하기

  • select (칼럼) from (테이블) order by (정렬할 칼럼) desc

3. 문자형 숫자 정렬하기

  • 문자형 * 1
    • select (칼럼) from table order by (문자형 숫자 * 1)  
  • 형변환
    • select (칼럼) from (테이블) order by (정렬할 칼럼) 

4. 랜덤으로 가지고오기

  • select (칼럼) from (테이블) order by rand() 
  • select (칼럼) from (테이블) order by rand() limit 3

5. 내맘대로 순서 정의해서 가지고 오기

  • SELECT (칼럼) from (테이블) order by field (칼럼, '3', '22', '1')

이렇게 하면  A열에서 3, 22, 1을 가지고 있는 row순으로 출력된다. 

'개발개발 > mySql' 카테고리의 다른 글

DB를 쿼리로 업데이트 할때  (0) 2018.09.16
mysql 월/주차 구하기  (1) 2018.01.06
left join 시 속도 문제  (0) 2016.12.20
order by varchar to int  (0) 2016.11.24
week(date)에서 한주의 시작일 바꾸기  (0) 2016.11.24

+ Recent posts