database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
ㆍMS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MS-SQL Q&A 7107 게시물 읽기
No. 7107
서브쿼리
작성자
lhh
작성일
2018-01-19 11:40
조회수
2,741

예를들면 emp테이블의 100개의 데이터중에서 9번째 데이터의 age 를 19로 변경하고자 합니다.

 

아래 두 줄의 쿼리를 서브쿼리로 한 줄로 만들수 있을까요?

 

select * from emp limit 9,1

 

update emp set age = 19

 

 

이 글에 대한 댓글이 총 7건 있습니다.

 MSSQL 은 limit을 지원 안하는걸로 알고 있습니다.

 

emp 테이블에 primary key가 있다면 

primary key를 A라 하겠습니다.

update emp set age = 19 where A = (select A FROM emp OFFSET 8 ROWS FETCH NEXT 1 ROWS ONLY) 

 

이런식으로 작성하면 되지 않을까 생각됩니다..

 

DBA님이 2018-01-19 12:20에 작성한 댓글입니다. Edit

답변감사합니다.

 

한가지 문제라면 해당 테이블에는 Primary Key가 없습니다.

그리고 각 필드데이터는 중복이 있을 수 있어서 WHERE 조건에도 제약이 있습니다. 그래서 SELECT 에서 UPDATE 할 특정 데이터를 하나만 찾아야 하므로 LIMIT 9, 1 이나 OFFSET ~ 구문을 필요로 합니다.

lhh님이 2018-01-19 12:56에 작성한 댓글입니다. Edit

신입 DBA 라 방법이 잘 떠오르지 않지만..

한 쿼리로 해결 해야 되는 부분이 아니라면 

emp 테이블을 임시테이블이나 테이블 변수에 Identity 변수를 두어 복사를 한다음

identity 값이 9 번째 인것을 업데이트 하면 되지 않을까 생각되네요..

서브쿼리로 작성은 Primary Key가 없으면 힘들지 않을까요 ..? ㅜㅜ

도움 못드려 죄송합니다..

 

DBA님이 2018-01-19 14:20에 작성한 댓글입니다.
이 댓글은 2018-01-19 14:21에 마지막으로 수정되었습니다. Edit

https://docs.microsoft.com/ko-kr/sql/t-sql/queries/select-order-by-clause-transact-sql

를 보시면

"ORDER BY 절을 지정하지 않으면 결과 집합에서 행이 반환되는 순서가 보장되지 않습니다."

라고 나와있습니다.

따라서 조건에 맞는 아무 행이나 1개 행을 update하신 후에 왜 이렇게 됐느냐고 누군가가 물어본다면 "접때 업데이트 할때는 그게 9번째 행이었다"라고 우기면 됩니다.

--예제: 입력한 순서대로 안 보여주는 예제

CREATE TABLE mixedOrder ( aa INT )
;
GO
 
-- 1부터 연달아 들어감
INSERT INTO mixedOrder( aa )
SELECT ROW_NUMBER() OVER( ORDER BY ( SELECT NULL ) ) AS aa
FROM sys.all_columns
;
-- 순서가 이쁘게 들어가 있는지 확인
SELECT * 
FROM mixedOrder
;
-- 중간중간 삭제해버림
DELETE FROM mixedOrder
WHERE aa%2 = 0
;
-- 아직도 순서는 이쁘장함
SELECT * 
FROM mixedOrder
;
-- 100001부터 연달아 들어감
INSERT INTO mixedOrder( aa )
SELECT 100000 + ROW_NUMBER() OVER( ORDER BY ( SELECT NULL ) ) AS aa
FROM sys.all_columns
;
-- 순서가 엉망임을 확인
SELECT * 
FROM mixedOrder
;
 
DROP TABLE mixedOrder
;
GO
 

정렬기준이 명확하고 그 순서에 따라 9번째 행이 1개의 행 밖에 없다면 

UPDATE emp
SET col1 = 5 -- 5로 업데이트
FROM
( --정렬 기준이 col2, col1 이라면 col2, col1을 기준으로 
SELECT *, ROW_NUMBER() OVER ( ORDER BY col2, col1 ) AS rn
FROM emp
) AS kk
WHERE rn = 9 AND kk.col2 = emp.col2 AND kk.col1 = emp.col1
;
 
식으로 9번째 행을 update할 수 있겠습니다.

 

우욱님이 2018-01-19 14:27에 작성한 댓글입니다. Edit

참.. 그래서 진짜 하고 싶었던 얘기를 못 썼네요..

PK 만드세요.

우욱님이 2018-01-19 14:29에 작성한 댓글입니다. Edit

두 분의 좋은 답변과 지적에 감사드립니다.

lhh님이 2018-01-19 15:05에 작성한 댓글입니다. Edit

Key가 없기 때문에 서브쿼리로 해당열을 찾을수는 없습니다.

위에 답변주신 분들 말씀대로 Key를 생성하시거나

아니면 커서를 이용해서 Row별로 Update를 하는 방법이 있습니다.

 

SELECT 쿼리를 커서로 만드시고,

 

커서를 돌리면서 카운팅해서,

9번째 데이터를 UPDATE 하면 됩니다.

 

아래 링크에 커서를 이용한 UPDATE 예제가 있습니다.

조금 응용하면 됩니다.

 

https://technet.microsoft.com/en-us/library/ms188713(v=sql.105).aspx

박지훈님이 2018-01-25 13:55에 작성한 댓글입니다.
이 댓글은 2018-01-25 14:02에 마지막으로 수정되었습니다. Edit
[Top]
No.
제목
작성자
작성일
조회
7110프로시저 다국어 질문 [1]
신입
2018-02-14
2439
7109쿼리 조인 질문드립니다. [1]
asdf
2018-02-08
2136
7108MSSQL 2000 설치 질문(설치 화면이 안나오는 현상)
민준기
2018-01-26
2190
7107서브쿼리 [7]
lhh
2018-01-19
2741
7106MSSQL 쿼리속도 질문 [2]
킨들
2018-01-14
2565
7105checkdb 시 오류 [2]
조성배
2018-01-10
2637
7104[질문]데이터에서 1을 만날때 값을 시퀀스하게 증가시키기 [2]
말말말초보
2017-11-16
2424
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.049초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다