WHERE 절로 조인 된 쿼리와 실제 JOIN을 사용하는 쿼리간에 중요한 차이점이 있습니까?


32

에서 알아 SQL 어려운 방법 (운동 여섯) , 저자의 선물 다음 쿼리 :

SELECT pet.id, pet.name, pet.age, pet.dead
    FROM pet, person_pet, person
    WHERE
    pet.id = person_pet.pet_id AND
    person_pet.person_id = person.id AND
    person.first_name = "Zed";

그런 다음 계속해서 말합니다.

실제로 이러한 종류의 쿼리를 "조인"이라고하는 다른 방법이 있습니다. 나는 그 개념이 혼란 스럽기 때문에 지금은 그 개념을 피하고 있습니다. 지금은 이런 식으로 테이블을 조인하는 방법을 고수하고 이것이 느리거나 "낮은 클래스"라고 말하는 사람들을 무시하십시오.

그게 사실입니까? 그 이유는 무엇?


3
나는 생각하지 않지만 쿼리 실행에 차이가 있는지 알아보기 위해 EXPLAIN을 시도 할 수 있습니다.
GrandmasterB

6
나는 제목이 "열심히 혼란스러워"라는 개념을 건너 뛰는 제목에서 "어려운 길"이라는 작품의 상충되는 신호를 지적하고 싶습니다. 그러나 "어려운 길"이 무엇인지에 대한 나의 개념은 틀릴 수도 있습니다. 그러나 다시는 아닐 수도 있습니다.
Mindwin

7
JOIN은 실제 필터에 대한 WHERE 부분을 남기고 읽기 쉽게하기 위해 의도 (조인 테이블)를 매우 잘 전달합니다. (maamaa 기타 영향 포함)
Th 00

2
저자가 간단한 조인을 작성하는 데 방해가되지 않으면 SQL을 어려운 방법으로 배우는 것입니다! ThomasS가 JOIN을 사용하여 말한 것처럼 의도가 명확 해지고 WHERE 절이 훨씬 간단 해집니다. 또한 JOIN을 사용하면 SQL을 뒷받침하는 집합 이론을 더 잘 보여줍니다.
다니엘 Hollinrake

1
"하지만 우리는 craaazzzyyyy 바나나이기 때문에 우리는이 기본 개념을 건너 뛸 것입니다." 나는 배우기 위해 다른 출처를 찾고 있다고 생각합니다. 어느 시점에서 외부 조인과 교차 조인을 수행해야하며 어떻게해야하는지 알아야합니다.
Maurice Reeves

답변:


23

저자의 접근 방식으로 OUTER JOIN을 가르치는 것이 훨씬 더 어려워 질 것입니다. INNER JOIN의 ON 절은 다른 많은 것들처럼 마음에 들지 않았습니다. 어쩌면 옛날 방식을 배운 적이 없기 때문일 수 있습니다. 나는 우리가 그것을 제거 한 이유가 있다고 생각하고 싶습니다. 그것은 밀착하지 않고이 방법을 저 클래스라고 부릅니다.

저자가 만든 매우 좁은 시나리오에서는 사실입니다.

  • ON을 사용하는 복잡한 SQL의 엔트리 레벨
  • 외부 참여가 아닌 JOIN / INNER JOIN 만 고려
  • 다른 사람의 코드를 읽을 필요가없고 ON 사용 / 코드 사용 / 사용 경험이있는 격리 된 코더입니다.
  • 많은 테이블을 가진 복잡한 쿼리가 필요하지 않습니다.

교육 진행의 일환으로, 그것을 분해하고 자연스럽게 진행하는 것이 더 쉽다고 생각합니다.

Select * from table
select this, something, that from table
select this from table where that = 'this'
select this from table join anothertable on this.id = that.thisid

테이블 조인 및 필터링 개념은 실제로 동일하지 않습니다. 저자가 다음과 같이 오래되거나 더 이상 사용되지 않는 것을 가르치려는 경우가 아니라면 외부 조인을 배울 때 올바른 구문을 배우면 더 많은 이월이 가능 *= or =*합니다.


