¾È±Ô °øºÎ¹æ

MS-SQL > À¯¿ëÇÑ Äõ¸® ¸ðÀ½.

µî·ÏÀÏ : 2017-07-03 19:02 Á¶È¸¼ö : 34,239

ÁýÇÕ(SET) : sqlÀº ºÐ¸í ÁýÇÕÀ» ÀÌ¿ëÇÑ´Ù. Ä¿¼­»ç¿ëÀ» ÀÚÁ¦ÇÏÀÚ.

±³ÁýÇÕ, Â÷ÁýÇÕ, ÇÕÁýÇÕ - ¿¹Àü¿¡ ÃʵîÇлý ¾Æ´Ô ÁßÇлý ½ÃÀý Áö°ã°Ô(?) µè´ø ´Ü¾îµéÀÌÁö¿ä
/*==========================================================*/
¸ÕÀú »ùÇÃÀ» ¸¸µé¾îµÎ°í
--drop table #a
--drop table #b
create table #a(id int)
create table #b(id int)
go
insert into #a values(1)
insert into #a values(2)
insert into #a values(3)
insert into #a values(4)
insert into #a values(5)
insert into #a values(6)
insert into #a values(7)
insert into #a values(8)

insert into #b values(2)
insert into #b values(4)
insert into #b values(6)
insert into #b values(8)
go

ÀÌÁ¦, ¾ÆÁÖ °£´ÜÈ÷ º¸µµ·Ï ÇÏÁö¿ä
/*==========================================================*/
1. ±³ÁýÇÕ (intersect)
   ¾Æ½±Áö¸¸ ÀÌ·±ÇÔ¼ö´Â sql¿¡ ¾ø½À´Ï´Ù.
   (Analysis Services¿ëÀ¸·Î´Â ÀÖÁö¸¸ t-sqlÇÔ¼ö´Â ¾Æ´ÏÁö¿ä)

   ±×·³ ÀÌ·±°æ¿ì´Â ¾î¶»°Ô ÇÒ±î¿ä ?
   -> in À̳ª exists ¸¦ ÀÌ¿ëÇϴ°̴ϴÙ. ¶Ç´Â Á¶ÀÎÀ» »ç¿ëÇÏÁö¿ä.
/*==========================================================*/
¿¹Á¦ : Å×À̺í1 °ú Å×À̺í2 µÑ´Ù µé¾îÀִ°ÍÀº ?

