SQL Server/T-SQL Tutorial/Subquery/Correlated subquery

Материал из SQL эксперт
Перейти к: навигация, поиск

A correlated subquery relies on the main query for its processing.

Correlated subqueries rely on a value from the main query to retrieve its rows you will always see a column from the main query being referenced by the subquery.
9>
10>
11> CREATE TABLE authors(
12>    au_id          varchar(11),
13>    au_lname       varchar(40)       NOT NULL,
14>    au_fname       varchar(20)       NOT NULL,
15>    phone          char(12)          NOT NULL DEFAULT ("UNKNOWN"),
16>    address        varchar(40)           NULL,
17>    city           varchar(20)           NULL,
18>    state          char(2)               NULL,
19>    zip            char(5)               NULL,
20>    contract       bit               NOT NULL
21> )
22> GO
1> insert authors values("1",  "Joe",   "Abra",   "111 111-1111", "6 St.", "Berkeley",  "CA", "11111", 1)
2> insert authors values("2",  "Jack",  "Majo",   "222 222-2222", "3 St.", "Oakland" ,  "CA", "22222", 1)
3> insert authors values("3",  "Pink",  "Cherry", "333 333-3333", "5 Ln.", "Vancouver", "BC", "33333", 1)
4> insert authors values("4",  "Blue",  "Albert", "444 444-4444", "7 Av.", "Vancouver", "BC", "44444", 1)
5> insert authors values("5",  "Red",   "Anne",   "555 555-5555", "6 Av.", "Regina",    "SK", "55555", 1)
6> insert authors values("6",  "Black", "Michel", "666 666-6666", "3 Pl.", "Regina",    "SK", "66666", 1)
7> insert authors values("7",  "White", "Sylvia", "777 777-7777", "1 Pl.", "Rockville", "MD", "77777", 1)
8> insert authors values("8",  "Yellow","Heather","888 888-8888", "3 Pu",  "Vacaville", "CA", "88888", 0)
9> insert authors values("9",  "Gold",  "Dep",    "999 999-9999", "5 Av.", "Oakland",   "CA", "99999", 0)
10> insert authors values("10", "Siler", "Dean",   "000 000-0000", "4 Av.", "Oakland",   "CA", "00000", 1)
11> GO
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
1>
2> CREATE TABLE titleauthor(
3>    au_id          varchar(20),
4>    title_id       varchar(20),
5>    au_ord         tinyint               NULL,
6>    royaltyper     int                   NULL
7> )
8> GO
1>
2> insert titleauthor values("1", "2", 1, 60)
3> insert titleauthor values("2", "3", 1, 100)
4> insert titleauthor values("3", "4", 1, 100)
5> insert titleauthor values("4", "5", 1, 100)
6> insert titleauthor values("5", "6", 1, 100)
7> insert titleauthor values("6", "7", 2, 40)
8> insert titleauthor values("7", "8", 1, 100)
9> insert titleauthor values("8", "9", 1, 100)
10> GO
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
(1 rows affected)
1>
2>      SELECT    DISTINCT au_lname, au_fname
3>      FROM      authors
4>      WHERE     10 IN (SELECT royaltyper
5>                FROM titleauthor
6>                 WHERE titleauthor.au_id = authors.au_id)
7> GO
au_lname                                 au_fname
---------------------------------------- --------------------
(0 rows affected)
1>
2> drop table titleauthor;
3> drop table authors;
4> GO
1>
2>


Correlated subquery using Group By