5
JOIN 문이 추가 된 이유는 외부 조인을 표현할 표준이 없기 때문에 각 데이터베이스 공급 업체가 자체 "특수"(호환되지 않는) 구문을 가지고 있기 때문입니다. IIRC Oracle에는 왼쪽 또는 오른쪽 외부 조인 이 있었 *=거나 =*표시했습니다. 다른 하나는 |=연산자를 사용하여 지원되는 왼쪽 외부 조인 만 사용했습니다 .
TMN

1
@TMN IIRC Oracle이 사용 +=했거나 사용 했을 수도 있습니다 =+. 나는 믿고 *=거래-SQL (사이베이스 (Sybase) 이후 MS-SQL)이었다. 그래도 좋은 지적입니다.
David

1
복잡해지기 시작하는 곳 (IMHO)은 내부 및 외부 조인이 혼합 된 경우입니다. 그런 상황에서, 나는 때때로 WHERE절 에서 조인을 수행하는 "저급"기술로 되돌아 간다고 고백 할 것이다 . (이것이 세타 조인 이라고 들었지만 이것이 맞는지 잘 모르겠습니다.)
David

"보다 큼"또는 "같음"과 같은 IIRC 연산자는 때때로 "세타 연산자"로 지칭되지만 Google 검색은 미적분학에서 일부 연산으로 이어집니다.
Walter Mitty

12

속도가 느린 지 여부는 Query Optimizer 및 쿼리를 능률화하는 방법에 따라 다릅니다 (작성한 내용이 실제로 실행되는 것이 아닙니다). 그러나이 인용문의 큰 문제점은 완전히 다른 방식으로 작동하는 여러 유형의 조인이 있다는 사실을 완전히 무시한다는 것입니다. 예를 들어, (이론적으로)에 대한 말은 ( 와 )에 inner joins대해서는 사실이 아닙니다 .outer joinsleft joinsright joins


9
+1 다른 유형의 조인의 경우. 내 조인의 대부분은 INNER JOIN또는 LEFT OUTER JOIN입니다. 그들은 "정말 혼란스럽지 않다". SQL은 혼란스러워 질 수 있지만 이것은 그 예가 아닙니다.
mgw854

주제와 그러나 문은 달라야 가입 유형 또는 조인의 종류 ?
user1451111

9

저자는 기존 구문이나 새로운 구문을 사용할 수있는 간단한 사례를 제시합니다. 테이블을 조인하는 것이 기본적인 SQL 쿼리 개념이기 때문에 조인이 혼란스러워한다는 그의 진술에 동의하지 않습니다. 따라서 저자는 여러 테이블 쿼리 예제를 수행 할뿐만 아니라 의견이있는 진술을하기 전에 JOINS의 작동 방식을 설명하는 데 어느 정도 시간을 소비했을 것입니다.

새로운 구문을 사용해야합니다. 이에 대한 주요 주장은 쿼리에 다음이 포함된다는 것입니다.

  • 기준 선택
  • 가입 기준
  • 필터 기준

이전 스타일을 사용하면 결합 및 필터 기준이 결합되어보다 복잡한 경우 혼동 될 수 있습니다.

또한 filter 절에서 조인 기준을 잊어 버리면 데카르트 곱을 얻을 수 있습니다.

 person_pet.person_id = person.id

이전 구문을 사용합니다.

최신 구문을 사용하면 INNER, LEFT OUTER 등을 원하는지 여부에 중요한 조인 발생 방법도 지정되므로 IMHO가 조인 테이블에 익숙하지 않은 사용자의 가독성을 높이는 JOIN 구문과 관련하여 더 명확합니다.


5