1. in »ç¿ë
select * from #a
where id in (select id from #b)

2. exists »ç¿ë
select * from #a x
where exists(select * from #b y where y.id=x.id)

3. Á¶Àλç¿ë
select x.* from #a x
   inner join #b y
      on (y.id = x.id)
/*==========================================================*/
2. Â÷ÁýÇÕ (except, minus)
   ¾Æ½±Áö¸¸ ÀÌ·±ÇÔ¼ö´Â sql¿¡ ¾ø½À´Ï´Ù.
   (Analysis Services¿ëÀ¸·Î´Â ÀÖÁö¸¸ t-sqlÇÔ¼ö´Â ¾Æ´ÏÁö¿ä)

   ±×·³ ÀÌ·±°æ¿ì´Â ¾î¶»°Ô ÇÒ±î¿ä ?
   -> not in À̳ª not exists ¸¦ ÀÌ¿ëÇϴ°̴ϴÙ. ¶Ç´Â outer joinÀ» »ç¿ëÇϴ°ÍÀÔ´Ï´Ù. 
/*==========================================================*/
¿¹Á¦2 : Å×À̺í1 ¿¡´Â Àִµ¥ Å×À̺í 2¿¡´Â ¾ø´Â °ÍÀº ?

1. not in »ç¿ë
select * from #a
where id not in (select id from #b)

2. not exists »ç¿ë
select * from #a x
where not exists(select * from #b y where y.id=x.id)

3. outer join »ç¿ë
select x.* from #a x
   left outer join #b y
      on (x.id = y.id)
where y.id is null

/*==========================================================*/
3. ÇÕÁýÇÕ (union)
   À¯ÀÏÇÏ°Ô Áö¿øµÇ´Â ÇÔ¼öÀÔ´Ï´Ù.
/*==========================================================*/
¿¹Á¦ : Å×À̺í1 ¿¡ Àִ°Ͱú Å×À̺í 2¿¡ Àִ°ÍÀ» ¸ðµÎ±¸ÇÒ¶§´Â ?

1. union »ç¿ë : Áߺ¹Á¦°Å¸¦ À§ÇØ sort¸¦ ÇÑ´Ù.
select * from #a
union
select * from #b  
  |--Sort(DISTINCT ORDER BY:([Union1004] ASC)) --> Áߺ¹Á¦°Å¸¦ À§Çؼ­ sort¸¦ ÇÑ´Ù.
       |--Concatenation
            |--Table Scan(OBJECT:([tempdb].[dbo].[#a]))
            |--Table Scan(OBJECT:([tempdb].[dbo].[#b]))

2. union all »ç¿ë : Áߺ¹Çã¿ë
select * from #a
union all
select * from #b  
  |--Concatenation   --> sort°¡ ¾ø´Ù.
       |--Table Scan(OBJECT:([tempdb].[dbo].[#a]))
       |--Table Scan(OBJECT:([tempdb].[dbo].[#b))

/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
¿©±â±îÁö °£´ÜÇÏ°Ô ÁýÇÕÀÇ °³³äÀ» ºÃ°í
ÀÌÁ¦ in °ú union ¿¡ ´ëÇÏ¿© Á¶±Ý¸¸ ´õ »ìÆ캸µµ·Ï ÇÏÁö¿ä.
/*==========================================================*/
1. in : ÁÖ¾îÁø °ªÀÌ ÇÏÀ§ Äõ¸® ¶Ç´Â ¸ñ·Ï¿¡ ÀÖ´Â ÀÓÀÇÀÇ °ª°ú ÀÏÄ¡ÇÏ´ÂÁö È®ÀÎÇÕ´Ï´Ù.

±¸¹®
test_expression [ NOT ] IN
    (
         subquery
         | expression [ ,...n ]
    )

ex) ȸ¿øÅ×À̺í(¾ÆÀ̵ð, À̸§, ·¹º§)
    1 È«±æµ¿ 1
2 ¯±¸ 1
3 »×»×ÀÌ 2

--drop table ȸ¿ø
create table ȸ¿ø (¾ÆÀ̵ð int, À̸§ varchar(10), ·¹º§ int)
create index idx on ȸ¿ø(·¹º§)
go
insert into ȸ¿ø values(1, "È«±æµ¿", 1)
insert into ȸ¿ø values(2, "¯±¸",   1)
insert into ȸ¿ø values(3, "»×»×ÀÌ", 2)
go

select * from ȸ¿ø where ·¹º§ in (1, 2)
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([pubs].[dbo].[ȸ¿ø]))
       |--Index Seek(OBJECT:([pubs].[dbo].[ȸ¿ø].[idx]),
                SEEK:([ȸ¿ø].[·¹º§]=1 OR [ȸ¿ø].[·¹º§]=2) ORDERED FORWARD)

½ÇÇó°èȹÀ» º¸¸é ·¹º§ in (1, 2) ±¸¹®ÀÌ ·¹º§=1 OR ·¹º§=2 ¿Í °°ÀÌ or¿¬»êÀ¸·Î º¯°æ µÇ¾ú´Ù.
ÀϹÝÀûÀ¸·Î ÀÌ·¯ÇÑ in ÀÇ °æ¿ì or ¿¬»êÀ¸·Î º¯°æµÇ¾î ½ÇÇàµÈ´Ù.

±×·³, Á»´Ù¸¥ ¹æ¹ýÀ¸·Î
declare @lev1 int, @lev2 int
set @lev1 = 1
set @lev2 = 2
select * from ȸ¿ø where ·¹º§ in (@lev1, @lev2)
  |--Table Scan(OBJECT:([pubs].[dbo].[ȸ¿ø]),
                WHERE:(([ȸ¿ø].[·¹º§]=[@lev2]) OR [ȸ¿ø].[·¹º§]=[@lev1]))

¿¹»óÇß´ø index seek ¹æ½ÄÀÌ ¾Æ´Ï¶ó table scan ¹æ½ÄÀÌ´Ù.
sql-server °¡ Cost base ¹æ½ÄÀÇ ¿ÉƼ¸¶ÀÌÁ®¸¦ »ç¿ëÇÏ´Ùº¸´Ï ÀÌ·±°á°ú°¡ ³ª¿Â´Ù.
Áï, À§ °æ¿ì¿¡ @lev1¸¸À» °¡Áö°í Äõ¸®¸¦ ÇÑ´Ù¸é index seek ¹æ½ÄÀ¸·Î 󸮵ȴÙ.
ÇÏÁö¸¸ À§ °á°ú¸¦ º¸¸é ´ÜÁö 2°³ÀÇ º¯¼ö¸¦ Àû¿ëÇÏÀÚ table scanÂÊÀ¸·Î µ¹¾Æ¼±´Ù.
¿Ö ±×·²±î ?

ÀϹÝÀûÀ¸·Î sql-server´Â »ó¼ö°ªÀÌ Äõ¸®¿¡¼­ »ç¿ëµÇ¸é Á¤È®ÇÑ Åë°èÁ¤º¸¸¦ »ç¿ëÇÏ¿©
index¸¦ »ç¿ëÇÒÁö table scanÀ¸·Î °¥Áö °áÁ¤À» ÇÏÁö¸¸ ¾Ë¼ö¾ø´Â º¯¼ö°ªÀÌ µé¾î¿À¸é
±×³É Æò±Õ°ªÀ» »ç¿ëÇÑ´Ù°í ÇÑ´Ù. ±×·¡¼­ ÀÌ°æ¿ì sql-server°¡ table scanÀ» ¼±ÅÃÇÑ°ÍÀÌ´Ù.
ÀÌ·±°æ¿ì¿¡ ÈùÆ®¸¦ »ç¿ëÇØ¾ß Á¤»óÀûÀÎ index È°¿ëÀ» ÇÑ´Ù.
¹°·Ð, ¿¹Á¦°¡ ¾ûÅ͸® ÀÌÁö¸¸ ½Ç¹«¿¡¼­µµ Çѹø Å×½ºÆ® Çغ¸±â ¹Ù¶õ´Ù.
¿©±â ¿¹Á¦¿Í ´Ù¸£Áö ¾ÊÀ»°ÍÀÌ´Ù.

Çϳª´õ, ÀϹÝÀûÀ¸·Î sql-server´Â ¾Õ¿¡¼­ ºÎÅÍ ÆĽÌÀ» ÇÏÁö¸¸ º¯¼ö¸¦ »ç¿ëÇÑ in ÀÇ °æ¿ì´Â
¹Ý´ë·Î µÚ¿¡¼­ºÎÅÍ ÆĽÌÀ» ÇÑ´Ù. À̰͵µ ¾Ë¾ÆµÑ ÇÊ¿ä´Â ÀÖÀ»µí.
±×·¸´Ù°íÇؼ­ in¾È¿¡ ³ª¿­µÈ¼ø¼­ ¶Ç´Â ¿ª¼øÀ¸·Î Á¤·ÄÀ̵Ǵ°ÍÀº Àý´ë ¾Æ´Ï´Ù.
Á¤·ÄµÈ ¼ø¼­¸¦ ¿øÇÑ´Ù¸é ¹Ýµå½Ã ¸í½ÃÀûÀ¸·Î order by ¸¦ ½á¼­ Á¤·Ä¼ø¼­¸¦ ÁöÁ¤ÇØÁÖ¾î¾ßÇÑ´Ù.

declare @lev1 int, @lev2 int
set @lev1 = 1
set @lev2 = null
select * from ȸ¿ø where ·¹º§ in (@lev1, @lev2)

ÀÌ°æ¿ì´Â ¾î¶»°Ô µÉ±î ?

->

declare @lev1 int, @lev2 int
set @lev1 = null
set @lev2 = null
select * from ȸ¿ø where ·¹º§ in (@lev1, @lev2)

¶Ç, ÀÌ·± °æ¿ì´Â ¾î¶»°Ô µÉ±î ?
°¢ÀÚ Çغ¸½Ã±æ...


/*-----------------------------------------------------------------------*/
1-1. in-subquary

1. in-subquaryÀÇ °æ¿ì join¹®À¸·Î Çؼ®ÀÌ µÈ´Ù.
2. in-subquary°¡ ¸ÕÀú ÀÐÈú¼öµµ, ³ªÁß¿¡ ÀÐÈú¼öµµ ÀÖ´Ù
   -> À妽º À¯¹«, Äõ¸®À¯Çü µî¿¡ µû¶ó¼­ ´Þ¶óÁø´Ù.
3. °í¼ö°¡ ¾Æ´Ï¶ó¸é in-subquary ½ÇÇà½Ã ¹Ýµå½Ã ½ÇÇà°èȹÀ» È®ÀÎÇغ¸½Ã±æ ±ÇÀåÇÕ´Ï´Ù.
   °¡²û À̳ðÀÌ »ý°¢Çѵ¥·Î ÀÛµ¿À» ¾ÈÇϴ¼ö°¡ ÀÖÀ¸´Ï Á¶½É...
/*-----------------------------------------------------------------------*/
»óÇ°Å×À̺í(»óÇ°ÄÚµå, »óÇ°¸í, ºÐ·ùÄÚµå)
ºÐ·ùÅ×À̺í(ºÐ·ùÄÚµå, Ä«Å×°í¸®¸í, µî±Þ)

ÀÌ·±½ÄÀ¸·Î µÇ¾î ÀÖÀ»°æ¿ì »óÇ°Å×ÀÌºí¿¡¼­ Ä«Å×°í¸®µî±ÞÀÌ "A"Àΰ͵éÀÇ ¸ñ·ÏÀ» º¸°í½Í´Ù¸é

select * from »óÇ°
where ºÐ·ùÄÚµå in (select ºÐ·ùÄÚµå from ºÐ·ù where µî±Þ = "A")  

ÀÌ·¸°Ô Äõ¸®¸¦ ÇÏ¸é ¿ÉƼ¸¶ÀÌÀú°¡

select »óÇ°.*
from »óÇ° inner join ºÐ·ù
on »óÇ°.ºÐ·ùÄÚµå = ºÐ·ù.ºÐ·ùÄÚµå
and ºÐ·ù.µî±Þ = "A"  

ÀÌ·±½ÄÀ¸·Î inner joinÀ¸·Î Ç®¾î¼­ 󸮸¦ ÇÑ´Ù.

ÀÌ·±½ÄÀÇ Äõ¸®¹®Àº ´ëºÎºÐÀÇ °æ¿ì in-subquary°¡ ¸ÕÀú ½ÇÇàµÇ´Â Á¶Àι®À¸·Î Çؼ®ÀÌ µÇ¾î
½ÇÇà°èȹÀÌ ³ª¿Ã°ÍÀ¸·Î ±â´ëÇÏÁö¸¸ ±×·¸Áö ¾ÊÀº °æ¿ìµµ ÀÖ´Ù.

in-subquaryÀÇ °æ¿ì ÀϹÝÀûÀ¸·Î in-subquary°¡ ¸ÕÀú ÀÐÇô¼­ main quary°¡ ³ªÁß¿¡ 󸮵DZ⸦
±â´ëÇÏ°í Äõ¸®¹®À» ÀÛ¼ºÇÏ°Ô µÈ´Ù.
ÀϹÝÀûÀ¸·Î ÀÌ·¸°Ô Ç®¸®Áö¸¸ °æ¿ì¿¡ µû¶ó¼­´Â ±×·¸Áö ¾Ê°í main quary°¡ ¸ÕÀú ÀÐÈ÷¸é¼­
in-subquary¸¦ ³ªÁß¿¡ filterÁ¶°ÇÀ¸·Î ó¸®Çϴ°æ¿ì°¡ Á¾Á¾ ¹ß»ýÇÑ´Ù.
·¹Äڵ尡 ¸¹Áö ¾ÊÀº°æ¿ì¿¡´Â Å©°Ô ¼º´É»ó ¹®Á¦°¡ µÇÁö ¾Ê°ÚÁö¸¸ ±×·¸Áö ¾ÊÀº °æ¿ì´Â
½É°¢ÇÑ ¼º´É»óÀÇ ÀúÇϸ¦ °¡Á®¿Â´Ù. ÀÌ°ÍÀ» ÁÖÀÇÇØ¾ß Çϴ°ÍÀÌ´Ù.
±×·¡¼­, °³¹ßÀÚµéÀº º»ÀÎÀÌ °í¼ö°¡ ¾Æ´Ï¶ó¸é ½ÇÇà°èȹÀ» È®ÀÎÇÏ¿©¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.

À§ ¿¹Á¦ÀÇ °æ¿ì¸¦ °¡Áö°í »ìÆ캻´Ù¸é
in-subquary°¡ ¸ÕÀú 󸮵ȴٸé
   ºÐ·ù Å×ÀÌºí¿¡¼­ µî±ÞÀÌ "A"ÀÎ ºÐ·ùÄÚµåµé¸¸À» ¸ÕÀú Àо ±×°ÍÀ» °¡Áö°í
»óÇ°Å×À̺íÀÇ ºÐ·ùÄÚµå À妽º¸¦ »ç¿ëÇÑ´Ù¸é ÃÖÀûÀÏ°ÍÀÌ´Ù.

main-quary°¡ ¸ÕÀú 󸮵ȴٸé
   »óÇ°Å×À̺íÀ» ¹«Á¶°Ç Ç®·Î Àо ¶Ç´Â ºÐ·ùÄÚµå À妽º¸¦ Ç®·Î ÀÐÀ¸¸é¼­ °¢ row¸¶´Ù
ºÐ·ù Å×ÀÌºí¿¡¼­ ÇØ´çºÐ·ùÄڵ尡 µî±ÞÀÌ "A"ÀÎÁö üũÇÏ¿© °É·¯ÁÖ´Â ÇüÅ·Π󸮵ȴÙ.
ÀÌ·±°æ¿ì ÀϹÝÀûÀ¸·Î Äõ¸®¼º´ÉÀÌ ¶³¾îÁö°Ô µÇ´Â°ÍÀÌ´Ù.

±×·¯¸é Á¶Àι®À» »ç¿ëÇÏÁö ¿Ö ±»ÀÌ in-subquary¸¦ »ç¿ëÇß´À³Ä ?
À§ »ùÇÃÀÌ ±×´ÙÁö ÁÁÀº »ùÇÃÀÌ ¾Æ´Ï¶ó ±×·±°ÍÀÌ°í ¾Æ·¡ »ùÇÃÀ» º¸ÀÚ.

use tempdb
go

set statistics profile off
set statistics io off

--¿¹Á¦1.
Å×½ºÆ®¸¦ À§ÇÑ »ùÇà ÀÛ¼º
--drop table ÄÚµå
create table ÄÚµå(»óÇ°ÄÚµå int not null, »óÇ°¸í varchar(40))
go
alter table ÄÚµå
   add constraint pk_ÄÚµå primary key(»óÇ°ÄÚµå)
go
set nocount on
declare @i int
set @i = 1
while (@i <= 50)
begin
   insert into ÄÚµå values(@i, convert(varchar(10), @i) )
   set @i = @i + 1
end
set nocount off
go
select count(*) from ÄÚµå --50

--drop table ¸ÅÃ⸶°¨
create table ¸ÅÃ⸶°¨(»óÇ°ÄÚµå int not null, ¸ÅÃâÀÏÀÚ char(8) not null, ¼ö·® int)
go
alter table ¸ÅÃ⸶°¨
   add constraint pk_¸ÅÃ⸶°¨ primary key (»óÇ°ÄÚµå, ¸ÅÃâÀÏÀÚ)
go
set nocount on

declare @i int, @j int
declare @dt datetime

set @i = 1
set @dt = "2000-01-01"

while (@dt < "2004-01-01") --4³âÄ¡ »ùÇÃÀÚ·á ¸¸µé±¸
begin
   set @j = 1
   while (@j <= 50)
   begin
      insert into ¸ÅÃ⸶°¨ values(@j, convert(varchar(8), @dt, 112), convert(int, rand() * 1000) )
      set @j = @j + 1
   end
   set @dt = dateadd(dd, 1, @dt)
end
set nocount off
go
select count(*) from ¸ÅÃ⸶°¨  --73050

set statistics profile on
set statistics io on

--¹®Á¦ : 2003 ³â 5¿ù ¸¶°¨³»¿ª list ?

1. ÀϹÝÀûÀ¸·Î ±×³É ¾Æ¹«»ý°¢¾øÀÌ Äõ¸®¸¦ ÇÑ´Ù¸é
select * from ¸ÅÃ⸶°¨
where ¸ÅÃâÀÏÀÚ between "20030501" and "20030531"
  |--Clustered Index Scan(OBJECT:([T1].[dbo].[¸ÅÃ⸶°¨].[pk_¸ÅÃ⸶°¨]),
     WHERE:([¸ÅÃ⸶°¨].[¸ÅÃâÀÏÀÚ]>=[@1] AND [¸ÅÃ⸶°¨].[¸ÅÃâÀÏÀÚ]<=[@2]))

"¸ÅÃ⸶°¨" Å×À̺í. ½ºÄµ ¼ö 1, ³í¸®Àû Àб⠼ö 299, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.

index seekÀÌ ¾Æ´Ï¶ó index scan¹æ½ÄÀ¸·Î ½ÇÇó°èȹÀÌ Ç®·È´Ù.
À妽º¸¦ È°¿ëÀ» ¸øÇÑ´Ù. ù¹ø° Ä÷³À» »ç¿ëÇÏÁö ¸øÇϱ⠶§¹®ÀÌ´Ù.

2. ù¹ø° Ä÷³À» in-subquary¸¦ »ç¿ëÇÏ¿© ÀÎÀ§ÀûÀ¸·Î °ø±ÞÇÔÀ¸·Î½á
   Á¤»óÀûÀ¸·Î À妽º¸¦ È°¿ëÇÏ°Ô²û ÇÑ´Ù.
select * from ¸ÅÃ⸶°¨
where »óÇ°ÄÚµå in (select »óÇ°ÄÚµå from ÄÚµå)
and ¸ÅÃâÀÏÀÚ between "20030501" and "20030531"
  |--Nested Loops(Inner Join, OUTER REFERENCES:([ÄÚµå].[»óÇ°ÄÚµå]) WITH PREFETCH)
       |--Clustered Index Scan(OBJECT:([T1].[dbo].[ÄÚµå].[pk_ÄÚµå]))
       |--Clustered Index Seek(OBJECT:([T1].[dbo].[¸ÅÃ⸶°¨].[pk_¸ÅÃ⸶°¨]),
          SEEK:([¸ÅÃ⸶°¨].[»óÇ°ÄÚµå]=[ÄÚµå].[»óÇ°ÄÚµå]
            AND [¸ÅÃ⸶°¨].[¸ÅÃâÀÏÀÚ] >= "20030501"
            AND [¸ÅÃ⸶°¨].[¸ÅÃâÀÏÀÚ] <= "20030531") ORDERED FORWARD)

"¸ÅÃ⸶°¨" Å×À̺í. ½ºÄµ ¼ö 50, ³í¸®Àû Àб⠼ö 112, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.
"ÄÚµå" Å×À̺í. ½ºÄµ ¼ö 1, ³í¸®Àû Àб⠼ö 2, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.

Á¤»óÀûÀ¸·Î À妽º¸¦ Àß È°¿ëÇÏ¿´°í Äõ¸®¼º´É¶ÇÇÑ ÈξÀ ¶Ù¾î³ª´Ù.

±×·¯³ª, ÀÌ°ÍÀº Å×½ºÆ®¸¦ À§ÇÏ¿© ÀÎÀ§ÀûÀ¸·Î ±×·¸°Ô ÇÑ°ÍÀÌ°í ½Ç¹«¿¡¼­´Â ´Ù¾çÇÑ »óȲÀ»
°ËÅäÇÏ¿© »ç¿ë¿©ºÎ¸¦ ÆÇ´ÜÇؾßÇÑ´Ù. Á¤¸» sqlÀº ¾î·Æ´Ù.

ÀÌ¿¹Á¦ÀÇ °æ¿ìµµ »ùÇÃÀ» ¸¸µé¶§ 4³âÄ¡¸¦ ¸¸µéÁö ¾Ê°í 1³âÄ¡¸¸ ¸¸µé¾î¼­ Å×½ºÆ®¸¦ Çغ¸¸é
1¹ø °æ¿ìó·³ ±×³É clustered index scan À» Çϴ°ÍÀÌ ÈξÀ È¿À²ÀÌ ´õ ÁÁ´Ù.
ÀÌ¿¹Á¦¸¦ º¸¸é óÀ½ 2³âÁ¤µµ´Â ±×³É Äõ¸®ÇÏ¿© clustered index scan À» À¯µµÇÏ°í
ÀÌÈÄ µ¥ÀÌÅÍ°¡ ´õ ¸¹ÀÌ ½×ÀÌ°Ô µÇ¸é in-subquary¸¦ È°¿ëÇÏ¿© clustered index seek À»
À¯µµÇÏ´Â ¹æ½ÄÀ» »ç¿ëÇØ¾ß Äõ¸®È¿À²À» ÀÏÁ¤ÇÏ°Ô À¯ÁöÇÒ¼ö ÀÖ´Ù.
ÀÌ·±°ÍÀÌ sqlÀÇ Àç¹Ì°¡ ¾Æ´Ò±î ?

--¿¹Á¦2. : in-subquary¸¦ »ç¿ëÇÏ¿© À妽º¸¦ »ç¿ëÇÏ°Ô²û À¯µµÇÑ°ÍÀÌ ¿ÀÈ÷·Á È¿À²À» ¶³¾î¶ß¸®´Â °æ¿ì

Å×½ºÆ®¸¦ À§ÇÑ »ùÇà ÀÛ¼º

set statistics profile off
set statistics io off

--drop table t1
create table t1(dt char(8) not null, seq int not null, qty int, c1 char(100))
go
alter table t1
   add constraint pk_t1 primary key (dt, seq)
go
set nocount on
declare @dt datetime
declare @i int, @j int

set @dt = "2000-01-01"
while (@dt < "2004-01-01")
begin
   set @i = convert(int, rand() * 100)
   set @j = 1
   while (@j <= @i)
   begin
      insert into t1 values(convert(varchar(8),@dt,112),@j,
                            convert(int,rand()*1000),convert(varchar(10),@j))
      set @j = @j + 1
   end
   set @dt = dateadd(dd, 1, @dt)
end
set nocount off

select count(*) from t1  --74007

--drop table dumy_dt
create table dumy_dt(dt char(8) not null, dt1 datetime)
go
alter table dumy_dt
   add constraint pk_dumy_dt primary key(dt)
go
set nocount on
declare @dt datetime

set @dt = "2000-01-01"
while (@dt < "2004-01-01")
begin
   insert into dumy_dt values( convert(varchar(8), @dt, 112), @dt )
   set @dt = dateadd(dd, 1, @dt)
end
set nocount off

--¹®Á¦ : 1¿ù ÀϺ° ÀÚ·áÁß seq °¡ 3 º¸´Ù ÀÛÀº list ?
set statistics profile on
set statistics io on

select * from t1
where dt like "200301%"
and seq < 3
  |--Clustered Index Seek(OBJECT:([T1].[dbo].[t1].[pk_t1]),
     SEEK:([t1].[dt] >= "200301" AND [t1].[dt] < "200302"), 
     WHERE:([t1].[seq]<3 AND like([t1].[dt], "200301%", NULL)) ORDERED FORWARD)
"t1" Å×À̺í. ½ºÄµ ¼ö 1, ³í¸®Àû Àб⠼ö 25, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.

select * from t1
where dt like "200301%"
and seq in (1, 2)
  |--Clustered Index Seek(OBJECT:([T1].[dbo].[t1].[pk_t1]),
     SEEK:([t1].[dt] >= "200301" AND [t1].[dt] < "200302"), 
     WHERE:(like([t1].[dt], "200301%", NULL) AND ([t1].[seq]=2 OR [t1].[seq]=1)) ORDERED FORWARD)
"t1" Å×À̺í. ½ºÄµ ¼ö 1, ³í¸®Àû Àб⠼ö 25, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.

select * from t1
where dt in (select dt from dumy_dt where dt like "200301%")
and seq in (1, 2)
  |--Nested Loops(Inner Join, OUTER REFERENCES:([dumy_dt].[dt]) WITH PREFETCH)
       |--Clustered Index Seek(OBJECT:([T1].[dbo].[dumy_dt].[pk_dumy_dt]),
          SEEK:([dumy_dt].[dt] >= "200301" AND [dumy_dt].[dt] < "200302"),  
          WHERE:(like([dumy_dt].[dt], "200301%", NULL)) ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([T1].[dbo].[t1].[pk_t1]),
          SEEK:([t1].[dt]=[dumy_dt].[dt] AND [t1].[seq]=1 OR
                [t1].[dt]=[dumy_dt].[dt] AND [t1].[seq]=2) ORDERED FORWARD)
"t1" Å×À̺í. ½ºÄµ ¼ö 62, ³í¸®Àû Àб⠼ö 207, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.
"dumy_dt" Å×À̺í. ½ºÄµ ¼ö 1, ³í¸®Àû Àб⠼ö 2, ¹°¸®Àû Àб⠼ö 0, ¹Ì¸® Àб⠼ö 0.

À§ °á°ú¸¦ º¸¸é ÀÌ°æ¿ì´Â ¿ÀÈ÷·Á in-subquary¸¦ »ç¿ëÇÏ¿© index scan À» index seek ·Î À¯µµÇÑ°ÍÀÌ
¿ÀÈ÷·Á Äõ¸® È¿À²À» ¶³¾î¶ß¸®´Â °æ¿ìÀÌ´Ù.

Áï, »óȲ¿¡ µû¶ó ÆÇ´ÜÇØ¾ß Çϴ°ÍÀÌ´Ù.
¸ðµç °æ¿ì¿¡ È¿À²ÀûÀÎ Äõ¸®¶õ º°·ç ¾ø´Ù.

/*-----------------------------------------------------------------------*/
¸¶Áö¸·À¸·Î Á¤¸®¸¦ Çغ¸ÀÚ.
/*-----------------------------------------------------------------------*/
--¸ÕÀú »ùÇø¸µé±¸
set statistics profile off
set statistics io off

set nocount on
go
drop table ±Þ¿©
drop table »ç¿ø
drop table Á÷±Þ
drop table ºÎ¼­
go
create table ºÎ¼­
( ºÎ¼­ÄÚµå int not null primary key
, ºÎ¼­¸í varchar(40)
, ºÎ¼­±¸ºÐ int)
go
create index idx_ºÎ¼­±¸ºÐ on ºÎ¼­(ºÎ¼­±¸ºÐ)
create index idx_ºÎ¼­¸í on ºÎ¼­(ºÎ¼­¸í)
go
insert into ºÎ¼­ values (1, "°³¹ßºÎ", 2)
insert into ºÎ¼­ values (2, "¿µ¾÷ºÎ", 3)
insert into ºÎ¼­ values (3, "Ãѹ«ºÎ", 1)
insert into ºÎ¼­ values (4, "ÀÎÅͳݻç¾÷ºÎ", 2)
insert into ºÎ¼­ values (5, "Çϵå¿þ¾îºÎ", 2)
go

create table Á÷±Þ
( Á÷±ÞÄÚµå int not null primary key
, Á÷±Þ¸í varchar(40))
go
create index idx_Á÷±Þ¸í on Á÷±Þ(Á÷±Þ¸í)
go
insert into Á÷±Þ values(1, "»ç¿ø")
insert into Á÷±Þ values(2, "´ë¸®")
insert into Á÷±Þ values(3, "°úÀå")
insert into Á÷±Þ values(4, "Â÷Àå")
insert into Á÷±Þ values(5, "ºÎÀå")
insert into Á÷±Þ values(6, "ÀÌ»ç")
go

create table »ç¿ø
( »ç¿ø¹øÈ£ int not null
, À̸§ varchar(10)
, ÀÔ»çÀÏÀÚ char(8)
, Á÷±ÞÄÚµå int
, ºÎ¼­ÄÚµå int)
go
--À妽º Å×½ºÆ®¸¦ ¸ñÀûÀ¸·Î nonclustered ·Î Àâ¾ÒÀ½.
alter table »ç¿ø
add constraint pk_»ç¿ø primary key nonclustered(»ç¿ø¹øÈ£)
create index idx_ºÎ¼­ÄÚµå on »ç¿ø(ºÎ¼­ÄÚµå)
create index idx_Á÷±ÞÄÚµå on »ç¿ø(Á÷±ÞÄÚµå)
create index idx_À̸§ on »ç¿ø(À̸§)
create index idx_ÀÔ»çÀÏÀÚ on »ç¿ø(ÀÔ»çÀÏÀÚ)

alter table »ç¿ø
add constraint fk_ºÎ¼­ foreign key(ºÎ¼­ÄÚµå)
references ºÎ¼­(ºÎ¼­ÄÚµå)
alter table »ç¿ø
add constraint fk_Á÷±Þ foreign key(Á÷±ÞÄÚµå)
references Á÷±Þ(Á÷±ÞÄÚµå)
go
insert into »ç¿ø values (1, "¯±¸",    "19990101", 1, 1)
insert into »ç¿ø values (2, "¸Í±¸",    "19990501", 1, 1)
insert into »ç¿ø values (3, "»×»×ÀÌ",  "20000101", 1, 1)
insert into »ç¿ø values (4, "°³¶ËÀÌ",  "20000101", 1, 3)
insert into »ç¿ø values (5, "ŸÀÜ",    "20000301", 2, 1)
insert into »ç¿ø values (6, "ġŸ",    "20000402", 2, 2)
insert into »ç¿ø values (7, "³­ÀåÀÌ",  "20000405", 2, 1)
insert into »ç¿ø values (8, "¹é¼³ÀÌ",  "20001011", 3, 1)
insert into »ç¿ø values (9, "ÀÀ»ïÀÌ",  "20010304", 3, 4)
insert into »ç¿ø values (10, "Ǫ",     "20010404", 4, 5)
insert into »ç¿ø values (11, "ƼĿ",   "20010404", 4, 1)
insert into »ç¿ø values (12, "»ÇºüÀÌ", "20021010", 5, 1)
insert into »ç¿ø values (13, "¿Ã¸®¹ö", "20030101", 1, 5)
go

create table ±Þ¿©
( »ç¿ø¹øÈ£ int not null
, ±Þ¿©³â¿ù char(6) not null
, ±Þ¿© int)
go
alter table ±Þ¿©
   add constraint pk_±Þ¿© primary key(»ç¿ø¹øÈ£, ±Þ¿©³â¿ù)
alter table ±Þ¿©
add constraint fk_±Þ¿© foreign key(»ç¿ø¹øÈ£)
references »ç¿ø(»ç¿ø¹øÈ£)
go
insert into ±Þ¿© values(1, "200212", 100)
insert into ±Þ¿© values(2, "200212", 150)
insert into ±Þ¿© values(3, "200212", 200)
insert into ±Þ¿© values(1, "200301", 100)
insert into ±Þ¿© values(2, "200301", 200)
insert into ±Þ¿© values(3, "200301", 400)
insert into ±Þ¿© values(4, "200301", 500)
insert into ±Þ¿© values(5, "200301", 100)
insert into ±Þ¿© values(6, "200301", 300)
insert into ±Þ¿© values(7, "200301", 100)
insert into ±Þ¿© values(8, "200301", 400)
insert into ±Þ¿© values(9, "200301", 100)
insert into ±Þ¿© values(10, "200301", 200)
insert into ±Þ¿© values(11, "200301", 100)
insert into ±Þ¿© values(12, "200301", 200)
insert into ±Þ¿© values(13, "200301", 100)
insert into ±Þ¿© values(1, "200302", 100)
insert into ±Þ¿© values(2, "200302", 600)
insert into ±Þ¿© values(3, "200302", 100)
insert into ±Þ¿© values(4, "200302", 500)
insert into ±Þ¿© values(5, "200302", 100)
insert into ±Þ¿© values(6, "200302", 400)
insert into ±Þ¿© values(7, "200302", 100)
insert into ±Þ¿© values(8, "200302", 200)
insert into ±Þ¿© values(9, "200302", 100)
insert into ±Þ¿© values(10, "200302", 300)
insert into ±Þ¿© values(11, "200302", 110)
insert into ±Þ¿© values(12, "200302", 100)
insert into ±Þ¿© values(13, "200302", 200)
insert into ±Þ¿© values(1, "200303", 200)
insert into ±Þ¿© values(2, "200303", 600)
insert into ±Þ¿© values(3, "200303", 130)
insert into ±Þ¿© values(4, "200303", 400)
insert into ±Þ¿© values(5, "200303", 100)
insert into ±Þ¿© values(6, "200303", 300)
insert into ±Þ¿© values(7, "200303", 100)
insert into ±Þ¿© values(8, "200303", 120)
insert into ±Þ¿© values(9, "200303", 100)
insert into ±Þ¿© values(10, "200303", 300)
insert into ±Þ¿© values(11, "200303", 150)
insert into ±Þ¿© values(12, "200303", 100)
insert into ±Þ¿© values(13, "200303", 100)
go
set nocount off
go

set statistics profile on
set statistics io on
/*-----------------------------------------------------------------------*/
1-1-1 in-subquary °¡ ¸ÕÀú ÀÐÈ÷´Â °æ¿ì(ÀϹÝÀûÀ¸·Î ¿øÇÏ´Â ÇüÅÂ)
/*-----------------------------------------------------------------------*/
select * from »ç¿ø
where ºÎ¼­ÄÚµå in (select ºÎ¼­ÄÚµå from ºÎ¼­ where ºÎ¼­±¸ºÐ = 1)  
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([ºÎ¼­].[ºÎ¼­ÄÚµå]))
            |--Index Seek(OBJECT:([tempdb].[dbo].[ºÎ¼­].[idx_ºÎ¼­±¸ºÐ]),
                  SEEK:([ºÎ¼­].[ºÎ¼­±¸ºÐ]=1) ORDERED FORWARD)
            |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ºÎ¼­ÄÚµå]),
                  SEEK:([»ç¿ø].[ºÎ¼­ÄÚµå]=[ºÎ¼­].[ºÎ¼­ÄÚµå]) ORDERED FORWARD)

/*-----------------------------------------------------------------------*/
1-1-2. in-subquary °¡ ³ªÁß¿¡ ÀÐÈ÷´Â °æ¿ì
/*-----------------------------------------------------------------------*/
--create index idx_ºÎ¼­ÄÚµå on »ç¿ø(ºÎ¼­ÄÚµå)
drop index »ç¿ø.idx_ºÎ¼­ÄÚµå --Å×½ºÆ®¸¦ À§Çؼ­ °­Á¦ÀûÀ¸·Î À妽º¸¦ Áö¿ì°í
go
select * from »ç¿ø
where ºÎ¼­ÄÚµå in (select ºÎ¼­ÄÚµå from ºÎ¼­ where ºÎ¼­±¸ºÐ = 1)  
  |--Nested Loops(Left Semi Join, OUTER REFERENCES:([»ç¿ø].[ºÎ¼­ÄÚµå]))
       |--Table Scan(OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Index Seek(OBJECT:([tempdb].[dbo].[ºÎ¼­].[idx_ºÎ¼­±¸ºÐ]),
                SEEK:([ºÎ¼­].[ºÎ¼­±¸ºÐ]=1 AND [ºÎ¼­].[ºÎ¼­ÄÚµå]=[»ç¿ø].[ºÎ¼­ÄÚµå]) ORDERED FORWARD)

select * from »ç¿ø
where »ç¿ø¹øÈ£ in (select »ç¿ø¹øÈ£ from ±Þ¿© where ±Þ¿©³â¿ù like "2002%")
  |--Nested Loops(Left Semi Join, OUTER REFERENCES:([»ç¿ø].[»ç¿ø¹øÈ£]))
       |--Table Scan(OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[±Þ¿©].[pk_±Þ¿©]),
             SEEK:([±Þ¿©].[»ç¿ø¹øÈ£]=[»ç¿ø].[»ç¿ø¹øÈ£]
               AND [±Þ¿©].[±Þ¿©³â¿ù] >= "2002" AND [±Þ¿©].[±Þ¿©³â¿ù] < "2003"), 
             WHERE:(like([±Þ¿©].[±Þ¿©³â¿ù], "2002%", NULL)) ORDERED FORWARD)

À̹ø¿¡´Â in-subquary°¡ ³ªÁß¿¡ ÀÐÇû³×¿ä.
Áï, ¿øÇϴ´ë·Î ÀÛµ¿À» ¾ÈÇÑ°ÍÀÌÁö¿ä. ÀÌ·±°æ¿ì´Â ¾öû³­ ºñÈ¿À²À» °¡Á®¿É´Ï´Ù.

À妽º¸¦ Çϳª¸¸µé±¸
create index idx_±Þ¿¬³â¿ù on ±Þ¿©(±Þ¿©³â¿ù)
go
select * from »ç¿ø
where »ç¿ø¹øÈ£ in (select »ç¿ø¹øÈ£ from ±Þ¿© where ±Þ¿©³â¿ù like "2002%")
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([±Þ¿©].[»ç¿ø¹øÈ£]))
            |--Sort(DISTINCT ORDER BY:([±Þ¿©].[»ç¿ø¹øÈ£] ASC))
            |    |--Index Seek(OBJECT:([tempdb].[dbo].[±Þ¿©].[idx_±Þ¿¬³â¿ù]),
                       SEEK:([±Þ¿©].[±Þ¿©³â¿ù] >= "2002" AND [±Þ¿©].[±Þ¿©³â¿ù] < "2003"), 
                       WHERE:(like([±Þ¿©].[±Þ¿©³â¿ù], "2002%", NULL)) ORDERED FORWARD)
            |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[pk_»ç¿ø]),
                  SEEK:([»ç¿ø].[»ç¿ø¹øÈ£]=[±Þ¿©].[»ç¿ø¹øÈ£]) ORDERED FORWARD)

ÀÌÁ¦ Á¤»óÀûÀ¸·Î in-subquary°¡ ¸ÕÀú ÀÐÇûÁö¿ä.
À妽º¶ó´Â °ÍÀÌ ÀÌ·¸°Ô ¾öû³­ Â÷À̸¦ °¡Á®¿À´Â °ÍÀÔ´Ï´Ù.
±×·¸´Ù°í, ÀÌ·±½ÄÀ¸·Î À妽º¸¦ ¹«ÇÑÁ¤ ¸¸µé¼ö´Â ¾ø´Â°ÍÀÌÁö¿ä.
±×·¡¼­, À妽º¸¦ ¸¸µå´Â°ÍÀ» Àü·«À̶ó°íµé ÇÕ´Ï´Ù.
±×¸¸Å­ ¸¹Àº °æ¿ìÀÇ ¼ö¸¦ µûÁ®º¸°í Äõ¸®À¯ÇüÀ» ¸é¹ÐÈ÷ ÆľÇÇÑ´ÙÀ½
¸Ó¸®Ä«¶ôÀÌ ºüÁúÁ¤µµ·Î °í¹ÎÇغ¸°í ¸¸µé¾î¾ßÇϴ°ÍÀÌÁö¿ä.
/*==========================================================*/
2. union : µÎ °³ ÀÌ»óÀÇ Äõ¸® °á°ú¸¦ ¸ðµç Äõ¸®¿¡ ¼ÓÇÏ´Â ¸ðµç ÇàÀÇ ÇÕÀ¸·Î ±¸¼ºµÇ´Â
           ÇϳªÀÇ °á°ú ÁýÇÕÀ¸·Î °áÇÕÇÕ´Ï´Ù.
           ÀÌ°ÍÀº µÎ Å×À̺íÀÇ ¿­À» °áÇÕÇÏ´Â Á¶ÀÎÀ» »ç¿ëÇÏ´Â °Í°ú´Â ´Ù¸¨´Ï´Ù.

UNION ¿¬»êÀÚ¸¦ »ç¿ëÇÏ¿© µÎ °³ÀÇ Äõ¸® °á°ú ÁýÇÕÀ» °áÇÕÇÒ ¶§´Â ´ÙÀ½ µÎ °¡Áö ±âº» ±ÔÄ¢À» µû¶ó¾ß ÇÕ´Ï´Ù.
¿­ÀÇ °³¼ö¿Í ¼ø¼­°¡ ¸ðµç Äõ¸®¿¡¼­ µ¿ÀÏÇØ¾ß ÇÕ´Ï´Ù.
µ¥ÀÌÅÍ Çü½ÄÀÌ È£È¯µÇ¾î¾ß ÇÕ´Ï´Ù.

±¸¹®
     { < query specification > | ( < query expression > ) }
        UNION [ ALL ]
        < query specification | ( < query expression > )
            [ UNION [ ALL ] < query specification | ( < query expression > )
                 [ ...n ] ]

/*-----------------------------------------------------------------------*/
2-1. »ç¿ëÇüÅÂ
   1. ÇÕÁýÇÕ(À§¿¡¼­ ºÃÀ¸¹Ç·Î »ý·«) - ¿Â¶óÀμ³¸í¼­¿¡µµ ¼³¸íÀÌ ÀߵǾî ÀÖÀ¸´Ï Âü°í
   2. Full Outer JoinÀÇ ´ë¾È
   3. ½ÇÇà°èȹÀÇ ºÐ¸®

/*-----------------------------------------------------------------------*/
2-1-1. Full Outer JoinÀÇ ´ë¾È
/*-----------------------------------------------------------------------*/
--drop table ¿¹±Ý³»¿ª
create table ¿¹±Ý³»¿ª(ÅëÀå¹øÈ£ int, ÀϷùøÈ£ int, ¿¹±ÝÀÏÀÚ char(10), ¿¹±Ý¾× int)
insert into ¿¹±Ý³»¿ª values (1, 1, "2003-06-01", 100)
insert into ¿¹±Ý³»¿ª values (1, 2, "2003-06-03", 100)
insert into ¿¹±Ý³»¿ª values (1, 3, "2003-06-05", 100)
insert into ¿¹±Ý³»¿ª values (1, 4, "2003-06-07", 100)
go
--drop table Ãâ±Ý³»¿ª
create table Ãâ±Ý³»¿ª(ÅëÀå¹øÈ£ int, ÀϷùøÈ£ int, Ãâ±ÝÀÏÀÚ char(10), Ãâ±Ý¾× int)
insert into Ãâ±Ý³»¿ª values (1, 1, "2003-06-01", 50)
insert into Ãâ±Ý³»¿ª values (1, 2, "2003-06-02", 50)
insert into Ãâ±Ý³»¿ª values (1, 3, "2003-06-05", 50)


¹®Á¦ : À§¿Í °°ÀÌ Å×À̺íÀÌ ¼³°èµÇ¾î ÀÖ´Ù°í ÇÏÀÚ. ¹°·Ð ÀԱݳ»¿ª°ú Ãâ±Ý³»¿ªÀº ¾÷¹«ÀûÀ¸·Î
ÇϳªÀÇ Å×À̺í·Î ¼³°è¸¦ Çß¾î¾ß ÇßÁö¸¸, ÀÌ¹Ì Àú·¸°Ô ¼³°èµÈ´ë·Î ¸î³âÀ» »ç¿ëÇØ¿Ô°í, ¼³°èº¯°æÀÌ
ÈûÀÌ µé´Ù´Â °¡Á¤ÇÏ¿¡¼­ ÀÏÀÚº° ÀÔÃâ±Ý³»¿ªÀ» º¸ÀÚ

1. Full Outer Join»ç¿ë
select case when x.ÅëÀå¹øÈ£ is not null then x.ÅëÀå¹øÈ£ else y.ÅëÀå¹øÈ£ end ÅëÀå¹øÈ£,
       case when x.¿¹±ÝÀÏÀÚ is not null then x.¿¹±ÝÀÏÀÚ else y.Ãâ±ÝÀÏÀÚ end ÀÔÃâ±ÝÀÏÀÚ,
       isnull(x.¿¹±Ý¾×, 0) ¿¹±Ý¾×,
       isnull(y.Ãâ±Ý¾×, 0) Ãâ±Ý¾×
from ¿¹±Ý³»¿ª x full outer join Ãâ±Ý³»¿ª y
on x.ÅëÀå¹øÈ£ = y.ÅëÀå¹øÈ£
and x.¿¹±ÝÀÏÀÚ = y.Ãâ±ÝÀÏÀÚ
order by case when x.¿¹±ÝÀÏÀÚ is not null then x.¿¹±ÝÀÏÀÚ else y.Ãâ±ÝÀÏÀÚ end

ÀÌ·±½ÄÀ¸·Î full outer joinÀ» »ç¿ëÇÏ¸é µÇÁö¸¸ °æ¿ì¿¡ µû¶ó¼­´Â union À» ÅëÇؼ­µµ °¡´ÉÇÏ´Ù.

2. Union »ç¿ë
select ÅëÀå¹øÈ£, ÀÔÃâ±ÝÀÏÀÚ, sum(¿¹±Ý¾×) ¿¹±Ý¾×, sum(Ãâ±Ý¾×) Ãâ±Ý¾×
from (
      select ÅëÀå¹øÈ£, ¿¹±ÝÀÏÀÚ as ÀÔÃâ±ÝÀÏÀÚ, ¿¹±Ý¾×, 0 as Ãâ±Ý¾× from ¿¹±Ý³»¿ª
      union all
      select ÅëÀå¹øÈ£, Ãâ±ÝÀÏÀÚ as ÀÔÃâ±ÝÀÏÀÚ, 0 as ¿¹±Ý¾×, Ãâ±Ý¾× from Ãâ±Ý³»¿ª
) x
group by ÅëÀå¹øÈ£, ÀÔÃâ±ÝÀÏÀÚ
order by ÀÔÃâ±ÝÀÏÀÚ

´Ù¾çÇÑ ÇØ°á¹æ¹ýÀ» ¾Ë°í °æ¿ì¿¡ µû¶ó¼­ ÀûÀýÈ÷ »ç¿ëÇÏ¸é µÇ°Ú³×¿ä.

/*-----------------------------------------------------------------------*/
2-1-2. ½ÇÇà°èȹºÐ¸®ÀÇ union
/*-----------------------------------------------------------------------*/
-- ¿¹Á¦1.
select * from »ç¿ø
where ÀÔ»çÀÏÀÚ like "2000%"
and ºÎ¼­ÄÚµå in (select ºÎ¼­ÄÚµå from ºÎ¼­ where ºÎ¼­±¸ºÐ=1)
  |--Nested Loops(Left Semi Join, WHERE:([»ç¿ø].[ºÎ¼­ÄÚµå]=[ºÎ¼­].[ºÎ¼­ÄÚµå]))
       |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |    |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ÀÔ»çÀÏÀÚ]),
                  SEEK:([»ç¿ø].[ÀÔ»çÀÏÀÚ] >= "2000" AND [»ç¿ø].[ÀÔ»çÀÏÀÚ] < "200¼"), 
                  WHERE:(like([»ç¿ø].[ÀÔ»çÀÏÀÚ], "2000%", NULL)) ORDERED FORWARD)
       |--Index Seek(OBJECT:([tempdb].[dbo].[ºÎ¼­].[idx_ºÎ¼­±¸ºÐ]),
             SEEK:([ºÎ¼­].[ºÎ¼­±¸ºÐ]=1) ORDERED FORWARD)

select * from »ç¿ø2
where ÀÔ»çÀÏÀÚ like "2000%"
union
select * from »ç¿ø2
where ºÎ¼­ÄÚµå in (select ºÎ¼­ÄÚµå from ºÎ¼­ where ºÎ¼­±¸ºÐ=1)
  |--Sort(DISTINCT ORDER BY:([Union1006] ASC, [Union1007] ASC,
                             [Union1008] ASC, [Union1009] ASC, [Union1010] ASC))
       |--Concatenation
            |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø2]))
            |    |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø2].[idx_ÀÔ»çÀÏÀÚ]),
                       SEEK:([»ç¿ø2].[ÀÔ»çÀÏÀÚ] >= "2000" AND [»ç¿ø2].[ÀÔ»çÀÏÀÚ] < "200¼"), 
                       WHERE:(like([»ç¿ø2].[ÀÔ»çÀÏÀÚ], "2000%", NULL)) ORDERED FORWARD)
            |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([tempdb].[dbo].[»ç¿ø2]))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([ºÎ¼­].[ºÎ¼­ÄÚµå]))
                      |--Index Seek(OBJECT:([tempdb].[dbo].[ºÎ¼­].[idx_ºÎ¼­±¸ºÐ]),
                            SEEK:([ºÎ¼­].[ºÎ¼­±¸ºÐ]=1) ORDERED FORWARD)
                      |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø2].[idx_ºÎ¼­ÄÚµå]),
                            SEEK:([»ç¿ø2].[ºÎ¼­ÄÚµå]=[ºÎ¼­].[ºÎ¼­ÄÚµå]) ORDERED FORWARD)