4>
5>
6> CREATE TABLE Product(
7>     ProductID               int                NOT NULL,
8>     Name                    nvarchar(25)       NOT NULL,
9>     ProductNumber           nvarchar(25)               ,
10>     Color                   nvarchar(15)       NULL,
11>      StandardCost            money              NOT NULL,
12>      Size                    nvarchar(5)        NULL,
13>      Weight                  decimal(8, 2)      NULL,
14>      ProductLine             nchar(20)           NULL,
15>      SellStartDate           datetime           NOT NULL,
16>      SellEndDate             datetime           NULL
17>  )
18>  GO
1> insert into Product values(1,"Product A", "1","Red",123.123,"1",1,"ProductLine A","1999-03-22","2000-03-22");
2> GO
(1 rows affected)
1>
2>
3> insert into Product values(2,"Product B", "2","Yellow",234.234,"1",3,"ProductLine B","2000-03-22","2001-03-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(3,"Product C", "3","Pink",345.345,"1",3,"ProductLine V","2001-09-22","2006-02-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(4,"Product D", "4","White",456.456,"1",4,"ProductLine D","2002-08-22","2006-03-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(5,"Product E", "5","Black",567.567,"1",5,"ProductLine E","2003-01-22","2003-04-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(6,"Product F", "6","Blue",678.678,"1",6,"ProductLine W","2004-02-22","2005-05-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(7,"Product G", "7","Drak",789.789,"1",7,"ProductLine Q","2005-03-22","2006-03-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(8,"Product H", "8","Gray",234.123,"1",8,"ProductLine F","2006-04-22","2006-09-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(9,"Product I", "9","Red",543.123,"1",9,"ProductLine R","2007-05-22","2008-03-22");
4> GO
(1 rows affected)
1>
2>
3> insert into Product values(0,"Product J", "0","Gold",765.123,"1",0,"ProductLine J","2008-06-22","2009-03-22");
4> GO
(1 rows affected)
1>
2>
3>
4>
5>
6> CREATE TABLE SalesOrderDetail(
7>     SalesOrderID            int                NOT NULL,
8>     SalesOrderDetailID      int                NOT NULL,
9>     CarrierTrackingNumber   nvarchar(25)       NULL,
10>     OrderQty                smallint           NOT NULL,
11>     ProductID               int                NOT NULL,
12>      SpecialOfferID          int                NOT NULL,
13>      UnitPrice               money              NOT NULL,
14>      UnitPriceDiscount       money              NOT NULL DEFAULT (0.0),
15>      LineTotal               AS ISNULL([UnitPrice] * (1.0 - [UnitPriceDiscount]) * [OrderQty], 0.0)
16>  );
17>  GO
1>
2> insert into SalesOrderDetail values (1,1,"1",1,1,1,$1,$1);
3> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (2,2,"2",2,2,2,$2,$2);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (3,3,"3",3,3,3,$3,$3);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (4,4,"4",4,4,4,$4,$4);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (5,5,"5",5,5,5,$5,$5);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (6,6,"6",6,6,6,$6,$6);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (7,7,"7",7,7,7,$7,$7);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (8,8,"8",8,8,8,$8,$8);
4> GO
(1 rows affected)
1>
2>
3> insert into SalesOrderDetail values (9,9,"9",9,9,9,$9,$9);
4> GO
(1 rows affected)
1>
2>
3>
4>
5> SELECT ProductID
6>   , Name
7> FROM Product AS P
8> WHERE 1 =
9>   (SELECT ProductID
10>   FROM SalesOrderDetail As SD
11>   WHERE P.ProductID = SD.ProductID
12>    GROUP BY ProductID)
13>  GO
ProductID   Name
----------- -------------------------
          1 Product A
(1 rows affected)
1>
2> drop table Product;
3> GO
1>
2>
3> drop table SalesOrderDetail;
4> GO


Correlated subquery using TOP 1

6>
7> CREATE TABLE Product(
8>     ProductID               int                NOT NULL,
9>     Name                    nvarchar(25)       NOT NULL,
10>     ProductNumber           nvarchar(25)               ,
11>     Color                   nvarchar(15)       NULL,
12>     StandardCost            money              NOT NULL,
13>     Size                    nvarchar(5)        NULL,
14>     Weight                  decimal(8, 2)      NULL,
15>     ProductLine             nchar(20)           NULL,
16>     SellStartDate           datetime           NOT NULL,
17>     SellEndDate             datetime           NULL
18> )
19> GO
1> insert into Product values(1,"Product A", "1","Red",123.123,"1",1,"ProductLine A","1999-03-22","2000-03-22");
2> GO
(1 rows affected)
1> insert into Product values(2,"Product B", "2","Yellow",234.234,"1",3,"ProductLine B","2000-03-22","2001-03-22");
2> GO
(1 rows affected)
1> insert into Product values(3,"Product C", "3","Pink",345.345,"1",3,"ProductLine V","2001-09-22","2006-02-22");
2> GO
(1 rows affected)
1> insert into Product values(4,"Product D", "4","White",456.456,"1",4,"ProductLine D","2002-08-22","2006-03-22");
2> GO
(1 rows affected)
1> insert into Product values(5,"Product E", "5","Black",567.567,"1",5,"ProductLine E","2003-01-22","2003-04-22");
2> GO
(1 rows affected)
1> insert into Product values(6,"Product F", "6","Blue",678.678,"1",6,"ProductLine W","2004-02-22","2005-05-22");
2> GO
(1 rows affected)
1> insert into Product values(7,"Product G", "7","Drak",789.789,"1",7,"ProductLine Q","2005-03-22","2006-03-22");
2> GO
(1 rows affected)
1> insert into Product values(8,"Product H", "8","Gray",234.123,"1",8,"ProductLine F","2006-04-22","2006-09-22");
2> GO
(1 rows affected)
1> insert into Product values(9,"Product I", "9","Red",543.123,"1",9,"ProductLine R","2007-05-22","2008-03-22");
2> GO
(1 rows affected)
1> insert into Product values(0,"Product J", "0","Gold",765.123,"1",0,"ProductLine J","2008-06-22","2009-03-22");
2> GO
(1 rows affected)
1>
2>
3>
4> CREATE TABLE SalesOrderDetail(
5>     SalesOrderID            int                NOT NULL,
6>     SalesOrderDetailID      int                NOT NULL,
7>     CarrierTrackingNumber   nvarchar(25)       NULL,
8>     OrderQty                smallint           NOT NULL,
9>     ProductID               int                NOT NULL,
10>     SpecialOfferID          int                NOT NULL,
11>     UnitPrice               money              NOT NULL,
12>     UnitPriceDiscount       money              NOT NULL DEFAULT (0.0),
13>     LineTotal               AS ISNULL([UnitPrice] * (1.0 - [UnitPriceDiscount]) * [OrderQty], 0.0)
14> );
15> GO
1>
2> insert into SalesOrderDetail values (1,1,"1",1,1,1,$1,$1);
3> GO
(1 rows affected)
1> insert into SalesOrderDetail values (2,2,"2",2,2,2,$2,$2);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (3,3,"3",3,3,3,$3,$3);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (4,4,"4",4,4,4,$4,$4);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (5,5,"5",5,5,5,$5,$5);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (6,6,"6",6,6,6,$6,$6);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (7,7,"7",7,7,7,$7,$7);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (8,8,"8",8,8,8,$8,$8);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (9,9,"9",9,9,9,$9,$9);
2> GO
(1 rows affected)
1>
2> SELECT ProductID
3>   , Name
4> FROM Product AS P
5> WHERE 1 =
6>   (SELECT TOP 1 ProductID
7>   FROM SalesOrderDetail As SD
8>   WHERE P.ProductID = SD.ProductID)
9> GO
ProductID   Name
----------- -------------------------
          1 Product A
(1 rows affected)
1>
2> drop table Product;
3> GO
1>
2>
3> drop table SalesOrderDetail;
4> GO


using SELECT DISTINCT or a GROUP BY statement in the inner query

6>
7>
8>
9> CREATE TABLE Product(
10>     ProductID               int                NOT NULL,
11>     Name                    nvarchar(25)       NOT NULL,
12>     ProductNumber           nvarchar(25)               ,
13>     Color                   nvarchar(15)       NULL,
14>     StandardCost            money              NOT NULL,
15>     Size                    nvarchar(5)        NULL,
16>     Weight                  decimal(8, 2)      NULL,
17>     ProductLine             nchar(20)           NULL,
18>     SellStartDate           datetime           NOT NULL,
19>     SellEndDate             datetime           NULL
20> )
21> GO
1> insert into Product values(1,"Product A", "1","Red",123.123,"1",1,"ProductLine A","1999-03-22","2000-03-22");
2> GO
(1 rows affected)
1> insert into Product values(2,"Product B", "2","Yellow",234.234,"1",3,"ProductLine B","2000-03-22","2001-03-22");
2> GO
(1 rows affected)
1> insert into Product values(3,"Product C", "3","Pink",345.345,"1",3,"ProductLine V","2001-09-22","2006-02-22");
2> GO
(1 rows affected)
1> insert into Product values(4,"Product D", "4","White",456.456,"1",4,"ProductLine D","2002-08-22","2006-03-22");
2> GO
(1 rows affected)
1> insert into Product values(5,"Product E", "5","Black",567.567,"1",5,"ProductLine E","2003-01-22","2003-04-22");
2> GO
(1 rows affected)
1> insert into Product values(6,"Product F", "6","Blue",678.678,"1",6,"ProductLine W","2004-02-22","2005-05-22");
2> GO
(1 rows affected)
1> insert into Product values(7,"Product G", "7","Drak",789.789,"1",7,"ProductLine Q","2005-03-22","2006-03-22");
2> GO
(1 rows affected)
1> insert into Product values(8,"Product H", "8","Gray",234.123,"1",8,"ProductLine F","2006-04-22","2006-09-22");
2> GO
(1 rows affected)
1> insert into Product values(9,"Product I", "9","Red",543.123,"1",9,"ProductLine R","2007-05-22","2008-03-22");
2> GO
(1 rows affected)
1> insert into Product values(0,"Product J", "0","Gold",765.123,"1",0,"ProductLine J","2008-06-22","2009-03-22");
2> GO
(1 rows affected)
1>
2>
3>
4> CREATE TABLE SalesOrderDetail(
5>     SalesOrderID            int                NOT NULL,
6>     SalesOrderDetailID      int                NOT NULL,
7>     CarrierTrackingNumber   nvarchar(25)       NULL,
8>     OrderQty                smallint           NOT NULL,
9>     ProductID               int                NOT NULL,
10>     SpecialOfferID          int                NOT NULL,
11>     UnitPrice               money              NOT NULL,
12>     UnitPriceDiscount       money              NOT NULL DEFAULT (0.0),
13>     LineTotal               AS ISNULL([UnitPrice] * (1.0 - [UnitPriceDiscount]) * [OrderQty], 0.0)
14> );
15> GO
1>
2> insert into SalesOrderDetail values (1,1,"1",1,1,1,$1,$1);
3> GO
(1 rows affected)
1> insert into SalesOrderDetail values (2,2,"2",2,2,2,$2,$2);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (3,3,"3",3,3,3,$3,$3);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (4,4,"4",4,4,4,$4,$4);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (5,5,"5",5,5,5,$5,$5);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (6,6,"6",6,6,6,$6,$6);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (7,7,"7",7,7,7,$7,$7);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (8,8,"8",8,8,8,$8,$8);
2> GO
(1 rows affected)
1> insert into SalesOrderDetail values (9,9,"9",9,9,9,$9,$9);
2> GO
(1 rows affected)
1>
2>
3> SELECT ID
4>   , Name
5> FROM Product AS P
6> WHERE 1 =
7>   (SELECT DISTINCT ProductID
8>   FROM SalesOrderDetail As SD
9>   WHERE P.ProductID = SD.ProductID)
10> GO
1>
2> drop table Product;
3> GO
1>
2>
3> drop table SalesOrderDetail;
4> GO