여러 테이블에서 SQL 쿼리 반환 데이터
다음을 알고 싶습니다.
- 데이터베이스의 여러 테이블에서 데이터를 얻는 방법은 무엇입니까?
- 이를 위해 어떤 유형의 방법이 있습니까?
- 조인과 노조 란 무엇이며 서로 어떻게 다른가요?
- 언제 다른 것을 사용해야합니까?
내 (예 : PHP) 응용 프로그램에서 이것을 사용할 계획이지만 데이터베이스에 대해 여러 쿼리를 실행하지 않으려면 단일 쿼리에서 여러 테이블의 데이터를 가져 오기 위해 어떤 옵션이 필요합니까?
참고 : PHP 대기열에서 지속적으로 발생하는 수많은 질문에 대한 잘 작성된 안내서에 링크하고 싶기 때문에이 글을 작성하고 있으므로 답변을 게시 할 때 더 자세히 링크 할 수 있습니다.
답은 다음과 같습니다.
1 부-조인 및 조합
이 답변은 다음과 같습니다.
- 1 부
- 내부 조인을 사용하여 둘 이상의 테이블 조인 ( 추가 정보 는 Wikipedia 항목 참조 )
- 통합 쿼리를 사용하는 방법
- 왼쪽 및 오른쪽 외부 조인 (이 stackOverflow 답변 은 조인 유형을 설명하기에 우수합니다)
- 쿼리를 교차 (및 데이터베이스가 지원하지 않는 경우 쿼리를 재생산하는 방법)-이것은 SQL-Server의 기능 ( info 참조 )이며 처음 에이 모든 것을 작성한 이유의 일부입니다 .
- 2 부
- 하위 쿼리-현재 상태, 사용 가능한 위치 및주의해야 할 사항
- 데카르트가 AKA에 합류-아, 불행!
데이터베이스의 여러 테이블에서 데이터를 검색하는 방법에는 여러 가지가 있습니다. 이 답변에서는 ANSI-92 조인 구문을 사용합니다. 이것은 이전 ANSI-89 구문을 사용하는 다른 많은 자습서와 다를 수 있습니다 (89에 익숙하다면 훨씬 덜 직관적 인 것처럼 보일 수 있지만 시도해 보는 것만 큼) 훨씬 쉽습니다. 쿼리가 더 복잡 해지는 시점을 이해합니다. 왜 사용합니까? 성능 향상이 있습니까? 짧은 대답은 '아니요, 그러나 입니다 일단 익숙해지면 쉽게 읽을. 이 구문을 사용하여 다른 사람들이 작성한 쿼리를 읽는 것이 더 쉽습니다.
또한 사용할 수있는 자동차를 추적 할 수있는 데이터베이스가있는 소형 마당의 개념을 사용하려고합니다. 소유자가 IT 컴퓨터 담당자로 고용했으며 모자를 놓을 때 요청한 데이터를 삭제할 수 있기를 기대합니다.
최종 테이블에서 사용할 다수의 조회 테이블을 만들었습니다. 이것은 우리에게 일하기에 합리적인 모델을 제공 할 것입니다. 먼저 다음 구조를 가진 예제 데이터베이스에 대해 쿼리를 실행합니다. 나는 시작할 때 발생하는 일반적인 실수를 생각하고 무엇이 잘못되었는지 설명하고 실수를 바로 잡는 방법을 보여줄 것이다.
첫 번째 테이블은 단순히 색상 목록이므로 자동차 야드에 어떤 색상이 있는지 알 수 있습니다.
mysql> create table colors(id int(3) not null auto_increment primary key,
-> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | varchar(15) | YES | | NULL | |
| paint | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> insert into colors (color, paint) values ('Red', 'Metallic'),
-> ('Green', 'Gloss'), ('Blue', 'Metallic'),
-> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from colors;
+----+-------+----------+
| id | color | paint |
+----+-------+----------+
| 1 | Red | Metallic |
| 2 | Green | Gloss |
| 3 | Blue | Metallic |
| 4 | White | Gloss |
| 5 | Black | Gloss |
+----+-------+----------+
5 rows in set (0.00 sec)
브랜드 표는 야드에서 판매 할 수있는 자동차 브랜드를 나타냅니다.
mysql> create table brands (id int(3) not null auto_increment primary key,
-> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| brand | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
mysql> insert into brands (brand) values ('Ford'), ('Toyota'),
-> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from brands;
+----+--------+
| id | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 3 | Nissan |
| 4 | Smart |
| 5 | BMW |
+----+--------+
5 rows in set (0.00 sec)
모델 테이블은 다른 유형의 자동차를 다루며, 실제 자동차 모델이 아닌 다른 자동차 유형을 사용하는 것이 더 간단합니다.
mysql> create table models (id int(3) not null auto_increment primary key,
-> model varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| model | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from models;
+----+--------+
| id | model |
+----+--------+
| 1 | Sports |
| 2 | Sedan |
| 3 | 4WD |
| 4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)
마지막으로 모든 다른 테이블을 묶으십시오. ID 필드는 실제로 자동차를 식별하는 데 사용되는 고유 로트 번호입니다.
mysql> create table cars (id int(3) not null auto_increment primary key,
-> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | int(3) | YES | | NULL | |
| brand | int(3) | YES | | NULL | |
| model | int(3) | YES | | NULL | |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1),
-> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
| 1 | 1 | 2 | 1 |
| 2 | 3 | 1 | 2 |
| 3 | 5 | 3 | 1 |
| 4 | 4 | 4 | 2 |
| 5 | 2 | 2 | 3 |
| 6 | 3 | 5 | 4 |
| 7 | 4 | 1 | 3 |
| 8 | 2 | 2 | 1 |
| 9 | 5 | 2 | 3 |
| 10 | 4 | 5 | 1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)
이것은 우리에게 다른 유형의 조인에 대한 아래의 예를 설명하기에 충분한 데이터를 제공하고 가치가 있도록 충분한 데이터를 제공합니다.
그래서 그 사장님의 입장에 들어간 사장님은 자신이 가진 모든 스포츠카의 ID 를 알고 싶어합니다 .
이것은 간단한 두 테이블 조인입니다. 모델을 식별하는 테이블과 사용 가능한 재고가있는 테이블이 있습니다. 보시다시피 model
, cars
테이블 의 열에 있는 데이터는 우리가 가진 테이블 의 models
열과 관련이 cars
있습니다. 이제, 우리는 모델 테이블의 ID가 알고 1
에 대해 Sports
너무 조인을 작성할 수 있습니다.
select
ID,
model
from
cars
join models
on model=ID
이 질문이 잘 생겼나요? 두 테이블을 식별했으며 필요한 정보가 포함되어 있으며 조인 할 열을 올바르게 식별하는 조인을 사용합니다.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
아뇨! 첫 번째 쿼리에서 오류가 발생했습니다! 네, 매실입니다. 알다시피, 쿼리에는 실제로 올바른 열이 있지만 그중 일부는 두 테이블에 모두 존재하므로 데이터베이스는 실제 열의 의미와 위치에 대해 혼란스러워합니다. 이 문제를 해결하기위한 두 가지 솔루션이 있습니다. 첫 번째는 훌륭하고 간단 tableName.columnName
합니다. 다음과 같이 데이터베이스의 의미를 정확히 알려주 는 데 사용할 수 있습니다 .
select
cars.ID,
models.model
from
cars
join models
on cars.model=models.ID
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
| 2 | Sedan |
| 4 | Sedan |
| 5 | 4WD |
| 7 | 4WD |
| 9 | 4WD |
| 6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)
다른 하나는 더 자주 사용되며 테이블 별칭이라고합니다. 이 예제의 테이블에는 단순하고 간단한 이름이 있지만 다음과 같이 입력하면 KPI_DAILY_SALES_BY_DEPARTMENT
빨리 오래 될 수 있으므로 간단한 방법으로 테이블의 별명을 지정합니다.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
이제 요청으로 돌아갑니다. 보시다시피 필요한 정보는 있지만 요청하지 않은 정보도 있으므로 요청에 따라 스포츠카 만 가져 오려면 명세서에 where 절을 포함시켜야합니다. 테이블 이름을 계속 사용하는 대신 테이블 별칭 방법을 선호하므로이 시점부터 계속 사용하겠습니다.
분명히 쿼리에 where 절을 추가해야합니다. ID=1
또는로 스포츠카를 식별 할 수 있습니다 model='Sports'
. ID가 색인화되고 기본 키 (및 입력 횟수가 줄어듦)를 쿼리에서 사용할 수 있습니다.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
빙고! 사장님은 행복합니다. 물론, 보스가되고 그가 요구 한 것에 만족하지 않으면 서 그는 정보를 보고 색상도 원한다고 말합니다 .
자, 우리는 이미 작성한 쿼리의 좋은 부분을 가지고 있지만 색상 인 세 번째 테이블을 사용해야합니다. 이제 주요 정보 테이블 cars
에 자동차 색상 ID가 저장되고 색상 ID 열로 다시 연결됩니다. 따라서 원본과 비슷한 방식으로 세 번째 테이블을 조인 할 수 있습니다.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
젠장, 테이블이 올바르게 조인되고 관련 열이 연결되었지만 방금 연결 한 새 테이블에서 실제 정보 를 가져 오는 것을 잊었습니다 .
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)
맞습니다. 잠시 동안 우리의 상사입니다. 이제이 중 일부에 대해 좀 더 자세히 설명하겠습니다. 보시다시피, from
명령문 의 절은 기본 테이블과 연결됩니다 (저는 종종 조회 또는 차원 테이블이 아닌 정보를 포함하는 테이블을 사용합니다. 쿼리는 모두 전환 된 테이블에서도 잘 작동하지만, 의미가없는 경우 우리는이 쿼리로 돌아와서 몇 개월 만에 읽었으므로 이해하기 쉽고 좋은 쿼리를 작성하는 것이 가장 좋습니다. 직관적으로 배치하고 멋진 들여 쓰기를 사용하여 모든 것이 명확하게되도록하십시오. 계속해서 다른 사람들을 가르치려면 이러한 특성을 쿼리에 주입하십시오 (특히 문제를 해결하려는 경우).
이러한 방식으로 점점 더 많은 테이블을 연결하는 것이 전적으로 가능합니다.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
join
명령문 에 둘 이상의 열을 조인하려는 테이블을 포함하는 것을 잊었지만 여기에 예가 있습니다. 경우 models
테이블 따라서 브랜드 별 모델을 가지고도라는 칼럼했다 brand
에 다시 연결 brands
상의 테이블 ID
필드, 그것은이 같이 할 수있다 :
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
and b.brand=d.ID
where
b.ID=1
위의 쿼리는 조인 된 테이블을 기본 테이블에 연결할 cars
뿐만 아니라 이미 조인 된 테이블 간의 조인도 지정합니다. 이 작업을 수행하지 않으면 데카르트 조인 (dcarsian join)이 발생합니다. 데카르트 조인은 정보가 데이터베이스에 결과를 제한하는 방법을 알려주지 않기 때문에 행이 반환되는 것이므로 쿼리는 기준에 맞는 모든 행을 반환 합니다.
따라서 데카르트 조인의 예를 제공하려면 다음 쿼리를 실행하십시오.
select
a.ID,
b.model
from
cars a
join models b
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 1 | Sedan |
| 1 | 4WD |
| 1 | Luxury |
| 2 | Sports |
| 2 | Sedan |
| 2 | 4WD |
| 2 | Luxury |
| 3 | Sports |
| 3 | Sedan |
| 3 | 4WD |
| 3 | Luxury |
| 4 | Sports |
| 4 | Sedan |
| 4 | 4WD |
| 4 | Luxury |
| 5 | Sports |
| 5 | Sedan |
| 5 | 4WD |
| 5 | Luxury |
| 6 | Sports |
| 6 | Sedan |
| 6 | 4WD |
| 6 | Luxury |
| 7 | Sports |
| 7 | Sedan |
| 7 | 4WD |
| 7 | Luxury |
| 8 | Sports |
| 8 | Sedan |
| 8 | 4WD |
| 8 | Luxury |
| 9 | Sports |
| 9 | Sedan |
| 9 | 4WD |
| 9 | Luxury |
| 10 | Sports |
| 10 | Sedan |
| 10 | 4WD |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)
좋은 신, 그건 못 생겼어 그러나 데이터베이스에 관한 한 정확히 요청 된 것입니다. 쿼리에서, 우리는에 대한 요구 ID
에서 cars
와 model
에서 models
. 그러나 테이블을 조인하는 방법 을 지정하지 않았기 때문에 데이터베이스는 첫 번째 테이블의 모든 행과 두 번째 테이블의 모든 행을 일치 시켰 습니다.
좋아, 그래서 보스는 돌아 왔고 더 많은 정보를 원한다. 나는 같은 목록을 원하지만 4WD도 포함합니다 .
그러나 이것은 우리에게 이것을 달성하기 위해 두 가지 다른 방법을 살펴볼 큰 변명을줍니다. 다음과 같이 where 절에 다른 조건을 추가 할 수 있습니다.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
or b.ID=3
위의 내용은 완벽하게 작동하지만 다르게 살펴 보겠습니다. 이것은 union
쿼리의 작동 방식을 보여주는 훌륭한 변명 입니다.
다음은 모든 스포츠카를 반환한다는 것을 알고 있습니다.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
그리고 다음은 모든 4WD를 반환합니다.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
따라서 union all
이들 사이 에 절 을 추가 하면 두 번째 쿼리 결과가 첫 번째 쿼리 결과에 추가됩니다.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
union all
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
| 5 | 4WD | Green |
| 7 | 4WD | White |
| 9 | 4WD | Black |
+----+--------+-------+
7 rows in set (0.00 sec)
보다시피, 첫 번째 쿼리 결과가 먼저 반환되고 두 번째 쿼리 결과가 반환됩니다.
이 예에서는 물론 첫 번째 쿼리를 사용하는 것이 훨씬 쉬웠지만 union
특정 경우에는 쿼리가 훌륭 할 수 있습니다. 서로 쉽게 조인되지 않는 테이블 또는 완전히 관련이없는 테이블의 테이블에서 특정 결과를 반환하는 좋은 방법 입니다. 그러나 따라야 할 몇 가지 규칙이 있습니다.
- 첫 번째 쿼리의 열 유형은 아래의 다른 모든 쿼리의 열 유형과 일치해야합니다.
- 첫 번째 쿼리의 열 이름은 전체 결과 집합을 식별하는 데 사용됩니다.
- 각 쿼리의 열 수는 같아야합니다.
이제 와 사용 의 차이점이 무엇인지 궁금 할 것 입니다. A는 동안 쿼리는 중복을 제거 하지 않습니다. 이것은 오버를 사용할 때 약간의 성능 저하가 있지만 결과가 가치 가 있다는 것을 의미합니다 .하지만 이것에 대해서는 추측하지 않습니다.union
union all
union
union all
union
union all
이 메모에서는 여기에 몇 가지 추가 메모가 있습니다.
- 결과를 주문하려면 a를 사용할 수
order by
있지만 더 이상 별칭을 사용할 수 없습니다. 위의 쿼리order by a.ID
에서 결과를 추가하면 오류가 발생합니다. 결과와 관련 하여 동일한 별칭이 두 쿼리에 모두 사용 되었더라도 열ID
대신 호출a.ID
됩니다. - 우리는 하나의
order by
진술 만 가질 수 있으며 마지막 진술과 같아야합니다.
다음 예제에서는 테이블에 행을 몇 개 더 추가합니다.
Holden
브랜드 테이블에 추가 했습니다. 또한 연속으로 추가 cars
즉 갖는다 color
값 12
색상 표에 대한 언급이 없다 -.
좋아, 보스가 다시 돌아와서 요청을 짖는다-* 우리가 가지고있는 각 브랜드의 수와 그 안에있는 자동차의 수를 원한다! '-전형적인, 우리는 토론의 흥미로운 부분에 도달하고 보스는 더 많은 작업을 원한다 .
바로 우리가해야 할 첫 번째 일은 가능한 브랜드의 전체 목록을 얻는 것입니다.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
이제 이것을 우리의 cars 테이블에 결합하면 다음과 같은 결과를 얻습니다.
select
a.brand
from
brands a
join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Nissan |
| Smart |
| Toyota |
+--------+
5 rows in set (0.00 sec)
물론 어떤 문제입니다-우리는 Holden
내가 추가 한 멋진 브랜드에 대한 언급을 보지 못했습니다 .
조인은 두 테이블 에서 일치하는 행을 찾기 때문 입니다. 유형의 자동차에 데이터 Holden
가 없으므로 반환되지 않습니다. 여기서 outer
조인을 사용할 수 있습니다 . 다른 테이블과 일치하는지 여부에 관계없이 한 테이블의 모든 결과를 반환 합니다 .
select
a.brand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Holden |
| Nissan |
| Smart |
| Toyota |
+--------+
6 rows in set (0.00 sec)
이제 우리는 멋진 집계 함수를 추가하여 카운트를 얻고 보스를 잠시 등 뒤로 내릴 수 있습니다.
select
a.brand,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+--------------+
| brand | countOfBrand |
+--------+--------------+
| BMW | 2 |
| Ford | 2 |
| Holden | 0 |
| Nissan | 1 |
| Smart | 1 |
| Toyota | 5 |
+--------+--------------+
6 rows in set (0.00 sec)
그리고 그와 함께, 보스는 멀리 떨어집니다.
이제 이것을 좀 더 자세히 설명하기 위해 외부 조인은 left
또는 right
유형일 수 있습니다 . 왼쪽 또는 오른쪽은 어떤 테이블이 완전히 포함 되는지 정의합니다 . A left outer join
는 왼쪽 테이블의 모든 행을 포함하는 반면 right outer join
오른쪽 테이블의 모든 결과를 결과 로 가져옵니다.
일부 데이터베이스는 두 테이블 모두full outer join
에서 결과를 가져 오거나 일치시킬 수 있지만 모든 데이터베이스에서 지원되는 것은 아닙니다.
아마 지금 시점에서 아마도 쿼리에서 조인 유형을 병합 할 수 있는지 궁금해 할 것입니다. 그리고 대답은 그렇습니다. 절대로 할 수 있습니다.
select
b.brand,
c.color,
count(a.id) as countOfBrand
from
cars a
right outer join brands b
on b.ID=a.brand
join colors c
on a.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| Ford | Blue | 1 |
| Ford | White | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| BMW | Blue | 1 |
| BMW | White | 1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)
그렇다면 왜 예상 한 결과가 아닌가? 비록 자동차에서 브랜드로의 외부 조인을 선택했지만 색상에 조인으로 지정되지 않았기 때문에 특정 조인은 두 테이블에서 일치하는 결과 만 가져옵니다.
예상 한 결과를 얻는 데 유용한 쿼리는 다음과 같습니다.
select
a.brand,
c.color,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
left outer join colors c
on b.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| BMW | Blue | 1 |
| BMW | White | 1 |
| Ford | Blue | 1 |
| Ford | White | 1 |
| Holden | NULL | 0 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| Toyota | NULL | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)
보시다시피 쿼리에 두 개의 외부 조인이 있고 결과가 예상대로 전달됩니다.
이제 다른 유형의 조인은 어떻습니까? 교차로는 어떻습니까?
모든 데이터베이스를 지원하는 intersection
것은 아니지만 거의 모든 데이터베이스를 사용하면 조인 (또는 최소한 잘 구조화 된 where 문)을 통해 교차를 만들 수 있습니다.
교차은 다소 유사 결합의 유형입니다 union
상술 한 바와 같이 -하지만 차이가 있다는 것입니다 단지 동일한 데이터 행을 반환 (나는 동일한 뜻) 노동 조합에 합류 다양한 개별 쿼리 사이. 모든 점에서 동일한 행만 반환됩니다.
간단한 예는 다음과 같습니다.
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
일반 union
쿼리는 테이블의 모든 행 (첫 번째 쿼리는 무엇이든 반환 ID>2
하고 두 번째 쿼리는)을 반환 ID<4
하여 전체 집합을 생성하지만 교차 쿼리는 id=3
두 기준을 모두 충족하므로 일치하는 행만 반환 합니다.
이제 데이터베이스가 intersect
쿼리를 지원하지 않는 경우 다음 쿼리를 사용하여 위의 내용을 쉽게 수행 할 수 있습니다.
select
a.ID,
a.color,
a.paint
from
colors a
join colors b
on a.ID=b.ID
where
a.ID>2
and b.ID<4
+----+-------+----------+
| ID | color | paint |
+----+-------+----------+
| 3 | Blue | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)
기본적으로 교차 쿼리를 지원하지 않는 데이터베이스를 사용하여 두 개의 서로 다른 테이블에서 교차를 수행하려면 테이블의 모든 열에 조인을 만들어야합니다 .
좋아,이 게시물이 매우 흥미 롭다는 것을 알았으며 쿼리 작성에 대한 지식을 공유하고 싶습니다. 이 Fluffeh에 감사드립니다 . 이 글을 읽고 내가 틀렸다고 생각하는 다른 사람들은 내 대답을 편집하고 비판하는 데 101 % 무료입니다. ( 솔직히, 나는 내 실수를 고쳐 주셔서 대단히 감사합니다. )
자주 묻는 질문 중 일부를 MySQL
태그에 게시하겠습니다 .
트릭 No. 1 ( 여러 조건과 일치하는 행 )
이 스키마가 주어지면
CREATE TABLE MovieList
(
ID INT,
MovieName VARCHAR(25),
CONSTRAINT ml_pk PRIMARY KEY (ID),
CONSTRAINT ml_uq UNIQUE (MovieName)
);
INSERT INTO MovieList VALUES (1, 'American Pie');
INSERT INTO MovieList VALUES (2, 'The Notebook');
INSERT INTO MovieList VALUES (3, 'Discovery Channel: Africa');
INSERT INTO MovieList VALUES (4, 'Mr. Bean');
INSERT INTO MovieList VALUES (5, 'Expendables 2');
CREATE TABLE CategoryList
(
MovieID INT,
CategoryName VARCHAR(25),
CONSTRAINT cl_uq UNIQUE(MovieID, CategoryName),
CONSTRAINT cl_fk FOREIGN KEY (MovieID) REFERENCES MovieList(ID)
);
INSERT INTO CategoryList VALUES (1, 'Comedy');
INSERT INTO CategoryList VALUES (1, 'Romance');
INSERT INTO CategoryList VALUES (2, 'Romance');
INSERT INTO CategoryList VALUES (2, 'Drama');
INSERT INTO CategoryList VALUES (3, 'Documentary');
INSERT INTO CategoryList VALUES (4, 'Comedy');
INSERT INTO CategoryList VALUES (5, 'Comedy');
INSERT INTO CategoryList VALUES (5, 'Action');
질문
찾기 모든 동영상 적어도에 속하는 모두 Comedy
와 Romance
범주를.
해결책
이 질문은 때때로 매우 까다로울 수 있습니다. 다음과 같은 쿼리가 답이 될 것 같습니다.
SELECT DISTINCT a.MovieName
FROM MovieList a
INNER JOIN CategoryList b
ON a.ID = b.MovieID
WHERE b.CategoryName = 'Comedy' AND
b.CategoryName = 'Romance'
SQLFiddle 데모
결과 가 나오지 않기 때문에 매우 잘못되었습니다 . 이에 대한 설명은 각 행CategoryName
에 유효한 값이 하나만 있다는 것입니다 . 예를 들어 첫 번째 조건은 true를 반환 하고 두 번째 조건은 항상 false입니다. 따라서 연산자 를 사용 하면 두 조건이 모두 맞아야합니다. 그렇지 않으면 거짓입니다. 또 다른 쿼리는AND
SELECT DISTINCT a.MovieName
FROM MovieList a
INNER JOIN CategoryList b
ON a.ID = b.MovieID
WHERE b.CategoryName IN ('Comedy','Romance')
SQLFiddle 데모
결과는에 일치하는 레코드가 하나 이상있는 레코드와 일치하기 때문에 여전히 올바르지 않습니다 categoryName
. 진정한 해결책은 영화 당 기록 인스턴스의 수를 계산하여이 될 것입니다 . 인스턴스 수는 조건에 제공된 총 값 수와 일치해야합니다.
SELECT a.MovieName
FROM MovieList a
INNER JOIN CategoryList b
ON a.ID = b.MovieID
WHERE b.CategoryName IN ('Comedy','Romance')
GROUP BY a.MovieName
HAVING COUNT(*) = 2
SQLFiddle 데모 (답변)
트릭 No. 2 ( 각 항목에 대한 최대 기록 )
주어진 스키마,
CREATE TABLE Software
(
ID INT,
SoftwareName VARCHAR(25),
Descriptions VARCHAR(150),
CONSTRAINT sw_pk PRIMARY KEY (ID),
CONSTRAINT sw_uq UNIQUE (SoftwareName)
);
INSERT INTO Software VALUES (1,'PaintMe','used for photo editing');
INSERT INTO Software VALUES (2,'World Map','contains map of different places of the world');
INSERT INTO Software VALUES (3,'Dictionary','contains description, synonym, antonym of the words');
CREATE TABLE VersionList
(
SoftwareID INT,
VersionNo INT,
DateReleased DATE,
CONSTRAINT sw_uq UNIQUE (SoftwareID, VersionNo),
CONSTRAINT sw_fk FOREIGN KEY (SOftwareID) REFERENCES Software(ID)
);
INSERT INTO VersionList VALUES (3, 2, '2009-12-01');
INSERT INTO VersionList VALUES (3, 1, '2009-11-01');
INSERT INTO VersionList VALUES (3, 3, '2010-01-01');
INSERT INTO VersionList VALUES (2, 2, '2010-12-01');
INSERT INTO VersionList VALUES (2, 1, '2009-12-01');
INSERT INTO VersionList VALUES (1, 3, '2011-12-01');
INSERT INTO VersionList VALUES (1, 2, '2010-12-01');
INSERT INTO VersionList VALUES (1, 1, '2009-12-01');
INSERT INTO VersionList VALUES (1, 4, '2012-12-01');
질문
각 소프트웨어에서 최신 버전을 찾으십시오. 다음 열을 표시합니다 SoftwareName
, Descriptions
, LatestVersion
( VersionNo 열에서 )DateReleased
해결책
일부 SQL 개발자는 실수로 MAX()
집계 함수를 사용 합니다. 그들은 이런 식으로 만드는 경향이 있습니다.
SELECT a.SoftwareName, a.Descriptions,
MAX(b.VersionNo) AS LatestVersion, b.DateReleased
FROM Software a
INNER JOIN VersionList b
ON a.ID = b.SoftwareID
GROUP BY a.ID
ORDER BY a.ID
SQLFiddle 데모
( 대부분의 RDBMS는 group by
절 에 집계되지 않은 일부 열을 지정하지 않기 때문에 구문 오류를 생성합니다. ) 결과는 LatestVersion
각 소프트웨어 에서 올바른 결과를 생성 하지만 분명히 DateReleased
부정확합니다. MySQL
지원하지 않는 Window Functions
및 Common Table Expression
일부 RDBMS가 이미처럼 아직. 이 문제의 해결 방법은 각 소프트웨어 subquery
에서 개별 최대 값을 가져오고 versionNo
나중에 다른 테이블에서 조인하는 소프트웨어 를 작성하는 것 입니다 .
SELECT a.SoftwareName, a.Descriptions,
b.LatestVersion, c.DateReleased
FROM Software a
INNER JOIN
(
SELECT SoftwareID, MAX(VersionNO) LatestVersion
FROM VersionList
GROUP BY SoftwareID
) b ON a.ID = b.SoftwareID
INNER JOIN VersionList c
ON c.SoftwareID = b.SoftwareID AND
c.VersionNO = b.LatestVersion
GROUP BY a.ID
ORDER BY a.ID
SQLFiddle 데모 (답변)
그렇습니다. 태그 에 대한 다른 FAQ 를 기억하자마자 다시 게시하겠습니다 MySQL
. 이 작은 기사를 읽어 주셔서 감사합니다. 나는 당신이 이것으로부터 약간의 지식을 얻었기를 바랍니다.
업데이트 1
트릭 No. 3 ( 두 ID 사이의 최신 레코드 찾기 )
주어진 스키마
CREATE TABLE userList
(
ID INT,
NAME VARCHAR(20),
CONSTRAINT us_pk PRIMARY KEY (ID),
CONSTRAINT us_uq UNIQUE (NAME)
);
INSERT INTO userList VALUES (1, 'Fluffeh');
INSERT INTO userList VALUES (2, 'John Woo');
INSERT INTO userList VALUES (3, 'hims056');
CREATE TABLE CONVERSATION
(
ID INT,
FROM_ID INT,
TO_ID INT,
MESSAGE VARCHAR(250),
DeliveryDate DATE
);
INSERT INTO CONVERSATION VALUES (1, 1, 2, 'hi john', '2012-01-01');
INSERT INTO CONVERSATION VALUES (2, 2, 1, 'hello fluff', '2012-01-02');
INSERT INTO CONVERSATION VALUES (3, 1, 3, 'hey hims', '2012-01-03');
INSERT INTO CONVERSATION VALUES (4, 1, 3, 'please reply', '2012-01-04');
INSERT INTO CONVERSATION VALUES (5, 3, 1, 'how are you?', '2012-01-05');
INSERT INTO CONVERSATION VALUES (6, 3, 2, 'sample message!', '2012-01-05');
질문
두 사용자 간의 최신 대화를 찾으십시오.
해결책
SELECT b.Name SenderName,
c.Name RecipientName,
a.Message,
a.DeliveryDate
FROM Conversation a
INNER JOIN userList b
ON a.From_ID = b.ID
INNER JOIN userList c
ON a.To_ID = c.ID
WHERE (LEAST(a.FROM_ID, a.TO_ID), GREATEST(a.FROM_ID, a.TO_ID), DeliveryDate)
IN
(
SELECT LEAST(FROM_ID, TO_ID) minFROM,
GREATEST(FROM_ID, TO_ID) maxTo,
MAX(DeliveryDate) maxDate
FROM Conversation
GROUP BY minFROM, maxTo
)
SQLFiddle 데모
2 부-서브 쿼리
자, 이제 보스가 다시 터졌습니다. 나는 브랜드가있는 모든 자동차 목록과 그 브랜드의 총 개수를 원합니다!
이는 SQL 쿼리 백에서 하위 쿼리 인 다음 트릭을 사용할 수있는 좋은 기회입니다. 용어에 익숙하지 않은 경우 하위 쿼리는 다른 쿼리 내에서 실행되는 쿼리입니다. 그것들을 사용하는 방법은 여러 가지가 있습니다.
우리의 요청을 위해 먼저 각 자동차와 브랜드를 나열하는 간단한 쿼리를 작성해 보겠습니다.
select
a.ID,
b.brand
from
cars a
join brands b
on a.brand=b.ID
이제 브랜드별로 분류 된 자동차 수를 얻으려면 다음과 같이 작성하십시오.
select
b.brand,
count(a.ID) as countCars
from
cars a
join brands b
on a.brand=b.ID
group by
b.brand
+--------+-----------+
| brand | countCars |
+--------+-----------+
| BMW | 2 |
| Ford | 2 |
| Nissan | 1 |
| Smart | 1 |
| Toyota | 5 |
+--------+-----------+
그렇다면 count 함수를 단순히 원래 쿼리에 추가 할 수 있어야합니까?
select
a.ID,
b.brand,
count(a.ID) as countCars
from
cars a
join brands b
on a.brand=b.ID
group by
a.ID,
b.brand
+----+--------+-----------+
| ID | brand | countCars |
+----+--------+-----------+
| 1 | Toyota | 1 |
| 2 | Ford | 1 |
| 3 | Nissan | 1 |
| 4 | Smart | 1 |
| 5 | Toyota | 1 |
| 6 | BMW | 1 |
| 7 | Ford | 1 |
| 8 | Toyota | 1 |
| 9 | Toyota | 1 |
| 10 | BMW | 1 |
| 11 | Toyota | 1 |
+----+--------+-----------+
11 rows in set (0.00 sec)
안타깝게도 우리는 그렇게 할 수 없습니다. 그 이유는 자동차 ID (열 a.ID)를 추가 할 때 그룹별로 추가해야하므로 카운트 기능이 작동하면 ID 당 하나의 ID 만 일치하기 때문입니다.
그러나 여기서는 하위 쿼리를 사용할 수 있습니다. 실제로 필요한 결과와 동일한 결과를 반환하는 완전히 다른 두 가지 유형의 하위 쿼리를 수행 할 수 있습니다. 첫 번째는 하위 쿼리를 select
절 에 넣는 것 입니다. 즉, 데이터 행을 얻을 때마다 하위 쿼리가 실행되고 데이터 열을 가져온 다음 데이터 행에 데이터가 표시됩니다.
select
a.ID,
b.brand,
(
select
count(c.ID)
from
cars c
where
a.brand=c.brand
) as countCars
from
cars a
join brands b
on a.brand=b.ID
+----+--------+-----------+
| ID | brand | countCars |
+----+--------+-----------+
| 2 | Ford | 2 |
| 7 | Ford | 2 |
| 1 | Toyota | 5 |
| 5 | Toyota | 5 |
| 8 | Toyota | 5 |
| 9 | Toyota | 5 |
| 11 | Toyota | 5 |
| 3 | Nissan | 1 |
| 4 | Smart | 1 |
| 6 | BMW | 2 |
| 10 | BMW | 2 |
+----+--------+-----------+
11 rows in set (0.00 sec)
그리고 Bam !, 이것은 우리를 할 것입니다. 그래도이 하위 쿼리는 반환하는 각 데이터 행마다 실행해야합니다. 이 작은 예에서도 5 가지 브랜드의 자동차 만 있지만 하위 쿼리는 11 개의 데이터 행을 반환하므로 11 번 실행되었습니다. 따라서이 경우 코드를 작성하는 가장 효율적인 방법은 아닙니다.
다른 접근 방식의 경우 하위 쿼리를 실행하고 테이블 인 것처럼 가장하십시오.
select
a.ID,
b.brand,
d.countCars
from
cars a
join brands b
on a.brand=b.ID
join
(
select
c.brand,
count(c.ID) as countCars
from
cars c
group by
c.brand
) d
on a.brand=d.brand
+----+--------+-----------+
| ID | brand | countCars |
+----+--------+-----------+
| 1 | Toyota | 5 |
| 2 | Ford | 2 |
| 3 | Nissan | 1 |
| 4 | Smart | 1 |
| 5 | Toyota | 5 |
| 6 | BMW | 2 |
| 7 | Ford | 2 |
| 8 | Toyota | 5 |
| 9 | Toyota | 5 |
| 10 | BMW | 2 |
| 11 | Toyota | 5 |
+----+--------+-----------+
11 rows in set (0.00 sec)
자, 우리는 동일한 결과를 얻습니다 (약간 다르게 정렬되었습니다-데이터베이스는 이번에 선택한 첫 번째 열로 정렬 된 결과를 반환하려고하는 것 같습니다).
그렇다면 두 가지의 차이점은 무엇이며 각 유형의 하위 쿼리를 언제 사용해야합니까? 먼저 두 번째 쿼리의 작동 방식을 이해해야합니다. from
쿼리 절 에서 두 개의 테이블을 선택한 다음 쿼리를 작성하고 데이터베이스가 실제로는 테이블이라는 것을 데이터베이스에 알 렸습니다. 이 방법을 사용하면 몇 가지 이점 이있을 수 있습니다 (일부 제한 사항도 있음). 가장 먼저이 하위 쿼리가 한 번 실행 되었습니다 . 데이터베이스에 많은 양의 데이터가 포함 된 경우 첫 번째 방법에 비해 크게 개선 될 수 있습니다. 그러나 이것을 테이블로 사용함에 따라 추가 데이터 행을 가져와야 실제로 데이터 행에 다시 결합 될 수 있습니다. 또한 충분한 것이 있는지 확인해야합니다위의 쿼리와 같이 간단한 조인을 사용하려는 경우 데이터 행. 당신이 기억하는 경우, 만에 일치하는 데이터가 행을 다시 끌어 가입 모두 조인의 측면을. 주의하지 않으면이 하위 쿼리에 일치하는 행이 없으면 cars 테이블에서 유효한 데이터가 반환되지 않을 수 있습니다.
이제 첫 번째 하위 쿼리를 살펴보면 몇 가지 제한 사항이 있습니다. 데이터를 단일 행으로 다시 가져 오기 때문에 한 행의 데이터 만 다시 가져올 수 있습니다 . 에 사용되는 하위 쿼리 select
쿼리의 절은 매우 자주 같은 경우에만 집계 함수를 사용 sum
, count
, max
또는 다른 유사한 집계 함수. 반드시 그럴 필요 는 없지만 종종 그들이 쓰는 방식입니다.
계속 진행하기 전에 하위 쿼리를 사용할 수있는 곳을 간단히 살펴 보겠습니다. 우리는 이것을 where
절 에서 사용할 수 있습니다 -이제이 예제는 데이터베이스에서 약간 고안된 것입니다. 다음 데이터를 얻는 더 좋은 방법이 있지만 예제 용으로 만 보는 것이 있습니다.
select
ID,
brand
from
brands
where
brand like '%o%'
+----+--------+
| ID | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 6 | Holden |
+----+--------+
3 rows in set (0.00 sec)
이름에 문자가 포함 된 브랜드 ID 및 브랜드 이름 (두 번째 열은 브랜드를 보여주기 위해 추가 된 것) 목록을 반환합니다 o
.
이제이 쿼리의 결과를 where 절에서 다음과 같이 사용할 수 있습니다.
select
a.ID,
b.brand
from
cars a
join brands b
on a.brand=b.ID
where
a.brand in
(
select
ID
from
brands
where
brand like '%o%'
)
+----+--------+
| ID | brand |
+----+--------+
| 2 | Ford |
| 7 | Ford |
| 1 | Toyota |
| 5 | Toyota |
| 8 | Toyota |
| 9 | Toyota |
| 11 | Toyota |
+----+--------+
7 rows in set (0.00 sec)
보시다시피, 하위 쿼리가 세 개의 브랜드 ID를 반환했지만 자동차 테이블에는 두 개의 브랜드 ID 만있었습니다.
이 경우 세부 정보를 위해 하위 쿼리는 다음 코드를 작성한 것처럼 작동합니다.
select
a.ID,
b.brand
from
cars a
join brands b
on a.brand=b.ID
where
a.brand in (1,2,6)
+----+--------+
| ID | brand |
+----+--------+
| 1 | Toyota |
| 2 | Ford |
| 5 | Toyota |
| 7 | Ford |
| 8 | Toyota |
| 9 | Toyota |
| 11 | Toyota |
+----+--------+
7 rows in set (0.00 sec)
다시 한 번, 하위 쿼리와 수동 입력이 데이터베이스에서 돌아올 때 행 순서를 어떻게 변경했는지 확인할 수 있습니다.
하위 쿼리에 대해 논의하는 동안 하위 쿼리로 수행 할 수있는 다른 작업을 살펴 보겠습니다.
- 다른 하위 쿼리 내에 하위 쿼리 등을 배치 할 수 있습니다. 데이터베이스에 따라 한계가 있지만, 일부 미친 사람과 열광적 인 프로그래머의 재귀 기능이 부족하면 대부분의 사람들은 그 한계에 도달하지 않습니다.
- 하나의 쿼리에 여러 개의 하위 쿼리를 배치 할 수 있고
select
, 일부 는 절에, 일부 는 절에,from
몇 개는where
절에 추가 할 수 있습니다. 입력 한 각 쿼리는 쿼리를 더욱 복잡하게 만들고 시간이 오래 걸릴 수 있음을 기억하십시오. 실행하십시오.
효율적인 코드를 작성해야하는 경우 쿼리를 여러 가지 방법으로 작성하고 결과를 얻는 데 가장 적합한 쿼리 인 타이밍을 지정하거나 설명 계획을 사용하여 참조하는 것이 좋습니다. 작동하는 첫 번째 방법이 항상 최선의 방법은 아닙니다.
3 부-트릭과 효율적인 코드
MySQL의 효율성
나는 팁과 요령을 위해 약간의 비트를 추가 할 것이라고 생각했습니다.
내가 볼 수있는 한 가지 질문 은 두 가지 테이블에서 일치하지 않는 행을 얻는 방법 이며 다음과 같이 가장 일반적으로 허용되는 답변을 참조하십시오 (자동차 및 브랜드 테이블을 기반으로 -Holden 이 브랜드이지만 자동차 표에는 표시되지 않음) :
select
a.ID,
a.brand
from
brands a
where
a.ID not in(select brand from cars)
그리고 그렇습니다 .
+----+--------+
| ID | brand |
+----+--------+
| 6 | Holden |
+----+--------+
1 row in set (0.00 sec)
그러나 일부 데이터베이스 에서는 효율적 이지 않습니다 . 여기 에 그것에 대해 묻는 스택 오버플로 질문에 대한 링크 가 있습니다. 여기서 딱딱한 부분에 들어가고 싶다면 깊이있는 기사 가 있습니다.
짧은 대답은 옵티마이 저가 효율적으로 처리하지 않으면 일치하지 않는 행을 얻기 위해 다음과 같은 쿼리를 사용하는 것이 훨씬 좋습니다.
select
a.brand
from
brands a
left join cars b
on a.id=b.brand
where
b.brand is null
+--------+
| brand |
+--------+
| Holden |
+--------+
1 row in set (0.00 sec)
하위 쿼리에서 동일한 테이블로 테이블 업데이트
Ahhh, 또 다른 oldie이지만 goodie-old FROM 절에서 업데이트 할 대상 테이블 'brands'를 지정할 수 없습니다 .
MySQL update...
에서는 동일한 테이블에서 하위 선택을 사용하여 쿼리 를 실행할 수 없습니다 . 자, 당신은 생각하고있을 것입니다. 왜 where 절에 넣지 않습니까? 그러나 max()
날짜가 다른 행만 다른 행 으로 업데이트하려면 어떻게해야 합니까? where 절에서는 정확히 그렇게 할 수 없습니다.
update
brands
set
brand='Holden'
where
id=
(select
id
from
brands
where
id=6);
ERROR 1093 (HY000): You can't specify target table 'brands'
for update in FROM clause
그래서 우리는 그것을 할 수 없습니다? 정확히는 아닙니다. 놀랍게도 많은 사용자가 알지 못하는 몰래 해결 방법이 있습니다.주의를 기울여야 할 해커도 포함됩니다.
하위 쿼리를 다른 하위 쿼리에 고정하면 두 쿼리 사이에 충분한 간격을 두어 작동 할 수 있습니다. 그러나 트랜잭션 내에서 쿼리를 유지하는 것이 가장 안전 할 수 있습니다. 이렇게하면 쿼리가 실행되는 동안 테이블에서 다른 변경이 이루어지지 않습니다.
update
brands
set
brand='Holden'
where id=
(select
id
from
(select
id
from
brands
where
id=6
)
as updateTable);
Query OK, 0 rows affected (0.02 sec)
Rows matched: 1 Changed: 0 Warnings: 0
FROM 키워드에 여러 쿼리 개념을 사용할 수 있습니다. 하나의 예를 보여 드리겠습니다.
SELECT DISTINCT e.id,e.name,d.name,lap.lappy LAPTOP_MAKE,c_loc.cnty COUNTY
FROM (
SELECT c.id cnty,l.name
FROM county c, location l
WHERE c.id=l.county_id AND l.end_Date IS NOT NULL
) c_loc, emp e
INNER JOIN dept d ON e.deptno =d.id
LEFT JOIN
(
SELECT l.id lappy, c.name cmpy
FROM laptop l, company c
WHERE l.make = c.name
) lap ON e.cmpy_id=lap.cmpy
원하는만큼 테이블을 사용할 수 있습니다. 테이블 하위 쿼리 내부에서도 필요한 경우 외부 조인과 공용체를 사용하십시오.
그것은 테이블과 필드만큼 많은 것을 포함하는 매우 쉬운 방법입니다.
희망 사항을 통해 테이블을 찾을 수 있기를 바랍니다.
mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | varchar(15) | YES | | NULL | |
| paint | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
참고 URL : https://stackoverflow.com/questions/12475850/sql-query-return-data-from-multiple-tables
'development' 카테고리의 다른 글
스칼라의 사례 클래스와 클래스의 차이점은 무엇입니까? (0) | 2020.02.19 |
---|---|
CSS-부동 자식 DIV 높이를 부모 높이로 확장 (0) | 2020.02.19 |
레일에서 문자열과 텍스트의 차이점은 무엇입니까? (0) | 2020.02.19 |
객체가 목록인지 튜플인지 확인하는 방법 (문자열은 아님)? (0) | 2020.02.19 |
mysqldump를 사용하지 않고 데이터베이스 복사 / 복제 (0) | 2020.02.19 |