¿¹Á¦°¡ º°·ç ÁÁÁö¸øÇÏÁö¸¸ ÀÌ·±½ÄÀ¸·Îµµ °¢°¢ÀÇ À妽º¸¦ »ç¿ëÇÏ°Ô²û ÇÒ¼öµµÀÖ´Ù´Â°Í Á¤µµ¸¸ ¾Ë°íÀÖÀÚ.

-- ¿¹Á¦2.(or¸¦ »ç¿ëÇÑ ¾ÈÁÁÀº ¹æ¹ýÀÌ´Ù.)
»ç¿øÁ¤º¸¸¦ º¸¿©ÁÖ´Â È­¸é»ó¿¡¼­ Á¶°Ç°ªÀ¸·Î »ç¿ø¹øÈ£¿Í ºÎ¼­Äڵ带 ÀԷ¹޴ ȭ¸éÀÌ ÀÖ´Ù°í
°¡Á¤À» ÇÏ°í Äõ¸®¹®À» ¸¸µé¾î º¸ÀÚ.(µÑÁß Çϳª¸¸ ÀԷµȴÙ. - ¿É¼Ç¹Ú½º³ª ÅǵîÀ» ÀÌ¿ëÇÑ´Ù°í °¡Á¤)

1. °¡Àå ÆíÇÑ or¸¦ »ç¿ëÇÑ ¹æ¹ý
--drop proc p1
create proc p1(@»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int)
as
select * from »ç¿ø
    where »ç¿ø¹øÈ£ = @»ç¿ø¹øÈ£
       or ºÎ¼­ÄÚµå = @ºÎ¼­ÄÚµå
