반응형

구글 번역으로 인한 발번역이 있습니다. 한국어 설정은 제일 하단에 기입했습니다.

전체 텍스트 검색 정보

정의의 도움으로 전체 텍스트 검색을 이해합시다.

간단한 정의

전체 텍스트 검색은 빠른 답변을 위해 문자 기반 데이터를 최적으로 검색하는 데 사용됩니다.

Microsoft 정의

SQL Server 및 Azure SQL Database (클라우드 버전의 SQL 데이터베이스)에서 전체 텍스트 검색을 사용하면 사용자와 응용 프로그램이 SQL Server 테이블의 문자 기반 데이터에 대해 전체 텍스트 쿼리를 실행할 수 있습니다.

전체 텍스트 쿼리 란?

전체 텍스트 쿼리는 텍스트 데이터가있는 열에 대해 작성되고 실행되어 데이터 패턴을 찾는 특수한 종류의 쿼리입니다. 이 문제에 대해서는 해당 열에 대해 전체 텍스트 검색을 활성화해야합니다.

적합성

전체 텍스트 검색은 다음 SQL Server 버전과 호환됩니다.

  1. SQL Server 2005 이상
  2. Azure SQL 데이터베이스

전문 검색 현대 버전

SQL 2016과 같은 최신 SQL Server 버전에서는 전체 텍스트 검색을 의미 검색과 함께 설치할 수 있습니다.

전체 텍스트 검색 – SQL Server 옵션

SQL Server를 설치할 때는 기본적으로 전체 텍스트 검색이 설치되지 않습니다. 원래 SQL Server를 설치하는 데 사용한 설정을 사용하여 현재 SQL 인스턴스에 더 많은 기능을 추가하여 선택적으로 설치해야합니다.

전체 텍스트 검색 – 데이터베이스 기본값

모든 SQL 데이터베이스는 기본적으로 전체 텍스트 검색과 함께 사용할 수 있습니다. SQL 데이터베이스에서 전체 텍스트 검색을 사용하기 전에 요구 사항을 제외하고 추가 설치가 필요하지 않습니다.

대소 문자 구분

Microsoft 문서에 따르면 전체 텍스트 검색은 대소 문자를 구분하지 않으므로 "제어판", "제어판"및 "제어판"이라는 단어는 모두 동일하게 취급됩니다.

전체 텍스트 검색 설정

언급했듯이 SQL Server를 설치하는 데 사용한 것과 동일한 설치 파일을 사용하여 기존 SQL Server 설치의 기능으로 전체 텍스트 검색을 추가해야합니다.

SQL Installer 실행

SQL Server 설치 관리자를 실행하여 시작하십시오. 저장하지 않고 설치 프로그램에서 직접 실행하려는 경우 드라이브로 마운트 할 수있는 옵션을 제공합니다.

설치 파일 실행

Setup.exe 파일을 클릭하여 SQL Server 설치를 실행하십시오.

기능으로 추가

설정 파일을 실행하자마자 일부 초기 검사가 수행됩니다. 이러한 검사가 통과되면 설치 탐색 모음 (섹션)에서 “기존 설치 옵션에 기능 추가” 를 선택해야합니다 .

현재 서버를 선택하십시오

다음으로 전체 텍스트 검색을 설치할 현재 / 잠재 서버를 선택하십시오. 우리의 경우 SQL 2016입니다.

추가 할 인스턴스 기능을 선택하십시오.

다음으로, 검색  전체 텍스트 및 의미 추출 추출 기능을 선택하십시오 (이전 SQL 버전에이 기능을 추가하면 의미 추출이 표시되지 않을 수 있음).

연습 전에이 기능을 이미 추가 했으므로 스크린 샷에서 회색으로 표시됩니다. 그러나 처음으로 추가하는 사람에게는 활성화되어 있고 약간의 시간이 걸리는 설치가 가능합니다.

전체 텍스트 검색 설치 상태 확인