쿼리 파서는 작성 방법에 관계없이 동등한 쿼리에 대해 동등한 내부 표현을 생성해서는 안됩니다. 저자는 방금 SQL-92 구문을 사용하기 때문에 "구식"또는 "낮은 클래스"라고 볼 수 있습니다. 내부적으로 파서와 최적화 프로그램은 동일한 쿼리 계획을 생성해야합니다.


5

*=외부 조인 구문을 포함하여 SQL을 이런 식으로 배웠습니다 . 나에게 모든 관계가 동일한 우선 순위를 부여 받고 쿼리를 일련의 질문으로 설정하는 데 더 나은 작업을 수행했기 때문에 매우 직관적이었습니다. 무엇을 원하십니까? 어디에서 원하십니까? 어느 것을 원하십니까?

이렇게함으로써 join구문을, 그것은 더 강하게 관계쪽으로 생각 과정을 방해. 그리고 개인적으로, 테이블과 관계가 섞여있는 코드를 훨씬 덜 읽을 수 있습니다.

적어도 MSSQL에서는 동일한 조인 순서를 사용한다고 가정하면 쿼리 성능에 의미있는 차이가 없습니다. 즉, 이런 식으로 SQL을 배우고 사용하는 데에는 분명하고 문제가 있습니다. 관계 중 하나를 잊어 버리면 예기치 않은 교차 ​​제품이 생깁니다. 사소한 크기의 데이터베이스에서 엄청나게 비싸고 (비 선택자에게는 위험합니다!) join스타일 구문을 사용할 때 관계를 잊어 버리기가 훨씬 어렵습니다 .


7
그것은 A의 관계형 데이터베이스, 그래서 관계는 쿼리에 매우 중요하다. 개인적으로 진정한 필터 (foo.x = 5)와 관계 (foo.x = bar.x)를 혼합하는 쿼리를 이해하는 것이 훨씬 어렵다는 것을 알게되었습니다. 엔진은이를 조인으로 쉽게 최적화 할 수 있지만, 인간은 본질적으로 세트 및 서브 세트와 달리 행 단위로 추론해야합니다.
Aaronaught

4

고려해야 할 두 가지 측면이 있습니다 : 성능유지 보수성 / 가독성 .

유지 보수성 / 가독성

나는 당신이 게시 한 원래의 쿼리보다 더 나은 / 나쁜 예라고 생각하는 다른 쿼리를 선택했습니다.

당신에게 더 좋아 보이고 더 읽기 쉬운 것은 무엇입니까?

select
    e.LoginID,
    DepartmentName = d.Name
from HumanResources.Employee e
inner join HumanResources.EmployeeDepartmentHistory edh
on e.BusinessEntityID = edh.BusinessEntityID
inner join HumanResources.Department d
on edh.DepartmentID = d.DepartmentID
where d.Name = 'Engineering';

또는...

select
    e.LoginID,
    DepartmentName = d.Name
from HumanResources.Employee e, 
HumanResources.EmployeeDepartmentHistory edh,
HumanResources.Department d
where e.BusinessEntityID = edh.BusinessEntityID
and edh.DepartmentID = d.DepartmentID
and d.Name = 'Engineering';

개인적으로, 첫 번째 것은 꽤 읽을 수 있습니다. 우리는을 사용하여 테이블을 조인 INNER JOIN하고 있음을 알 수 있습니다. 즉, 후속 조인 절에서 일치하는 행을 가져옵니다 (예 : "BusinessEntityID에서 EmployeeDepartmentHistory를 사용하여 Employee에 참여하고 해당 행 포함").

후자는 쉼표가 아무 의미가 없습니다. 모든 WHERE절 술어로 무엇을하고 있는지 궁금합니다 .

전자는 내 뇌가 생각하는 것처럼 더 많이 읽습니다. 매일 매일 SQL과 조인을 위해 쉼표를 봅니다. 다음 단계로 안내합니다.

실제로 이러한 종류의 쿼리를 "조인"이라고하는 다른 방법이 있습니다.