go

declare @»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int
set @»ç¿ø¹øÈ£ = 3
set @ºÎ¼­ÄÚµå = null
exec p1 @»ç¿ø¹øÈ£, @ºÎ¼­ÄÚµå
  |--Table Scan(OBJECT:([tempdb].[dbo].[»ç¿ø]),
        WHERE:([»ç¿ø].[»ç¿ø¹øÈ£]=[@»ç¿ø¹øÈ£] OR [»ç¿ø].[ºÎ¼­ÄÚµå]=[@ºÎ¼­ÄÚµå]))

ÀÌ·±, ¼ÀÇà µ¥ÀÌÅÍ°¡ ¿ö³«¿¡ Àû´Ùº¸´Ï table scanÀ» Çϳ׿ä
µ¥ÀÌÅÍ·®ÀÌ ¸¹ÀÌ ÀÖ´Ù¸é ÀÌ·¸°Ô ¾ÈµÇ°í ¾Æ¸¶µµ »ç¿ø¹øÈ£À妽º¸¦ ÀÌ¿ëÇÏ°Ô²û ½ÇÇà°èȹÀÌ
Ç®·ÈÀ» °ÍÀÌ´Ù. ±×·¸Áö¸¸ ´ÙÀ½¹ø Äõ¸®½Ã »ç¿ø¹øÈ£¸¦ null·Î ÇÏ°í ºÎ¼­Äڵ带 ÀÔ·ÂÇÑ´Ù¸é
¾î¶»°Ô µÉ°ÍÀΰ¡...?