전체 텍스트 검색이 설치되면 마스터 데이터베이스에 대해 다음 T-SQL 스크립트를 실행하여 확인할 수 있습니다.

-- Is Full-Text Search installed then 1 or 0

SELECT fulltextserviceproperty('IsFulltextInstalled') as [Full-Text Search]

전체 텍스트 검색을 사용하여 단어 및 구문 검색

이제 전체 텍스트 검색을 사용하여 단어 및 구에 대한 몇 가지 기본 검색 작업을 수행합니다.

샘플 데이터베이스 설정

전체 텍스트 검색의 기본 사용법을 이해하려면 다음과 같이 SQLDevBlogV6 이라는 샘플 데이터베이스를 설정하십시오 .

-- Create sample database (SQLDevBlogV6)

CREATE DATABASE SQLDevBlogV6;

GO





USE SQLDevBlogV6;



-- (1) Create Article table in the sample database

CREATE TABLE [dbo].[Article] (

[ArticleId] INT IDENTITY (1, 1) NOT NULL,

[Category] VARCHAR (50) NULL,

[Author] VARCHAR (50) NULL,

[Title] VARCHAR (150) NULL,

[Published] DATETIME2 (7) NULL,

[Notes] VARCHAR (400) NULL,

CONSTRAINT [PK_Article] PRIMARY KEY (ArticleId)

);



GO



-- (2) Populate the table with data