그들은 모두 조인입니다. 쉼표도 조인입니다. 저자가 실제로 그들을 몰락이라고 부르지 않는다는 사실은 분명하지 않습니다. 분명해야합니다. 당신은 당신이 지정 여부, 관계형 데이터를 결합하고 JOIN,.

공연

이것은 RDBMS에 따라 달라집니다. Microsoft SQL Server를 대표해서 만 말할 수 있습니다. 성능 측면에서 이들은 동등합니다. 당신은 어떻게 알 수 있습니까? 실행 후 계획을 캡처하고 이러한 각 명령문에 대해 SQL Server가 정확히 수행하는 작업을 확인하십시오.

여기에 이미지 설명을 입력하십시오

위의 이미지에서 위의 두 쿼리를 모두 사용하고 있으며 조인에 대한 명시 적 문자 ( JOINvs ,) 만 다릅니다 . SQL Server는 똑같은 일을합니다.

개요

쉼표를 사용하지 마십시오. 명시 적 JOIN진술을 사용하십시오 .


WHERE 절을 사용하는 변형이 동일하다는 것을 깨닫기 오래 전에 INNER JOIN을 배웠으며 두 예제 모두 나에게 읽기 쉽습니다. WHERE와 쉼표가있는 것이 더 읽기 쉽습니다. 그것이 떨어지는 곳은 비교적 간단한 쿼리가 아니라 큰 복잡한 쿼리에 있다고 생각합니다.
Robert Harvey

요점은 쉼표 변형이 관계형 조인이 아니라고 생각하는 것이 전혀 정확하지 않다는 것입니다.
토마스 스트링거

쉼표를 조인으로 잘못 해석하는 것 같습니다. 쉼표는 단순히 테이블을 분리합니다. 쉼표가 아닌 조인을 만드는 조건입니다.
Robert Harvey

1
나는 술어절에서 어떤 일도 일어나지 않는다고 가장 확실하게 말할 수있다. 관계형 쿼리의 구문을 잘못 해석하고 있다고 생각합니다. WHERE 절없이 쉼표 결합을 시도 했습니까? 여전히 작동합니다. 직교 조인입니다. 쉼표를 사용하여 얻는 것이 무엇이라고 생각하십니까? 문자를 저장하려한다고 말하지 마십시오.
Thomas Stringer

1
나는 당신의 의도가 더 명확하기 때문에 첫 번째 것이 더 좋다고 말할 것입니다. 모호성이 훨씬 적습니다.
다니엘 Hollinrake

4

아니요, 전혀 사실이 아닙니다. 저자는 혼란을 위해 독자를 설정하고 표준 구문과 그가 선호하는이 오래된 변형 간의 구조적 차이를 피하는화물 컬트 프로그래밍을 장려합니다. 특히 복잡한 WHERE 절을 사용하면 쿼리가 특별한 이유를 파악하기가 더 어려워집니다.

그의 예는 독자가 엄청나게 많은 혼란을 가지고있는 의미의 정신지도를 생성하게한다.

SELECT pet.id, pet.name, pet.age, pet.dead
    FROM pet, person_pet, person
    WHERE
    pet.id = person_pet.pet_id AND
    person_pet.person_id = person.id AND
    person.first_name = "Zed";

대략 위의 내용은 다음과 같습니다.

모든 애완 동물, person_pet 및 애완 동물 ID가 person_pet의 pet_id와 일치하고 해당 레코드의 person_id가 FIRST_NAME이 "Zed"인 사람의 person_id와 일치하는 사람의 애완 동물 ID, NAME, AGE 및 DEAD를 가져옵니다.

이와 같은 멘탈 맵을 사용하면 독자 (어떤 이유로 SQL을 작성하는 독자)는 하나 이상의 테이블을 생략하여 실수를 쉽게 할 수 있습니다. 이러한 방식으로 작성된 코드 리더는 SQL 작성자가 수행하려는 작업을 정확하게 파악하기 위해 더 열심히 노력해야합니다. ( "Harder"는 구문 강조 표시 유무에 관계없이 SQL을 읽는 수준에 있지만 여전히 0보다 큰 차이입니다.)