2. unionÀ» »ç¿ëÇÏ¿© ½ÇÇà°èȹ ºÐ¸®

drop proc p1 --Áö¿ì°í ´Ù½Ã¸¸µéÀÚ
go
create proc p1(@»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int)
as
    select * from »ç¿ø
    where @»ç¿ø¹øÈ£ is not null
      and »ç¿ø¹øÈ£ = @»ç¿ø¹øÈ£
    union all
    select * from »ç¿ø
    where @»ç¿ø¹øÈ£ is null
      and ºÎ¼­ÄÚµå = @ºÎ¼­ÄÚµå
go
--»ç¿ø¹øÈ£°¡ ³Ñ¾î¿À¸é ¹«Á¶°Ç pk¸¦ »ç¿ëÇÏ°í,
--±×·¸Áö ¾Ê´Ù¸é ºÎ¼­ÄÚµå À妽º¸¦ »ç¿ëÇÏ°Ô²û ½ÇÇà°èȹÀ» ºÐ¸®ÇÏ¿´´Ù.
--ÀÌ°æ¿ì union ÀÌ ¾Æ´Ï¶ó union all À» »ç¿ëÇÏ¿´´Ù.
--ÀÌ·±½ÄÀÇ Äõ¸®¹®À» ¸¸µé¶§ ÁÖÀÇÇÒ°ÍÀº µÑÁßÇϳª¸¸ ÂüÀÌ¿©¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.