SET IDENTITY_INSERT [dbo].[Article] ON

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (1, N'Development', N'Atif', N'Introduction to T-SQL Programming ', N'2017-01-01 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (2, N'Testing', N'Peter', N'Database Unit Testing Fundamentals', N'2017-01-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (3, N'DLM', N'Sadaf', N'Database Lifecycle Management for beginners', N'2017-01-20 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (4, N'Development', N'Peter', N'Common Table Expressions (CTE)', N'2017-02-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (5, N'Testing', N'Sadaf', N'Manual Testing vs. Automated Testing', N'2017-03-20 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (6, N'Testing', N'Atif', N'Beyond Database Unit Testing', N'2017-11-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (7, N'Testing', N'Sadaf', N'Cross Database Unit Testing', N'2017-12-20 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (8, N'Development', N'Peter', N'SQLCMD - A Handy Utility for Developers', N'2018-01-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (9, N'Testing', N'Sadaf', N'Scripting and Testing Database for beginners ', N'2018-02-15 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (10, N'Development', N'Atif', N'Advanced Database Development Methods', N'2018-07-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (11, N'Testing', N'Sadaf', N'How to Write Unit Tests for your Database', N'2018-11-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (12, N'Development', N'Peter', N'Database Development using Modern Tools', N'2018-12-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (13, N'DLM', N'Atif', N'Designing, Developing and Deploying Database', N'2019-01-01 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (14, N'DLM', N'Peter', N'How to Apply Database Lifecycle Management', N'2019-02-10 00:00:00', NULL)

INSERT INTO [dbo].[Article] ([ArticleId], [Category], [Author], [Title], [Published], [Notes]) VALUES (15, N'Testing', N'Saqib', N'SQL Unit Testing Stored Procedures', N'2019-03-10 00:00:00', NULL)

SET IDENTITY_INSERT [dbo].[Article] OFF

문구와 단어

전체 텍스트 검색의 맥락에서 더 많은 문구와 단어를 봅시다. 이렇게하면 전체 텍스트 검색을 통해 원하는 것을 더 잘 알 수 있습니다.

 T-SQL 소개  라는 문구는 문구이며“ 소개 ”및“ T-SQL ”은 중요한 단어입니다.

SQL Server에서 전체 텍스트 검색을 구현하는 단계

전체 텍스트 검색은 다음과 같은 방식으로 구현됩니다.

  1. 전체 텍스트 인덱스를 저장하기 위해 전체 텍스트 카탈로그를 만듭니다.
  2. 테이블 또는 인덱싱 된 뷰에서 전체 텍스트 인덱스를 정의하십시오.
  3. CONTAINS 또는 FREETEXT를 사용하여 전체 텍스트 검색 쿼리를 실행하여 단어 와 구 를 찾습니다  .

전체 텍스트 카탈로그 작성

따라서 샘플 데이터베이스 (SQLDevBlogV6)가 작성되고 채워졌습니다. 전체 텍스트 카탈로그를 만드는 것이 전체 텍스트 검색을 구현하는 첫 번째 단계입니다.

SQL Server의 개체 탐색기  이동하여 데이터베이스 노드를 확장 한 다음 SQLDevBlogV6 을 클릭하십시오 .

클릭 저장을 한 후 클릭하여 전체 텍스트 카탈로그를, 다음을 클릭 새로운 전체 텍스트 카탈로그를 :

카탈로그 이름을 DevBlogCatalog 로 입력하고 확인을 클릭하십시오 .

새로 작성된 전체 텍스트 카탈로그는 다음과 같습니다.

테이블에 전체 텍스트 인덱스 정의

Articles 테이블을 마우스 오른쪽 단추로 클릭하고 전체 텍스트 인덱스 를 클릭 한 다음 아래와 같이 전체 텍스트 인덱스 정의 를 클릭 합니다.

전체 텍스트 인덱싱 마법사가 트리거됩니다. 클릭 다음 , 다음을 클릭합니다 다음을 다시 테이블에 기본 키가 마법사에 의해 미리 선택되어 있는지 확인한 뒤.

다음 단계에서 전체 텍스트 쿼리에 대한 제목 열을 선택하십시오 . 다음은 전체 텍스트 쿼리를 실행할 열입니다.

그런 다음 아래와 같이 자동 옵션 (다른 옵션을 선택하지 않는 경우)을 선택하여 변경 내용 추적을 자동화하는 기본 옵션을 선택하십시오 .

다음 단계에서는이 연습에서 앞에서 정의한 전체 텍스트 색인과 연결할 전체 텍스트 카탈로그 (DevBlogCatalog)를 선택하십시오. 그런 다음 아래와 같이 기본 옵션을 선택한 후 다음을 클릭하십시오.

클릭 다음을 하고 선택적인 단계를 건너 뛰고, 다음을 클릭합니다 마침을 전체 텍스트 색인이 성공적으로 생성 된 것을 볼 수 있습니다.

이제 전체 텍스트 검색을 활성화하여 기사 테이블  제목 열에 대해 전체 텍스트 쿼리를 실행할 수 있습니다 .

전체 텍스트 쿼리를 사용하여 단어 테스트 검색

다음 T-SQL 스크립트를 작성하여 CONTAINS 키워드 (조건 자)를 사용하여 단어를 빠르게 검색 할 수 있습니다 .

-- Search for the Word Testing using Full-Text Query

SELECT * FROM dbo.Article

WHERE CONTAINS(Title,'Testing')

제목  에서 테스트 단어 를 검색 한 결과 는 다음과 같습니다.

전체 텍스트 검색없이 Like 연산자를 사용하여 동일한 결과를 얻을 수 있습니다. 차이점은 수백만 행과 수백만 행에 대해이 쿼리를 실행할 때와 LIKE 연산자가 어려움을 겪을 때입니다. 한편 전문가에 따르면 CONTAINS는 훨씬 빠릅니다.

전체 텍스트 쿼리를 사용하여 초보자를위한 구문 검색

제목에 "초보자를위한" 이라는 문구 가 사용 된 모든 기사를 찾아 보겠습니다 . 이것은 초보자가 빨리 시작할 수 있도록 도와줍니다.

이번에는 FREETEXT 키워드 (Predicate)를 사용하고 있습니다. 다음 T-SQL 스크립트를 사용하여 초보자를위한 모든 기사를 얻을 수 있습니다.

-- Search for Phrase: for beginners using Full-Text Query

SELECT * FROM dbo.Article

WHERE FREETEXT(Title,'for beginners')

축하합니다. 전체 텍스트 검색의 기본 사항을 성공적으로 익혔습니다. 단어와 구에 대한 전체 텍스트 검색 쿼리를 설정하고 실행하는 실습 경험도 있습니다.

다음 기사에서 고급 전체 텍스트 검색 사용법을 설명하므로 계속 연락하십시오. 데이터베이스 분석 시나리오에서 종종 유용합니다.

해야 할 일

전체 텍스트 검색을 설정하고 전체 텍스트 쿼리를 실행할 수 있으므로 다음을 시도하여 기술을 향상 시키십시오.

  1. 기사에 대한 자세한 정보를 제공 하여 데이터베이스 Notes 열을 채우십시오. CONTAINS 및 FREETEXT 키워드를 사용하여 단어와 구를 검색하려면 전체 텍스트 카탈로그를 정의하고 전체 텍스트 쿼리를 실행해야합니다.
  2. 또한 단어 단위  검색 하여이 단어가 언급 된 모든 기사를 찾으십시오. 열에 단위 테스트, 단위 테스트 또는 단위 테스트로 저장 될 수 있습니다.
  3. 이 기사 의 샘플 데이터베이스를 참조하십시오 . 전체 텍스트 설정 Product 테이블을 검색 하고 열 이름 에 전체 텍스트 인덱스를 정의하고 가능한 한 많은 레코드를 추가하십시오. 원하는 단어와 구를 검색하여 원하는 제품 (이름)을 찾으십시오.

 

원본 : https://codingsight.com/implementing-full-text-search-in-sql-server-2016-for-beginners/

 

++ 한국어 설정

위의 설정대로 따라하면 한국어가 설정이 되지않아 FREETEXT가 제대로 작동하지 않는것을 확인할 수 있다.

 

1. 사용하는 데이터 베이스 - Storage - Full Text Catalogs - 상단에서만든카타로그 오른쪽클릭

2. Properties 클릭 (sql server manager를 한국어로 설정했다면 속성)

3. Tables/Views 탭 클릭

4. 해당 탭에서 하단의 Eligible columns 를 보면 이 글의 상단에서 Full-Text query를 사용할 column들이 보인다.

5. 체크한 column들의 Language for Word Breaker 가 영어로 설정되어 있을것인데 모두 Korean으로 바꿔준다.

6. ok로 설정 완료  

반응형
반응형

SQL Server의 기본 격리 수준(isolation level)은 read committed 입니다. 

그래서 데이터를 읽을 때는 공유 잠금이 유지됩니다. 그러므로, 쉽게 설명하자면 

SELECT문이 실행 중인 동안에 같은 row혹은 table에 insert나 update하는 작업은 block됩니다. 

거꾸로 같은 row, data page 혹은 테이블에 데이터를 insert, update하는 동안 SELECT문은 block되게 됩니다. 

이렇게 되면 데이터베이스 성능이 현저히 떨어지게 됩니다. 

그러므로 일반적으로 단순 조회 쿼리에는 with (nolock)문을 추가하여 사용합니다.

ex) SELECT * FROM MEMBER with (nolock)



출처: https://skymin2.tistory.com/43 [생계형 개발자]

반응형
반응형

프로그래밍 언어중에서 조건에따라 작업방식을 달리 할 수 있는 조건문이라는 것이 있습니다. 대표적인 문법이 IF문과 CASE문인데요. MSSQL에서도 조건절인 CASE문과 IF문을 지원하니 한번 활용해보시는 것도 좋을것 같습니다.

 

CASE WHEN

가장 많이쓰이는 조건문입니다. 조건에 따라 값을 지정해 주는 역할을 합니다. 

--CASE사용법--
CASE WHEN 조건절 THEN 참일때 값 ELSE 거짓일때 값 END 컬럼명
--테이블(MY_TABLE)에서 성별(GENDER)이 001이면 여, 그게아니면 남자로 검색--
SELECT DISTINCT
GENDER,
CASE WHEN GENDER = '001' THEN '여' ELSE '남' END AS 성별
FROM MY_TABLE

다중 CASE WHEN

--테이블(MY_TABLE)에서 성적(SCORE)별 학점을 계산
SELECT *,
   (CASE WHEN SCORE>= '90' THEN 'A학점'
        WHEN (SCORE>= '80' AND SCORE < '90') THEN 'B학점'
        WHEN (SCORE>= '70' AND SCORE < '80') THEN 'C학점' 
        WHEN (SCORE>= '60' AND SCORE < '70') THEN 'D학점'
        ELSE 'F학점'
    END) AS '학점'
FROM MY_TABLE

IF ELSE

CASE WHEN과 같은 조건문입니다. CASE문과 마찬가지로 조건에 따라 원하는 작업을 수행할 수 있습니다.

--IF 사용법--
IF 조건 참일때 값 ELSE 거짓일때 값 END 컬럼명
--@NUM 이 30일때 30이라고 출력, 40일경우 40이라고 출력, 아닐경우 아니라고 출력하기--
DECLARE @NUM INT
SET @NUM = 40

IF(@NUM = 30)
PRINT 'NUM은 30입니다.'
ELSE IF(@NUM=40)
PRINT 'NUM은 40입니다'
ELSE
PRINT 'NUM은 30이나 40이 아닙니다.'

출처 : https://coding-factory.tistory.com/113

반응형
반응형

1. JOIN 의 개요

  • 두 개 이상의 테이블 들을 연결 또는 결합하여 데이터를 출력하는 것을 JOIN이라고 하며, 일반적으로 사용되는 SQL 문장의 상당수가 JOIN이라고 생각하면 JOIN의 중요성을 이해하기 쉬울 것이다.
  • JOIN은 관계형 데이터베이스의 가장 큰 장점이면서 대표적인 핵심 기능이라고 할 수 있다.
  • 일반적인 경우 행들은 PRIMARY KEY(PK)나 FOREIGN KEY(FK) 값의 연관에 의해 JOIN이 성립된다. 하지만 어떤 경우에는 이러한 PK, FK의 관계가 없어도 논리적인 값들의 연관만으로 JOIN이 성립 가능하다.
  • FROM 절에 여러 테이블이 나열되더라도 SQL에서 데이터를 처리할 때는 단 두 개의 집합 간에만 조인이 일어난다는 것이다.
  • FROM 절에 A, B, C 테이블이 나열되었더라도 특정 2개의 테이블만 먼저 조인 처리되고, 2개의 테이블이 조인되어서 처리된 새로운 데이터 집합과 남은 한 개의 테이블이 다음 차례로 조인되는 것이다.
  • 예를 들어 A, B, C, D 4개의 테이블을 조인하고자 할 경우 옵티마이저는 ( ( (A JOIN D) JOIN C) JOIN B)와 같이 순차적으로 조인을 처리하게 된다.
  • 먼저 A와 D 테이블을 조인 처리하고, 그 결과 집합과 C 테이블을 다음 순서에 조인 처리하고, 마지막으로 3개의 테이블을 조인 처리한 집합과 B 테이블을 조인 수행하게 된다.
  • 이때 테이블의 조인 순서는 옵티마이저에 의해서 결정되고 과목3의 주요 튜닝 포인트가 된다.

2. EQUAL JOIN

  • 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법으로 대부분 PK ↔ FK의 관계를 기반으로 한다.
  • 그러나 일반적으로 테이블 설계 시에 나타난 PK ↔ FK의 관계를 이용하는 것이지 반드시 PK ↔ FK의 관계로만 EQUI JOIN이 성립하는 것은 아니다.
  • 이 기능은 계층형(Hierarchical)이나 망형(Network) 데이터베이스와 비교해서 관계형 데이터베이스의 큰 장점이다
  • WHERE 안에 사용한 JOIN
  • 형식)
  SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...  
    FROM 테이블1, 테이블2  
   WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2; 
      => WHERE 절에 JOIN 조건을 넣는다.
  • ANSI/ISO SQL 표준 방식
SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...  
  FROM 테이블1   
 INNER JOIN 테이블2  
    ON 테이블1.칼럼명1 = 테이블2.칼럼명2;
    => ON 절에 JOIN 조건을 넣는다.  (조건식)
  • 예) WHERE 조건이용한 JOIN
 SELECT PLAYER.PLAYER_NAME  선수명  
      , TEAM.TEAM_NAME      소속팀명  
   FROM PLAYER, TEAM  
  WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID; 
  • 예) ANSI JOIN
SELECT PLAYER.PLAYER_NAME  선수명  
     , TEAM.TEAM_NAME      소속팀명  
  FROM PLAYER  
 INNER JOIN TEAM  
    ON PLAYER.TEAM_ID = TEAM.TEAM_ID;
  • "테이블명.칼럼명"처럼 테이블명과 칼럼명이 같이 나타난다.
  • 이렇게 특정 칼럼에 접근하기 위해 그 칼럼이 어느 테이블에 존재하는 칼럼인지를 명시하는 것은 두 가지 이유가 있다.
    • 1. JOIN에 사용되는 두 개의 테이블에 같은 칼럼명이 존재하는 경우에는 DBMS의 옵티마이저는 어떤 칼럼을 사용해야 할지 모르기 때문에 파싱 단계에서 에러가 발생된다.
    • 2. 데이터가 어느 테이블에 있는 칼럼을 말하는 것인지 쉽게 알 수 있게 하므로 SQL에 대한 가독성이나 유지보수성을 높이는 효과가 있다.
  • 하나의 SQL 문장 내에서 유일하게 사용하는 칼럼명이라면 칼럼명 앞에 테이블 명을 붙이지 않아도 되지만, 현재 두 집합에서 유일하다고 하여 미래에도 두 집합에서 유일하다는 보장은 없기 때문에 향후 발생할 오류를 방지하고 일관성을 위해 유일한 칼럼도 출력할 칼럼명 앞에 테이블명을 붙여서 사용하는 습관을 기르는 것을 권장한다.
  • 조인 조건에 맞는 데이터만 출력하는 INNER JOIN에 참여하는 대상 테이블이 N개라고 했을 때, N개의 테이블로부터 필요한 데이터를 조회하기 위해 필요한 JOIN 조건은 대상 테이블의 개수에서 하나를 뺀 N-1개 이상이 필요하다.
  • 즉 FROM 절에 테이블이 3개가 표시되어 있다면 JOIN 조건은 3-1=2개 이상이 필요하며, 테이블이 4개가 표시되어 있다면 JOIN 조건은 4-1=3개 이상이 필요하다.
  • (옵티마이저의 발전으로 옵티마이저가 일부 JOIN 조건을 실행계획 수립 단계에서 추가할 수도 있지만, 예외적인 사항이다.)

가. 선수-팀 EQUI JOIN 사례

  • 우선 선수(PLAYER) 테이블과 팀(TEAM) 테이블에 있는 데이터와 이들 간의 관계를 나타내는 그림을 통해서 실제로 데이터들이 어떻게 연결되는지 살펴본다.
  • 위와 같이 선수들의 정보가 들어 있는 선수(PLAYER) 테이블이 있고, 팀의 정보가 들어 있는 팀(TEAM) 테이블이 있다.
  • 그런데 선수(PLAYER) 테이블에 있는 소속팀코드(TEAM_ID) 칼럼이 팀(TEAM) 테이블의 팀코드(TEAM_ID)와 PK(팀 테이블의 팀코드)와 FK(선수 테이블의 소속팀 코드)의 관계에 있다.
  • 예1) 테이블 명을 이용한 경우
 --WHERE조건을 이용한 JOIN  
 SELECT PLAYER.PLAYER_NAME  
      , PLAYER.BACK_NO  
      , PLAYER.TEAM_ID  
      , TEAM.TEAM_NAME  
      , TEAM.REGION_NAME  
   FROM PLAYER, TEAM  
  WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;  
 
--ANSI JOIN  
 SELECT PLAYER.PLAYER_NAME  
      , PLAYER.BACK_NO  
      , PLAYER.TEAM_ID  
      , TEAM.TEAM_NAME  
      , TEAM.REGION_NAME  
   FROM PLAYER  
  INNER JOIN TEAM  
     ON PLAYER.TEAM_ID = TEAM.TEAM_ID;
  • 예2) ALIAS를 이용한 경우
--WHERE조건을 이용한 JOIN  
 SELECT A.PLAYER_NAME  
      , A.BACK_NO  
      , A.TEAM_ID  
      , B.TEAM_NAME  
      , B.REGION_NAME  
   FROM PLAYER A, TEAM B  
  WHERE A.TEAM_ID = B.TEAM_ID;


 --ANSI JOIN  
 SELECT A.PLAYER_NAME  
      , A.BACK_NO  
      , A.TEAM_ID  
      , B.TEAM_NAME  
      , B.REGION_NAME  
   FROM PLAYER A  
  INNER JOIN TEAM  B  
     ON A.TEAM_ID = B.TEAM_ID;   

나. 선수-팀 WHERE 절 검색 조건 사례

-- WHERE 조건 JOIN  
 SELECT A.PLAYER_NAME  
      , A.BACK_NO  
      , A.TEAM_ID  
      , B.TEAM_NAME  
      , B.REGION_NAME  
   FROM PLAYER A, TEAM B  
  WHERE A.TEAM_ID = B.TEAM_ID  
    AND A.POSITION = 'GK'  
  ORDER BY A.BACK_NO;  
 
  
 --ANSI  
 SELECT A.PLAYER_NAME  
      , A.BACK_NO  
      , A.TEAM_ID  
      , B.TEAM_NAME  
      , B.REGION_NAME  
   FROM PLAYER A  
  INNER JOIN TEAM  B  
     ON A.TEAM_ID   = B.TEAM_ID  
  WHERE A.POSITION = 'GK'  
  ORDER BY A.BACK_NO;
  • ALIAS 명을 지정 하였으나 테이블 명을 사용 할 경우 열명이 부적합니다의 오류가 발생 한다.
SELECT PLAYER.PLAYER_NAME  -- 열명이 부적합 합니다. 발생  
     , A.BACK_NO  
     , A.TEAM_ID  
     , B.TEAM_NAME  
     , B.REGION_NAME  
  FROM PLAYER A  
 INNER JOIN TEAM  B  
    ON A.TEAM_ID   = B.TEAM_ID  
 WHERE  A.POSITION = 'GK'  
 ORDER BY A.BACK_NO; 

3. Non Equal Join

  • 연산자가 아닌 다른 (between >= , <=, >, <)연산자를 사용하여 join을 수행한다.
  • 두 개의 테이블이 PK-FK로 연관관계를 가지거나 논리적으로 같은 값이 존재하는 경우에는 "=" 연산자를 이용하여 EQUI JOIN을 사용한다.
  • 그러나 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에는 EQUI JOIN을 사용할 수 없으며 Non Equal Join을 사용 할 수 있으나 모델링에 따라 사용 하지 못하는 경우가 발생된다.
  • 예)
  
  SELECT E.ENAME  
       , E.JOB  
       , E.SAL  
       , S.GRADE  
    FROM EMP E, SALGRADE S  
   WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

  • 사원(EMP) 테이블에서 사원들의 급여가 급여등급(SALGRADE) 테이블의 등급으로 표시되기 위해서는 "=" 연산자로 JOIN을 이용할 수가 없다.

  • 그림 Ⅱ-1-17을 보면 SCOTT라는 사원을 예로 들어 급여는 3,000달러($)이고, 3,000달러($)는 급여등급 테이블에서 2,001 ~ 3,000달러($) 사이의 4급에 해당하는 급여등급이라는 값을 얻을 수 있다.
  • 예) 14 명 모두에 대한 급여 등급 쿼리