JOIN이 일반적인 이유가 있으며 이는 오래된 고전적인 "관심의 절정"canard입니다. 특히, SQL 쿼리의 경우 데이터 구성 방식과 데이터 필터링 방식분리 해야 할 충분한 이유 가 있습니다.

쿼리가보다 명확하게 작성된 경우

SELECT pet.id, pet.name, pet.age
FROM pet
  JOIN person_pet ON pet.id = person_pet.pet_id
  JOIN person ON person.id = person_pet.person_id
WHERE 
  person.first_name = "Zed";

그런 다음 독자는 요구되는 구성 요소를 명확하게 구분합니다. 이 쿼리의 고유 한 필터는 구성 요소가 서로 관련되는 방식과 분리되어 있으며 각 관계의 필수 구성 요소는 필요한 위치 바로 옆에 있습니다.


물론 현대식 데이터베이스 시스템은 두 스타일간에 의미있는 차이를 보지 않아야합니다. 그러나 데이터베이스 성능이 유일한 고려 사항이라면 SQL 쿼리에는 공백이나 대문자가 없을 것입니다.


2
나는 이것을 여러 번 자제하는 것을 들었으므로, 악마의 옹호자 역할을 해보자. X 어려운 방법은 기술적 깊이에 관한 것입니다. SQL에 대해 잘 알고있는 사람은 실제로 두 가지 접근 방식이 생성되는 출력 측면에서 동등 하다는 것을 알아야합니다 .
Robert Harvey

1
알 수 있지만 저자는 단순히 적절한 SQL 서버와 동등한 진술이라고 주장하는 것이 아닙니다. 그들은 JOIN을 사용하는 것이 "혼란"이라고 주장하는데, 이는 더티 코드가 기다리는 경로입니다. ( "아니, LINQ를 사용하지 않는, 단지 손으로 당신을위한 문을 작성합니다." "컴파일러는 내가이 메소드를 호출 것에 대해 상관하지 않는다, 그래서 FN1 이름을하지 않을 이유가 없다")
DougM

3

남자는 고전적인 오류를 만들고 있습니다. 그는 특정 구현으로 추상적 인 개념을 가르치려고 노력하고 있습니다. 당신이 그렇게하자마자 당신은 이런 종류의 혼란에 빠지게됩니다.

기본 데이터베이스 개념을 먼저 학습 한 다음이를 설명하는 한 가지 방법으로 SQL을 보여 주어야합니다.

왼쪽과 오른쪽 조인은 너무 중요하지 않다고 주장 할 수 있습니다. 외부 조인, 이전 *==*구문을 사용할 수 있습니다 .

이제 구문이 더 단순하지만 간단한 쿼리에 대해서만 주장 할 수 있습니다. 이 버전으로 복잡한 쿼리를 시작하자마자 끔찍한 혼란에 빠질 수 있습니다. "새"구문이 도입되지 않아 복잡한 쿼리를 수행 할 수 있으며, 읽기 쉽고 유지 관리가 쉬운 방식으로 복잡한 쿼리를 수행했습니다.


3
"Learn X the Hard Way"는 다른 학습 방식입니다. 코드를 작성하고 나중에 이해하십시오.
Robert Harvey

7
@RobertHarvey 그것은 다른 학습 방식이 아니라 표준입니다. 나중에 바퀴가 빠질 때 여전히 제 위치에있는 경우에만 발생합니다. 테이블 이이 방법에 대한 자신감을 가질 수있는 직사각형 셀 배열이라고 생각하는 SQL을 작성하는 사람들이 너무 많았습니다.
Tony Hopkinson

2

이 예는 내부 JOIN을 사용한 간단한 재구성과 동일합니다. 차이점은 JOIN 구문이 허용하는 추가 가능성에만 있습니다. 예를 들어, 관련된 두 테이블의 열이 처리되는 순서를 지정할 수 있습니다. 예를 들어 https://stackoverflow.com/a/1018825/259310을 참조 하십시오 .