declare @»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int
set @»ç¿ø¹øÈ£ = 3
set @ºÎ¼­ÄÚµå = null
exec p1 @»ç¿ø¹øÈ£, @ºÎ¼­ÄÚµå
  |--Concatenation
       |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |    |--Filter(WHERE:(STARTUP EXPR([@»ç¿ø¹øÈ£]<>NULL)))
       |         |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[pk_»ç¿ø]),
                       SEEK:([»ç¿ø].[»ç¿ø¹øÈ£]=[@»ç¿ø¹øÈ£]) ORDERED FORWARD)
       |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
            |--Filter(WHERE:(STARTUP EXPR([@»ç¿ø¹øÈ£]=NULL)))
                 |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ºÎ¼­ÄÚµå]),
                       SEEK:([»ç¿ø].[ºÎ¼­ÄÚµå]=[@ºÎ¼­ÄÚµå]) ORDERED FORWARD)

declare @»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int
set @»ç¿ø¹øÈ£ = null
set @ºÎ¼­ÄÚµå = 1
exec p1 @»ç¿ø¹øÈ£, @ºÎ¼­ÄÚµå
  |--Concatenation
       |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |    |--Filter(WHERE:(STARTUP EXPR([@»ç¿ø¹øÈ£]<>NULL)))
       |         |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[pk_»ç¿ø]),
                       SEEK:([»ç¿ø].[»ç¿ø¹øÈ£]=[@»ç¿ø¹øÈ£]) ORDERED FORWARD)
       |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
            |--Filter(WHERE:(STARTUP EXPR([@»ç¿ø¹øÈ£]=NULL)))
                 |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ºÎ¼­ÄÚµå]),
                       SEEK:([»ç¿ø].[ºÎ¼­ÄÚµå]=[@ºÎ¼­ÄÚµå]) ORDERED FORWARD)