SELECT E.ENAME 사원명  
     , E.SAL 급여  
     , S.GRADE 급여등급   
  FROM EMP E, SALGRADE S   
 WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

4. 3개 이상의 table join

-- WHERE JOIN  
 SELECT P.PLAYER_NAME   선수명  
      , P.POSITION      포지션  
      , T.REGION_NAME   연고지  
      , T.TEAM_NAME     팀명  
      , S.STADIUM_NAME  구장명  
   FROM PLAYER P, TEAM T, STADIUM S  
  WHERE P.TEAM_ID  = T.TEAM_ID  
    AND T.STADIUM_ID = S.STADIUM_ID  
  ORDER BY 선수명;  
    

-- ANSI   
 SELECT P.PLAYER_NAME    선수명  
      , P.POSITION       포지션  
      , T.REGION_NAME    연고지  
      , T.TEAM_NAME      팀명  
      , S.STADIUM_NAME   구장명  
   FROM PLAYER P   
  INNER JOIN TEAM T  
     ON P.TEAM_ID = T.TEAM_ID  
  INNER JOIN STADIUM S  
     ON T.STADIUM_ID = S.STADIUM_ID  
  ORDER BY 선수명;
  • 지금까지 JOIN에 대한 기본적인 사용법을 확인해 보았는데, JOIN이 필요한 기본적인 이유는 과목1에서 배운 정규화에서부터 출발한다.
  • 정규화란 불필요한 데이터의 정합성을 확보하고 이상현상(Anomaly) 발생을 피하기 위해, 테이블을 분할하여 생성하는 것이다.
  • 사실 데이터웨어하우스 모델처럼 하나의 테이블에 모든 데이터를 집중시켜놓고 그 테이블로부터 필요한 데이터를 조회할 수도 있다.
  • 그러나 이렇게 됐을 경우, 가장 중요한 데이터의 정합성에 더 큰 비용을 지불해야 하며, 데이터를 추가, 삭제, 수정하는 작업 역시 상당한 노력이 요구될 것이다.
  • 성능 측면에서도 간단한 데이터를 조회하는 경우에도 규모가 큰 테이블에서 필요한 데이터를 찾아야 하기 때문에 오히려 검색 속도가 떨어질 수도 있다.
  • 테이블을 정규화하여 데이터를 분할하게 되면 위와 같은 문제는 자연스럽게 해결 된다.
  • 그렇지만 특정 요구조건을 만족하는 데이터들을 분할된 테이블로부터 조회하기 위해서는 테이블 간에 논리적인 연관관계가 필요하고 그런 관계성을 통해서 다양한 데이터들을 출력할 수 있는 것이다.
  • 그리고, 이런 논리적인 관계를 구체적으로 표현하는 것이 바로 SQL 문장의 JOIN 조건인 것이다.
  • 관계형 데이터베이스의 큰 장점이면서, SQL 튜닝의 중요 대상이 되는 JOIN을 잘못 기술하게 되면 시스템 자원 부족이나 과다한 응답시간 지연을 발생시키는 중요 원인이 되므로 JOIN 조건은 신중하게 작성해야 한다.

출처 : http://www.gurubee.net/lecture/2375

반응형

'DB > SQL' 카테고리의 다른 글

SQL의 종류 DDL, DML, DCL 이란?  (0) 2022.02.25
Foreign Key 제약 설정 Delete Rule  (0) 2020.04.21
WHERE 절의 조합(AND / OR / NOT / IN)  (0) 2020.04.21
[SQL] join의 on절과 where절 차이  (0) 2020.04.10

+ Recent posts