수신 된 지혜는 의심 스러울 때 더 읽기 쉬운 방식으로 쿼리를 작성하는 것입니다. 그러나 JOIN 또는 WHERE 공식이 읽기 쉬운 지 여부는 개인 취향의 문제인 것으로 보이므로 두 가지 형식이 널리 퍼져 있습니다.


좋은 대답이지만 WHERE, JOIN명령문 에서 또는 절 을 사용하는지 여부 는 실제로 쿼리 최적화 프로그램에 따라 성능에 영향을 줄 수 있습니다. 나는 그것이 두 번 이상 일어나는 것을 보았습니다.
로크

성능에 미치는 영향은 다음과 같습니다. 암시 적 조인을 사용하면 쿼리 최적화 프로그램에 더 많은 옵션을 사용하여 쿼리를 최적화 할 수 있습니다. 이는 좋은 것처럼 보이지만 문제가 될 수 있습니다. 구체적으로, 쿼리 최적화 기는 개발 및 프로덕션에서 다른 방식으로 쿼리를 튜닝 할 수있다. 옵티마이 저는 성능을 저하시키는 튜닝에 속일 수 있습니다. 내 권장 사항은 명시 적 조인 구문을 사용하고 조인이 성능을 예측할 수 있도록 인덱스가있는 열을 사용하고 있는지 확인하는 것입니다.
Michael Potter

2

SQL을 배웠을 때 INNER JOIN, LEFT JOIN 등 양식은 존재하지 않았습니다. 다른 답변에서 이미 언급했듯이 SQL의 다른 방언은 각각 고유 구문을 사용하여 외부 조인을 구현했습니다. 이로 인해 SQL 코드의 이식성이 손상되었습니다. 언어를 다시 가져 오려면 약간의 변경이 필요했으며 LEFT JOIN 등이 해결되었습니다.

모든 INNER JOIN에 대해 WHERE 절의 조인 조건에 해당하는 쉼표 조인을 작성할 수 있습니다. 이전 양식을 좋아하는 것에서 새 양식을 선호하는 것으로 마이그레이션하는 데 시간이 걸렸습니다. 분명히 Learning the the Hard Way의 저자는 여전히 낡은 방법이 더 쉽다고 생각합니다.

차이점이 있습니까? 예, 있습니다. 첫 번째는 ON 절이있는 INNER JOIN이 이전 스타일 조인보다 저자의 의도를 더 명확하게 보여줍니다. ON 절이 실제로는 조인 조건이며 다른 종류의 제한이 아니라는 것이 더 분명합니다. 따라서 이전 스타일보다 읽을 때 INNER JOIN을 사용하는 코드를 쉽게 배울 수 있습니다. 다른 사람의 코드를 유지할 때 중요합니다.

두 번째 차이점은 새로운 스타일로 인해 쿼리 최적화 프로그램이 승리 전략을 쉽게 찾을 수 없다는 것입니다. 이것은 매우 작은 효과이지만 실제로 적용됩니다.

세 번째 차이점은 INNER JOIN (또는 일반 JOIN)을 사용하여 배울 때 LEFT JOIN 등을 쉽게 배울 수 있다는 것입니다.

그 외에는 실질적인 차이가 없습니다.


0

당신이 세트와 형식적인 논리의 관점에서 생각하는지에 달려 있습니다 .....

그런 다음 "join"키워드를 사용하지 않으면 공식 논리에서 SQL로보다 간단하게 진행할 수 있습니다.

그러나 99 %의 사람들처럼 수학 학위에서 공식적인 논리를 즐기지 않았다면 join 키워드를 사용하면 더 쉽게 배울 수 있습니다. 예전에는 공식 논리 쿼리를 작성하는 다른 방법으로 대학에서 SQL을 발표했습니다 ....

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.