µÎ°¡Áö °æ¿ì´Ù ¿øÇϴ´ë·Î Á¤È®È÷ ½ÇÇà°èȹÀÌ ºÐ¸®µÇ¾î ¾ðÁ¦³ª ¿øÇÏ´Â À妽º¸¦ Àß »ç¿ëÇÑ´Ù.

3.µ¿ÀûÄõ¸® »ç¿ë
drop proc p1 --Áö¿ì°í ´Ù½Ã¸¸µéÀÚ
go
create proc p1(@»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int)
as
declare @sql varchar(1000)
set @sql = "select * from »ç¿ø where "
set @sql = @sql +
               case when @»ç¿ø¹øÈ£ is not null
                         then " »ç¿ø¹øÈ£ = " + convert(varchar(10), @»ç¿ø¹øÈ£)
                    else " ºÎ¼­ÄÚµå = " + convert(varchar(10), @ºÎ¼­ÄÚµå)
               end
--print @sql
exec (@sql)
go
declare @»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int
set @»ç¿ø¹øÈ£ = 3
set @ºÎ¼­ÄÚµå = null
exec p1 @»ç¿ø¹øÈ£, @ºÎ¼­ÄÚµå

SELECT * FROM [»ç¿ø] WHERE [»ç¿ø¹øÈ£]=@1
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[pk_»ç¿ø]),
             SEEK:([»ç¿ø].[»ç¿ø¹øÈ£]=Convert([@1])) ORDERED FORWARD)

declare @»ç¿ø¹øÈ£ int, @ºÎ¼­ÄÚµå int
set @»ç¿ø¹øÈ£ = null
set @ºÎ¼­ÄÚµå = 1
exec p1 @»ç¿ø¹øÈ£, @ºÎ¼­ÄÚµå

SELECT * FROM [»ç¿ø] WHERE [ºÎ¼­ÄÚµå]=@1
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ºÎ¼­ÄÚµå]),
             SEEK:([»ç¿ø].[ºÎ¼­ÄÚµå]=Convert([@1])) ORDERED FORWARD)

ÀÌ·±½ÄÀ¸·Î µ¿ÀûÄõ¸®¹®À» ¸¸µé¾î ½ÇÇàÀ» ÇÏ¸é ¸Å¹ø stored procedure¸¦ ÀçÄÄÆÄÀÏÇϸç
ÇØ´çÇÏ´Â À妽º¸¦ »ç¿ëÇÏ¿© ¿øÇÏ´Â °á°ú¸¦ ¾òÀ»¼ö ÀÖ´Ù.
ÇÏÁö¸¸ ÀÌ·±½ÄÀ̶ó¸é stored procedure¸¦ »ç¿ëÇÏ´Â È¿°ú¸¦ Á¦´ë·Î º¼¼ö¾ø´Ù.
¾î¶² ¹æ½ÄÀÌ ÁÁÀ»Áö´Â °¢ÀÚ ÆÇ´ÜÇÏÀÚ.

-- ¿¹Á¦3. (¿ä¹ø¿¡´Â like¸¦ »ç¿ëÇÑ ¾ÈÁÁÀº ¹æ¹ýÀÌ´Ù).
»ç¿øÁ¤º¸¸¦ º¸¿©ÁÖ´Â È­¸é»ó¿¡¼­ Á¶°Ç°ªÀ¸·Î »ç¿øÀ̸§°ú ÀÔ»ç¿ùÀ» ÀԷ¹޴ ȭ¸éÀÌ ÀÖ´Ù°í
°¡Á¤À» ÇÏ°í Äõ¸®¹®À» ¸¸µé¾î º¸ÀÚ.(µÑÁß Çϳª¸¸ ÀԷµȴÙ. - ¿É¼Ç¹Ú½º³ª ÅǵîÀ» ÀÌ¿ëÇÑ´Ù°í °¡Á¤)

1. °¡Àå ÆíÇÑ like ¹æ¹ý
--drop proc p2
create proc p2(@À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8))
as
select * from »ç¿ø where À̸§ like @À̸§
                          or ÀÔ»çÀÏÀÚ like @ÀÔ»çÀÏÀÚ
go

