복붙노트

[SQL] 여러 테이블에서 SQL 쿼리 데이터를 반환

SQL

여러 테이블에서 SQL 쿼리 데이터를 반환

나는 다음을 알고 싶다 :

내 (예를 들어 - PHP)에서이를 사용할 계획입니다 응용 프로그램,하지만 난 하나의 쿼리에서 여러 테이블에서 데이터를 얻을 수 있나요 어떤 옵션, 데이터베이스에 대해 여러 쿼리를 실행하지 않으?

참고 : 나는 끊임없이 PHP 큐에 건너하는 수많은 질문에 잘 쓰여진 가이드에 링크 할 수 싶습니다 내가 대답을 게시 할 때 내가 더 자세히이에 연결할 수 있도록 내가이 글을 쓰는하고있다.

대답은 다음 덮개를 :

해결법

  1. ==============================

    1.이 답변 커버 :

    이 답변 커버 :

    데이터베이스에 여러 테이블에서 데이터를 검색하는 방법에는 여러 가지가 있습니다. 이 대답에, 나는 ANSI-92 조인 구문을 사용하는 것입니다. 이것은 기존의 ANSI-89 구문을 사용합니다 거기 다른 자습서의 수와 다를 수 있습니다 (당신이 89로 사용하는 경우, 훨씬 직관적 인 것처럼 보일 수 있습니다 -하지만 내가 말할 수있는 모두는 그것을 시도하는 것입니다) 훨씬 쉽게로 쿼리가 더 복잡 받기 시작하면 이해합니다. 왜 그것을 사용? 성능 향상이 있습니까? 짧은 대답은 no입니다,하지만 일단 익숙해지면 쉽게 읽을 수 있습니다. 이 구문을 사용하여 다른 사람에 의해 작성된 쿼리를 쉽게 읽을 수 있습니다.

    나는 또한 그것을 사용할 무슨 차를 추적하는 데이터베이스가 작은 caryard의 개념을 사용하기 위하여려고하고있다. 소유자는 자신의 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)
    

    는 caryard 밖으로 자동차의 다른 브랜드 가능성이 판매 할 수 테이블을 식별 브랜드.

    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)
    

    이것은 우리에게 다음과 조인의 다른 유형의 예제를 포함하고 또한 그들이 보람 충분한 데이터를 제공 할 수있는 충분한 데이터를 (I 희망) 줄 것이다.

    그것의 모래에 들어가기 그래서 상사는 그가이 모든 스포츠카의 ID를 알고 싶어한다.

    이 두 테이블 조인 간단합니다. 우리는 모델과에서 사용할 수 stock와 테이블을 식별하는 테이블이 있습니다. 당신이 볼 수 있듯이, 차 테이블의 모델 열의 데이터는 우리가 가지고있는 차 테이블의 모델 컬럼에 관한 것이다. 이제, 우리는 모델 테이블이 너무 조인을 작성할 수 있습니다 스포츠 1의 ID를 가지고 있음을 알고있다.

    select
        ID,
        model
    from
        cars
            join models
                on model=ID
    

    그래서이 쿼리는 좋은 권리를 보인다? 우리는 두 개의 테이블을 확인하고 우리가 필요로하는 정보를 포함하고 올바르게에 가입 할 것을 열을 식별 그 조인을 사용했다.

    ERROR 1052 (23000): Column 'ID' in field list is ambiguous
    

    noes 오! 우리의 첫 번째 쿼리에서 오류! 예, 그것은 매화입니다. 당신은 쿼리가 실제로 올바른 열을 가지고있어, 볼 수 있지만 데이터베이스가 실제 열이 우리가 의미 어디서 무엇인지 혼동됩니다, 그래서 그들 중 일부는, 두 테이블에 존재합니다. 이 문제를 해결하기 위해 두 가지 해결책이 있습니다. 먼저 우리는 우리가이 같은 뜻을 정확히 데이터베이스를 알려 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 모델 = '스포츠'에 의해 어느 스포츠 자동차를 식별 할 수 있습니다. 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)
    

    빙고! 보스는 행복하다. 물론, 그가 요구로 만족되는 보스 인 결코, 그는 그때뿐만 아니라 색상을 원하는 말한다, 정보를 살펴 봅니다.

    좋아, 그래서 우리는 우리의 쿼리의 좋은 부분이 이미 작성해야하지만 우리는 색상입니다 세 번째 테이블을 사용합니다. 이제, 우리의 주요 정보 테이블 차 저장 자동차 색상 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)
    

    그래, 그 순간 우리의 백 오프 보스입니다. 이제 좀 더 구체적으로,이 중 일부를 설명합니다. 당신이 우리의 문에 절에서 우리의 기본 테이블을 연결하는 볼 수 있듯이 (나는 종종 조회 또는 차원 테이블보다는 정보를 포함하는 테이블을 사용합니다. 쿼리는 모두가 주위 스위치 테이블과 마찬가지로 잘 작동하지만 덜 감각을 만들 것 모든 것이 명확로하므로 사용의 좋은 들여 쓰기, 직관적으로 배치 - 우리가이 쿼리에 돌아올 때 좋은 것 쿼리를 작성하려고하고 이해하기 쉽게하는 것이 가장 좋습니다, 몇 달의 시간에 그것을 읽기 .이 될 수 있습니다 당신이 가르쳐 다른 사람에게 갈 경우, 자신의 쿼리에서 이러한 특성을 주입하려고 - 당신이 그 문제를 해결하는 것, 특히.

    이 방법으로 더 많은 테이블을 연결 유지하기 위해 전적으로 가능하다.

    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
    

    나는 문을 조인 우리는 하나 이상의 열을 가입 할 수있는 테이블을 포함하는 것을 잊었다하지만, 여기에 예입니다. 모델 테이블 따라서 브랜드 별 모델이 있고 경우 또한,이 같이 할 수있는 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
    

    당신은 쿼리는 위의 주요 자동차 테이블에 조인 된 테이블을 연결뿐만 아니라, 이미 조인 된 테이블 간의 조인을 지정하고, 볼 수 있습니다. 나쁜에 대한 DBA의 발언이다 -이 완료되지 않은 경우, 결과는 조인 데카르트라고합니다. 가입 데카르트 A는, 정보가 어떻게 결과를 제한하는 데이터베이스를 말하지 않기 때문에 행이 반환됩니다 하나 인 쿼리 반환 기준에 맞는 모든 행하므로.

    따라서, 조인 데카르트의 예를 제공하기 위해, 다음 쿼리를 실행할 수 있습니다 :

    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와 모델에서 모델에 대해 물었다. 우리는 테이블을 조인하는 방법을 지정하지 않았기 때문에 그러나, 데이터베이스는 두 번째 테이블의 모든 행과 첫 번째 테이블에서 모든 행을 일치했다.

    좋아, 보스가 돌아왔다, 그는 다시 더 많은 정보를 원한다. 나는 동일한 목록을 원하지만, 또한에 4WDs을 포함한다.

    그러나 이것은 우리에게 이러한 목표를 달성하기 위해 두 가지 방법으로 볼 수있는 좋은 구실을 제공합니다. 우리는이 같은 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
    

    위가 완벽하게 작동하지만,이 통합 쿼리 작동 방식을 보여주는 좋은 변명, 다르게에서보기를 할 수 있습니다.

    우리는 다음과 같은 모든 스포츠 자동차를 반환 할 것이라는 점을 알고있다 :

    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
    

    그리고 다음은 모든 4WDs을 반환합니다 :

    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
    

    노동 조합에게 그 사이의 모든 조항을 추가하여 그래서, 두 번째 쿼리의 결과는 첫 번째 쿼리의 결과에 추가됩니다.

    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)
    

    당신이 볼 수 있듯이, 첫 번째 쿼리의 결과는, 먼저 반환 두 번째 쿼리의 결과에 따른다.

    이 예에서는 물론 훨씬 더 쉬웠을 단순히 첫 번째 쿼리를 사용하는 것이지만, 통합 쿼리는 특정 사례에 대한 중대한 될 수 있습니다. 또는 그 문제에 전혀 관계가없는 테이블 - 그들은 쉽게 함께 가입하지 않은 테이블에서 테이블에서 특정 결과를 반환 할 수있는 좋은 방법입니다. 그러나 따라야 할 몇 가지 규칙이 있습니다.

    지금, 당신은 차이가 모든 노동 조합과 노동 조합을 사용하는 사이에 무엇인지 궁금 할 것이다. 통합 쿼리는 중복을 제거 노조있는 동안 모두는하지 않습니다. 이것은 모든 조합을 통해 노동 조합을 사용하지만 결과는 가치가 될 수있는 경우 작은 성능 저하가 있음을 의미합니까 -이 생각에서 그런 종류의 추측하지 않습니다.

    이 메모에서, 여기 몇 가지 추가 사항을 협조 할 수 있습니다.

    다음 예를 들어, 나는 우리 테이블에 몇 가지 추가 행을 추가하고있다.

    나는 브랜드 테이블에 홀든을 추가했습니다. 색상 테이블에 대한 언급이 없다 - 나는 또한 12의 색상 값이 차에 행을 추가했습니다.

    좋아, 상사로부터 요청을 짖는 다시 돌아왔다! - 나는 우리가 수행하는 각 브랜드의 수와 그 안에 자동차의 수를 원하는 *`- 일반, 우리는 단지 우리의 토론의 흥미로운 부분에 도착하고 보스가 더 많은 일을 원한다 .

    Rightyo, 그래서 우리가해야 할 첫번째 일은 가능한 브랜드의 전체 목록을 얻을 수 있습니다.

    select
        a.brand
    from
        brands a
    
    +--------+
    | brand  |
    +--------+
    | Ford   |
    | Toyota |
    | Nissan |
    | Smart  |
    | BMW    |
    | Holden |
    +--------+
    6 rows in set (0.00 sec)
    

    우리는 우리의 자동차 테이블이 가입 할 때 지금, 우리는 다음과 같은 결과를 얻을 :

    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)
    

    어느 물론 문제입니다 - 우리는 내가 추가 한 아름다운 홀덴 브랜드의 어떤 언급을보고하지 않습니다.

    A는 두 테이블의 행을 일치하는 외모에 참여하기 때문이다. 이 반환되지 않습니다 홀든 유형 인 자동차 데이터가 없기 때문에. 우리가 외부 조인을 사용할 수있는 곳이다. 이것은 그들이 다른 테이블 여부에 일치 여부를 하나 개의 테이블에서 모든 결과를 반환합니다 :

    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)
    

    그리고, 멀리 보스 skulks와.

    이제 좀 더 자세히 이것을 설명하기 위해, 외부는 왼쪽 또는 오른쪽 유형이 될 수 합류했다. 완전히 포함 된 테이블 왼쪽이나 오른쪽으로 정의합니다. 왼쪽 외부는 (당신이 그것을 짐작) 오른쪽 외부 결과로 오른쪽에있는 테이블의 모든 결과 제공에 참여하는 동안, 왼쪽에있는 테이블의 모든 행을 포함 할 것이다 가입 할 수 있습니다.

    일부 데이터베이스는 완전 외부 두 테이블에서 (일치 여부) 결과를 다시 가져올 것이다 가입 수,하지만이 모든 데이터베이스에서 지원되지 않습니다.

    지금이 시점에서 나는 아마 그림은, 당신은 당신이 쿼리에서 조인 유형을 병합 할 수 있는지 여부를 궁금해하는 - 그리고 대답은 '예, 당신이 절대적으로 할 수있다.

    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)
    

    우리가 볼 수 있듯이, 우리는 두 개의 외부 쿼리에 조인이 결과는 예상대로를 통해오고있다.

    지금, 당신은 어떻게 그 다른 유형에 대한 문의 조인? 어떤 교차점에 대해?

    음, 모든 데이터베이스가 교차로를 지원하지만 조인을 통해 거의 모든 데이터베이스가 교차로를 만들 수 없습니다 (또는 잘 구조화 된 곳 문 최소한의에서).

    교차로는 전술 한 바와 같이 노동 조합 다소 유사 결합의 유형입니다 -하지만 차이는 단지 동일한 데이터 행을 반환하는 (그리고 나는 동일한 뜻) 노동 조합에 합류 다양한 개별 쿼리 사이. 모든 점에서 동일하다 행만 반환됩니다.

    간단한 예는 다음과 같은 것이다 :

    select
        *
    from
        colors
    where
        ID>2
    intersect
    select
        *
    from
        colors
    where
        id<4
    

    통상 통합 쿼리 테이블의 모든 행을 반환하지만 전체 집합을 초래할 것이다 (ID> 2 이상 아무것도 제 아무것도 갖는 ID <4 복귀 제 쿼리), 교집합 쿼리는 로우 매칭 ID를 반환 = 3이 두 조건을 만족한다.

    데이터베이스가 교차 쿼리를 지원하지 않는 경우 이제, 위의 쉽게 다음 쿼리와 accomlished 할 수 있습니다 :

    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)
    

    당신은 본질적으로 교차 쿼리를 지원하지 않는 데이터베이스를 사용하여 두 개의 서로 다른 테이블에 걸쳐 교차로를 수행하고자하는 경우, 당신은이 테이블의 모든 컬럼에 가입 만들어야합니다.

  2. ==============================

    2.좋아,이 게시물 매우 흥미로운 발견하고 나는 쿼리를 만드는 방법에 대한 내 지식의 일부를 공유하고 싶습니다. 이 Fluffeh 주셔서 감사합니다. 이 글을 읽을 수 있고, 내가 틀렸다 것을 느낄 수 있습니다 기타 편집에 101 % 무료이며 내 대답을 비판. (솔직히, 나는 내 실수 (들)을 수정 매우 감사 바랍니다.)

    좋아,이 게시물 매우 흥미로운 발견하고 나는 쿼리를 만드는 방법에 대한 내 지식의 일부를 공유하고 싶습니다. 이 Fluffeh 주셔서 감사합니다. 이 글을 읽을 수 있고, 내가 틀렸다 것을 느낄 수 있습니다 기타 편집에 101 % 무료이며 내 대답을 비판. (솔직히, 나는 내 실수 (들)을 수정 매우 감사 바랍니다.)

    나는 MySQL의 태그에 자주 묻는 몇 가지 질문을 게시 할 수 있습니다.

    이 스키마 감안할 때

    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');
    

    질문

    적어도 두 코미디와 로맨스 범주에 속하는 모든 영화를 찾을 수 있습니다.

    해결책

    이 질문은 매우 까다로운 때로는 될 수 있습니다. 이 같은 쿼리가 응답 될 것입니다 것처럼 보일 수 있습니다 -

    SELECT  DISTINCT a.MovieName
    FROM    MovieList a
            INNER JOIN CategoryList b
                ON a.ID = b.MovieID
    WHERE   b.CategoryName = 'Comedy' AND
            b.CategoryName = 'Romance'
    

    어떤이 더 결과를 생성하지 않기 때문에 확실히 매우 잘못된 것입니다. 이것의 설명은 각 행에 범주의 하나의 유효한 값이 있다는 것입니다. 예를 들어, 첫 번째 조건은 두 번째 조건은 항상 거짓, true를 돌려줍니다. 따라서, AND 연산자를 사용하여 두 조건이 충족되어야한다; 그렇지 않으면 거짓이 될 것입니다. 또 다른 쿼리는 다음과 같이이다

    SELECT  DISTINCT a.MovieName
    FROM    MovieList a
            INNER JOIN CategoryList b
                ON a.ID = b.MovieID
    WHERE   b.CategoryName IN ('Comedy','Romance')
    

    이 제품 분류에 적어도 하나의 일치가 그 기록을 일치하기 때문에 그 결과는 여전히 올바르지 않습니다. 진짜 해결책은 영화 당 기록 인스턴스의 수를 계산하여이 될 것입니다. 인스턴스의 수는 상황에 제공된 값의 총 개수와 일치한다.

    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
    

    을 감안할 때 스키마,

    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, 설명을 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
    

    결과는 각 소프트웨어의 올바른 LatestVersion을 생산하지만, 분명히 DateReleased이 잘못 (하지 GROUP BY 절에 집계되지 않은 열 중 일부를 지정하는 때문에 대부분의 RDBMS이에 구문 오류가 발생합니다). 일부 RDBMS가 이미처럼 MySQL은 아직 윈도우 기능 및 공통 테이블 표현식을 지원하지 않습니다. 이 문제에 대한 해결 방법은 각 소프트웨어에 개별 최대 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
    

    그래서 그것을였습니다. 내가 MySQL의 태그에 다른 질문을 기억으로 내가 다른 곧 게시 될 것입니다. 이 작은 기사를 읽어 주셔서 감사합니다. 나는 당신이이어야이에서 조금이라도 지식을 얻을 것을 희망한다.

    UPDATE 1

    을 감안할 때 스키마

    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
    )
    
  3. ==============================

    3.자, 이제 보스가 다시 폭발했다 - 나는 브랜드와 우리가 그 브랜드의 얼마나 많은 총 우리 자동차의 모든 목록을 원한다!

    자, 이제 보스가 다시 폭발했다 - 나는 브랜드와 우리가 그 브랜드의 얼마나 많은 총 우리 자동차의 모든 목록을 원한다!

    서브 쿼리 - 이것은 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 |
    +--------+-----------+
    

    그래서, 우리는 단순히 우리의 원래 쿼리의 오른쪽으로 카운트 기능을 추가 할 수 있어야한다?

    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
        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)
    

    그리고 빵이!이 우리를 할 것입니다. 당신이 생각났습니다 경우이 하위 쿼리는 각각 우리가 반환 된 데이터의 모든 단일 행에 대해 실행해야합니다. 심지어이 작은 예제에서, 우리는 자동차의 다섯 개 가지 브랜드를 가지고 있지만, 우리는 우리가 반환되는 데이터의 열한 행이 같은 하위 쿼리는 열한 시간을 달렸다. 그래서,이 경우, 코드를 작성하는 가장 효율적인 방법은 아닌 것 같아.

    다른 접근 방식의 경우, 하위 쿼리를 실행하고 테이블 척 할 수 있습니다 :

    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 절에서 두 테이블을 선택하고 쿼리를 작성하고 실제로 테이블 대신했다 데이터베이스 말했다 - 데이터베이스가 완벽하게 행복하다. 이 방법을 사용하여 몇 가지 혜택 (뿐만 아니라 몇 가지 제한)가있을 수 있습니다. 제일이 하위 쿼리 한 번 실행한다는 것입니다. 우리의 데이터베이스는 많은 양의 데이터가 포함 된 경우, 잘 첫 번째 방법에 비해 엄청난 개선이있을 수 있습니다. 그러나, 우리는 테이블로 이것을 사용하고, 우리는 데이터의 추가 행에 데려 와야 - 실제로 데이터의 우리의 행에 다시 합류 할 수 있도록있다. 우리는 또한 우리가 간단한 위의 쿼리처럼 조인을 사용하려는 경우 데이터의 충분한 행이 있는지 확인해야합니다. 당신이 기억하는 경우에만 가입의 양쪽에 일치하는 데이터가있는 행을 다시 끌어 가입 할 수 있습니다. 우리가 조심하지 않으면이이 하위 쿼리에 일치하는 행이 아니었다면 우리의 자동차 테이블에서 반환되는 유효하지 않은 데이터가 될 수 있습니다.

    이제 첫 번째 하위 쿼리를 다시 찾고, 거기에 몇 가지 제한 사항이 있습니다뿐만 아니라. 우리는 단일 행에 데이터를 다시 당겨 때문에, 우리는 다시 한 행의 데이터를 가져올 수 있습니다. 쿼리의 select 절에서 사용되는 서브 쿼리는 매우 종종 합계, 개수, 최대 또는 다른 유사한 집계 함수로만 집계 함수를 사용합니다. 그들은 필요 없어,하지만은 작성되는 빈도입니다.

    우리가 이동하기 전에 그래서, 우리는 하위 쿼리를 사용할 수있는 다른 얼핏을 가지고 있습니다. 우리는 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를 반환에도 불구하고, 우리의 자동차 테이블은 그 두 가지에 대한 항목을했다.

    우리는 다음과 같은 코드를 작성하는 경우이 경우, 더 자세히 들어, 하위 쿼리가 작동한다 :

    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)
    

    다시 말하지만, 당신은 수동 입력 VS 하위 쿼리는 데이터베이스에서 반환하는 행의 순서를 변경하는 방법을 볼 수 있습니다.

    우리는 하위 쿼리를 논의하는 동안, 우리는 하위 쿼리와 함께 할 수있는 다른 것을 볼 수 있습니다 :

    당신은 몇 가지 효율적인 코드를 작성해야하는 경우 (그 타이밍에 의해 또는이 계획을 설명하여 중) 결과를 얻을 수있는 최적의 쿼리 인 쿼리를 여러 가지 방법을 작성하고보고 도움이 될 수 있습니다. 작품은 항상 그 일을하는 가장 좋은 방법을하지 않을 수 있습니다 첫 번째 방법.

  4. ==============================

    4.나는 올이 팁과 트릭을 위해, 약간의 여분의 비트를 추가 생각했다.

    나는 올이 팁과 트릭을 위해, 약간의 여분의 비트를 추가 생각했다.

    내가 공정한 비트를 생각해 볼 질문 하나, 내가 두 테이블에서 일치하지 않는 행을받을 수 있나요 어떻게 내가 대답이 가장 일반적으로 다음과 같은 (우리의 자동차를 기반으로 브랜드 테이블 같은으로 받아 볼 - 홀든이로 나열했다 브랜드 만) 차 테이블에 표시되지 않습니다

    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)
    

    그러나 어떤 데이터베이스에 효율적이지 않습니다. 여기에 대해 묻는 스택 오버플로 질문에 대한 링크이며, 여기 당신이 모래 투성이의 nitty에 들어가려면 깊이 기사에 우수합니다.

    옵티마이 효율적으로 처리하지 않을 경우 짧은 대답은,이 같은 쿼리를 사용하는 것이 훨씬 더 할 수있는 비 일치하는 행을 얻기 위해 다음과 같은 :

    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)
    

    아, 또 하나의 명곡하지만 고맙기 - 당신은 FROM 절에서 업데이트 대상 테이블 '브랜드'를 지정할 수 없습니다 이전.

    MySQL은 같은 테이블에 부속으로 업데이 트 ... 쿼리를 실행 할 수 없습니다. 지금, 당신은 생각 될 수있다, 왜 그냥 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
    
  5. ==============================

    5.당신은 키워드의 여러 쿼리의 개념을 사용할 수 있습니다. 한 가지 예를 보여 드리죠 :

    당신은 키워드의 여러 쿼리의 개념을 사용할 수 있습니다. 한 가지 예를 보여 드리죠 :

    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
    

    당신은 당신이 원하는대로 많은 테이블로 사용할 수 있습니다. 를 사용하여 외부 조인하고, 심지어 테이블 하위 쿼리 안에, 필요의 어느 조합.

    즉 테이블과 필드 많은으로 포함하는 아주 쉬운 방법입니다.

  6. ==============================

    6.이 당신과 같이 일을 통해 읽고있는이 테이블을 찾을 수 있습니다 희망 :

    이 당신과 같이 일을 통해 읽고있는이 테이블을 찾을 수 있습니다 희망 :

    jsfiddle

    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    |                |
    +-------+-------------+------+-----+---------+----------------+
    
  7. from https://stackoverflow.com/questions/12475850/sql-query-return-data-from-multiple-tables by cc-by-sa and MIT license