declare @À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8)
set @À̸§ = "¯%"
set @ÀÔ»çÀÏÀÚ = null
exec p2 @À̸§, @ÀÔ»çÀÏÀÚ
  |--Table Scan(OBJECT:([tempdb].[dbo].[»ç¿ø]),
        WHERE:(like([»ç¿ø].[À̸§], [@À̸§], NULL) OR like([»ç¿ø].[ÀÔ»çÀÏÀÚ], [@ÀÔ»çÀÏÀÚ], NULL)))

ÀÌ·±, ¼ÀÇà µ¥ÀÌÅÍ°¡ ¿ö³«¿¡ Àû´Ùº¸´Ï table scanÀ» Çϳ׿ä
µ¥ÀÌÅÍ·®ÀÌ ¸¹ÀÌ ÀÖ´Ù¸é ÀÌ·¸°Ô ¾ÈµÇ°í ¾Æ¸¶µµ À̸§À妽º¸¦ ÀÌ¿ëÇÏ°Ô²û ½ÇÇà°èȹÀÌ
Ç®·ÈÀ» °ÍÀÌ´Ù. ±×·¸Áö¸¸ ´ÙÀ½¹ø Äõ¸®½Ã À̸§À» null·Î ÇÏ°í ÀÔ»çÀÏÀÚ¸¦ ÀÔ·ÂÇÑ´Ù¸é
¾î¶»°Ô µÉ°ÍÀΰ¡...?

2. unionÀ» »ç¿ëÇÏ¿© ½ÇÇà°èȹ ºÐ¸®

drop proc p2 --Áö¿ì°í ´Ù½Ã¸¸µéÀÚ
go
create proc p2(@À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8))
as
    select * from »ç¿ø where À̸§ like @À̸§ and @À̸§ is not null
    union all
    select * from »ç¿ø where ÀÔ»çÀÏÀÚ like @ÀÔ»çÀÏÀÚ and @À̸§ is null
go
--À̸§ÀÌ ³Ñ¾î¿À¸é ¹«Á¶°Ç À̸§À妽º¸¦ »ç¿ëÇÏ°í,
--±×·¸Áö ¾Ê´Ù¸é ÀÔ»çÀÏÀÚÀ妽º¸¦ »ç¿ëÇÏ°Ô²û ½ÇÇà°èȹÀ» ºÐ¸®ÇÏ¿´´Ù.
--ÀÌ°æ¿ì union ÀÌ ¾Æ´Ï¶ó union all À» »ç¿ëÇÏ¿´´Ù.
--ÀÌ·±½ÄÀÇ Äõ¸®¹®À» ¸¸µé¶§ ÁÖÀÇÇÒ°ÍÀº µÑÁßÇϳª¸¸ ÂüÀÌ¿©¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.

declare @À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8)
set @À̸§ = "¯%"
set @ÀÔ»çÀÏÀÚ = null
exec p2 @À̸§, @ÀÔ»çÀÏÀÚ
  |--Concatenation
       |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |    |--Filter(WHERE:(STARTUP EXPR([@À̸§]<>NULL)))
       |         |--Nested Loops(Inner Join, OUTER REFERENCES:(LikeRangeStart([@À̸§], NULL),
                                                               LikeRangeEnd([@À̸§], NULL),
                                                               LikeRangeInfo([@À̸§], NULL)))
       |              |--Compute Scalar(DEFINE:([Expr1009]=LikeRangeStart([@À̸§], NULL),
                                                [Expr1011]=LikeRangeEnd([@À̸§], NULL),
                                                [Expr1013]=LikeRangeInfo([@À̸§], NULL)))
       |              |    |--Constant Scan
       |              |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_À̸§]),
                            SEEK:([»ç¿ø].[À̸§] > LikeRangeStart([@À̸§], NULL)
                              AND [»ç¿ø].[À̸§] < LikeRangeEnd([@À̸§], NULL)), 
                           WHERE:(like([»ç¿ø].[À̸§], [@À̸§], NULL)) ORDERED FORWARD)
       |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
            |--Filter(WHERE:(STARTUP EXPR([@À̸§]=NULL)))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1026], [Expr1027],
                                                   LikeRangeInfo([@ÀÔ»çÀÏÀÚ], NULL)))
                      |--Compute Scalar(DEFINE:([Expr1026]=Convert(LikeRangeStart([@ÀÔ»çÀÏÀÚ], NULL)),
                                                [Expr1027]=Convert(LikeRangeEnd([@ÀÔ»çÀÏÀÚ], NULL)),
                                                [Expr1020]=LikeRangeInfo([@ÀÔ»çÀÏÀÚ], NULL)))
                      |    |--Constant Scan
                      |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ÀÔ»çÀÏÀÚ]),
                            SEEK:([»ç¿ø].[ÀÔ»çÀÏÀÚ] > [Expr1026] AND [»ç¿ø].[ÀÔ»çÀÏÀÚ] < [Expr1027]), 
                            WHERE:(like([»ç¿ø].[ÀÔ»çÀÏÀÚ], [@ÀÔ»çÀÏÀÚ], NULL)) ORDERED FORWARD)

declare @À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8)
set @À̸§ = null
set @ÀÔ»çÀÏÀÚ = "2000%"
exec p2 @À̸§, @ÀÔ»çÀÏÀÚ
  |--Concatenation
       |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
       |    |--Filter(WHERE:(STARTUP EXPR([@À̸§]<>NULL)))
       |         |--Nested Loops(Inner Join, OUTER REFERENCES:(LikeRangeStart([@À̸§], NULL),
                                                               LikeRangeEnd([@À̸§], NULL),
                                                               LikeRangeInfo([@À̸§], NULL)))
       |              |--Compute Scalar(DEFINE:([Expr1009]=LikeRangeStart([@À̸§], NULL),
                                                [Expr1011]=LikeRangeEnd([@À̸§], NULL),
                                                [Expr1013]=LikeRangeInfo([@À̸§], NULL)))
       |              |    |--Constant Scan
       |              |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_À̸§]),
                            SEEK:([»ç¿ø].[À̸§] > LikeRangeStart([@À̸§], NULL)
                              AND [»ç¿ø].[À̸§] < LikeRangeEnd([@À̸§], NULL)), 
                            WHERE:(like([»ç¿ø].[À̸§], [@À̸§], NULL)) ORDERED FORWARD)
       |--Bookmark Lookup(BOOKMARK:([Bmk1002]), OBJECT:([tempdb].[dbo].[»ç¿ø]))
            |--Filter(WHERE:(STARTUP EXPR([@À̸§]=NULL)))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1026], [Expr1027],
                                                                LikeRangeInfo([@ÀÔ»çÀÏÀÚ], NULL)))
                      |--Compute Scalar(DEFINE:([Expr1026]=Convert(LikeRangeStart([@ÀÔ»çÀÏÀÚ], NULL)),
                                                [Expr1027]=Convert(LikeRangeEnd([@ÀÔ»çÀÏÀÚ], NULL)),
                                                [Expr1020]=LikeRangeInfo([@ÀÔ»çÀÏÀÚ], NULL)))
                      |    |--Constant Scan
                      |--Index Seek(OBJECT:([tempdb].[dbo].[»ç¿ø].[idx_ÀÔ»çÀÏÀÚ]),
                            SEEK:([»ç¿ø].[ÀÔ»çÀÏÀÚ] > [Expr1026] AND [»ç¿ø].[ÀÔ»çÀÏÀÚ] < [Expr1027]), 
                            WHERE:(like([»ç¿ø].[ÀÔ»çÀÏÀÚ], [@ÀÔ»çÀÏÀÚ], NULL)) ORDERED FORWARD)

µÎ°¡Áö °æ¿ì´Ù ¿øÇϴ´ë·Î Á¤È®È÷ ½ÇÇà°èȹÀÌ ºÐ¸®µÇ¾î ¾ðÁ¦³ª À妽º¸¦ Àß »ç¿ëÇÑ´Ù.
ÀÌ·±½ÄÀÇ union À» »ç¿ëÇÑ ½ÇÇà°èȹ ºÐ¸®´Â À¯¿ëÇÏ´Ï Àß ÀÍÇôµÎ¼¼¿ä.

3.µ¿ÀûÄõ¸® »ç¿ë
drop proc p2 --Áö¿ì°í ´Ù½Ã¸¸µéÀÚ
go
create proc p2(@À̸§ varchar(10), @ÀÔ»çÀÏÀÚ varchar(8))
as
declare @sql varchar(1000)
set @sql = "select * from »ç¿ø where "
set @sql = @sql +
               case when @À̸§ is not null then " À̸§ like """ + @À̸§ + """"
                    else "
¡Ø Ȥ½Ã µµ¿òÀÌ µÇ¼Ì´Ù¸é ´ñ±Û¿¡ ÇѸ¶µð ³²°ÜÁÖ¼¼¿ä!
ÀÛ¼ºÀÚ   ºñ¹Ð¹øÈ£
ÀÚµ¿±Û ¹æÁö     (ÀÚµ¿±Û ¹æÁö ±â´ÉÀÔ´Ï´Ù.)
³»¿ë   ´ñ±Û´Þ±â 
À̸ÞÀÏ ¹®ÀÇ : cak0280@nate.com  
Copyright 2000 By ENTERSOFT.KR All Rights Reserved.