MS-SQL > °øÅë Å×ÀÌºí ½Ä(Common Table Expressions) °ú Àç±Í Äõ¸® µî·ÏÀÏ : 2017-06-30 17:12 Á¶È¸¼ö : 52,594°øÅë Å×ÀÌºí ½Ä(CTE) Àº ´Ü¼ø Äõ¸®·ÎºÎÅÍ ÆÄ»ýµÈ Àӽà °á°ú ÁýÇÕÀÔ´Ï´Ù.
CTE ´Â ÆÄ»ýµÈ Å×À̺íÀ» »ç¿ëÇÏ´Â °Íó·³, µ¿ÀÏÇÑ ¼ö´ÜÀ¸·Î »ç¿ë µÇ¾îÁú ¼ö ÀÖ½À´Ï´Ù. CTE´Â ¶ÇÇÑ Àڽſ¡ ´ëÇÑ ÂüÁ¶¸¦ Æ÷ÇÔÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ´Â µ¥ÀÌÅͺ£À̽º °³¹ßÀÚ°¡ Àç±Í Äõ¸®¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖµµ·Ï ÇØÁÝ´Ï´Ù. CTE ´Â ¶ÇÇÑ ºä ´ë½Å »ç¿ë µÇ¾îÁú ¼öµµ ÀÖ½À´Ï´Ù. °³³äÀûÀ¸·Î´Â ÀÓ½ÃÅ×À̺í°ú ºñ½ÁÇÕ´Ï´Ù. ´õ ÀûÀº ÄÚµå·Î ÀÓ½ÃÅ×À̺í, Àç±ÍÈ£ÃâµîÀ» ó¸®ÇÒ ¼ö ÀÖ½À´Ï´Ù. ±âÁ¸ SQL 2000 ¿¡¼ »ç¿ë ÇÏ´ø ¹æ½Ä select SalesPersonID, count(*) as NumSales into #tmp from Sales.SalesOrderHeader Group by SalesPersonID select ts.SalesPersonID, sp.SalesYTD, ts.NumSales from Sales.SalesPerson sp inner join #tmp ts on ts.SalesPersonID = sp.SalesPersonID order by NumSales Desc SQL 2005ÀÇ CTE ¸¦ ÀÌ¿ëÇÑ ¹æ½Ä with TopSales (SalesPersonID, NumSales) as ( Select SalesPersonID, Count(*) From Sales.SalesOrderHeader Group BY SalesPersonID) select ts.SalesPersonID, sp.SalesYTD, ts.NumSales from Sales.SalesPerson sp inner join TopSales ts on ts.SalesPersonID = sp.SalesPersonID order by NumSales Desc 1.ÆÄ»ýµÈ Å×À̺í·Î »ç¿ëµÈ CTE ÇÊÅ͸µ Çϱ⠺ä·Î ¸®ÅÏµÈ °á°úÁýÇÕÀ» ÇÊÅ͸µÇÏ´Â °Í°ú ¸¶Âù°¡Áö·Î, ¿©·¯ºÐÀº °øÅë Å×ÀÌºí ½Ä(CTE) ¾È¿¡ Æ÷ÇÔµÈ °á°ú ÁýÇÕÀ» ÇÊÅ͸µ ÇÒ ¼ö ÀÖ½À´Ï´Ù. WITH SalesCTE(ProductID , SalesOrderID) AS ( SELECT ProductID , COUNT(SalesOrderID) FROM Sales.SalesOrderDetail GROUP BY ProductID ) SELECT * FROM SalesCTE WHERE SalesOrderID > 50 --50ȸÀÌ»óÁÖ¹®µÈ¸ðµçÁ¦Ç°µé 2.CTE ·Î Áý°èÇϱ⠰øÅë Å×ÀÌºí ½Ä(CTE) À¸·Î ¸®ÅÏµÈ µ¥ÀÌÅ͸¦ °¡Áö°í Áý°è ¶Ç´Â ±× ¹ÛÀÇ ´Ù¸¥ °è»êÀ» ¼öÇàÇÏ´Â °ÍÀº ±âº» Å×À̺í·ÎºÎÅÍ ¸®ÅÏµÈ µ¥ÀÌÅ͸¦ °¡Áö°í Áý°è ¹× ±âŸ °è»êÀ» ¼öÇàÇÏ´Â °Í°ú À¯»çÇÕ´Ï´Ù. WITH SalesCTE(ProductID , SalesOrderID) AS ( SELECT ProductID , COUNT(SalesOrderID) FROM Sales.SalesOrderDetail GROUP BY ProductID ) SELECT AVG(SalesOrderID) FROM SalesCTE WHERE SalesOrderID > 50 -- 50 ȸÀÌ»óÁÖ¹®µÈ¸ðµçÁ¦Ç°µéÀÇÆò±ÕÁÖ¹®È½¼ö 3. °øÅë Å×ÀÌºí ½Ä(CTE)À» »ç¿ëÇÏ´Â Àç±Í Äõ¸® °øÅë Å×ÀÌºí ½Ä(CTE)ÀÇ ÁøÁ¤ÇÑ À§·ÂÀº Àç±Í Äõ¸®¸¦ ÀÛ¼ºÇÏ´Â µ¥¿¡ ÀÖ½À´Ï´Ù. °øÅë Å×ÀÌºí ½Ä(CTE) ÀÌ ÀÚ±â Àڽſ¡ ´ëÇÑ ÂüÁ¶°¡ °¡´ÉÇϱ⠶§¹®¿¡, Àç±Í Äõ¸®ÀÇ ÀÛ¼ºÀ» ºñ±³Àû °£´ÜÈ÷, ¼ö¿ùÇÏ°Ô ÇÒ ¼ö ÀÖ½À´Ï´Ù. CREATE TABLE CarParts ( CarID int NOT NULL , Part varchar(15) , SubPart varchar(15) , Qty int ) GO INSERT CarParts VALUES(1 , 'Body' , 'Door' , 4) INSERT CarParts VALUES(1 , 'Body' , 'Trunk Lid' , 1) INSERT CarParts VALUES(1 , 'Body' , 'Car Hood' , 1) INSERT CarParts VALUES(1 , 'Door' , 'Handle' , 1) INSERT CarParts VALUES(1 , 'Door' , 'Lock' , 1) INSERT CarParts VALUES(1 , 'Door' , 'Window' , 1) INSERT CarParts VALUES(1 , 'Body' , 'Rivets' , 1000) INSERT CarParts VALUES(1 , 'Door' , 'Rivets' , 100) INSERT CarParts VALUES(1 , 'Door' , 'Mirror' , 1) ÀÚµ¿Â÷ÀÇ ºÎÇ° ¹× ÇÏÀ§ ºÎÇ°¿¡ ´ëÇÑ Á¤º¸¸¦ °¡Áö°í ÀÖ´Â Å×À̺íÀ» ¸¸µé±â À§ÇÑ Äõ¸® ÀÔ´Ï´Ù. º¸Åë ÀÌ·¯ÇÑ Á¤º¸¸¦ ´ã°í ÀÖ´Â Å×À̺íÀ» Àç·áÇ¥(bill of materials)¶ó°í ºÎ¸¨´Ï´Ù. Àç±ÍÀû CTE ´Â Àç·áÇ¥ , Á¶Á÷µµ ¹× ±âŸ °èÃþÀûÀÎ ±¸Á¶¸¦ °®´Â µ¥ÀÌÅ͸¦ ¹ÝȯÇÏ´Â ÀÛ¾÷À» ½±°Ô ÇÒ ¼ö ÀÖµµ·Ï ÇÕ´Ï´Ù. Áö±Ý »ý¼ºÇÏ´Â Å×À̺í Á¤º¸¿¡¼ Body ¿Í °°Àº ºÎÇ°ÀÌ ¿©·¯ ÇÏÀ§ ºÎÇ°µéÀ» °¡Áö°í ÀÖ´Ù´Â »ç½ÇÀ» ÁÖ¸ñÇϽʽÿÀ.. ¿¹¸¦ µé¾î, Body ºÎÇ°Àº 1000 °³ÀÇ ¸ø(rivet) À» ÇÏÀ§ ºÎÇ°À¸·Î °¡Áö°í ÀÖ°í, Body ÀÇ ÇÏÀ§ ºÎÇ°ÀÎ Door ¶ÇÇÑ ÀÚ½Å(Door) ÀÇ ÇÏÀ§ ºÎÇ°À¸·Î 100°³ÀÇ ¸ø(rivet)À» °¡Áö°í ÀÖ½À´Ï´Ù. WITH CarPartsCTE(SubPart , Qty) AS ( -- ¾ÞÄ¿¸â¹ö(Anchor Member): -- CarPartsCTE ÀÚ½ÅÀ»ÂüÁ¶ÇÏÁö¾Ê´ÂSELECT Äõ¸® SELECT SubPart , Qty FROM CarParts WHERE Part = 'Body' UNION ALL -- Àç±Í¸â¹ö(Recursive Member): -- CTE(CarPartsCTE) ÀÚ±âÀÚ½ÅÀ»ÂüÁ¶ÇÏ´ÂSELECT Äõ¸® SELECT CarParts.SubPart , CarPartsCTE.Qty * CarParts.Qty FROM CarPartsCTE INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part WHERE CarParts.CarID = 1 ) -- Ãâ·ÂÄõ¸® SELECT SubPart , SUM(Qty) as q FROM CarPartsCTE GROUP BY SubPart Àç±ÍÀû CTE ´Â ÃÖ¼ÒÇÑ 2°³ ÀÌ»óÀÇ Äõ¸®µé·Î ±¸¼º µÇ¾îÁý´Ï´Ù. ù¹ø° ¿ä¼Ò·Î ±¸¼ºµÈ Äõ¸®´Â CTE ÀÚü¸¦ ÂüÁ¶ÇÏÁö ¾Ê´Â Äõ¸®ÀÔ´Ï´Ù. ÀÌ·¯ÇÑ Äõ¸® Á¤ÀÇ´Â CTE ±¸Á¶ÀÇ ±âº» °á°ú ÁýÇÕÀ» Çü¼ºÇϱ⠶§¹®¿¡ ¾ÞÄ¿ ¸â¹ö(anchor member)¶ó°í ÇÕ´Ï´Ù. µÎ ¹ø° ±¸¼º¿ä¼Ò´Â Àç±Í ¸â¹ö(recursive member) ¶ó°í ºÒ¸®¿öÁö´Â Àç±Í Äõ¸®ÀÔ´Ï´Ù. ÀÌ·¯ÇÑ Äõ¸®µéÀº UNION ALL ¿¬»êÀÚ¿¡ ÀÇÇØ ±¸º°µÇ¾î Áý´Ï´Ù. ÀÚµ¿Â÷ÀÇ º»Ã¼(Body) ¸¦ ¸¸µé±â À§ÇØ ÇÊ¿äÇÑ ºÎÇ°µéÀÇ ÃÑ ¼ö·®¿¡ ´ëÇÑ ¸®½ºÆ®¸¦ ¾ò¾î¿À´Â Äõ¸® ÀÔ´Ï´Ù. °øÅë Å×ÀÌºí ½Ä(CTE)Àº ¸Ç óÀ½ °£´ÜÇÑ Äõ¸®(“SELECT SubPart, Qty FROM CarParts WHERE Part = 'Body'”.)·ÎºÎÅÍ ±âº» °á°ú ÁýÇÕÀ» ¸¸µì´Ï´Ù. ±× ´ÙÀ½, ÀÌ ºÎÇ°µéÀÇ ÇÏÀ§ ºÎÇ°µé°ú ÀÌ ÇÏÀ§ ºÎÇ°ÀÇ °³¼ö(ÇÊ¿äÇÑ »óÀ§ ºÎÇ°ÀÇ °³¼ö * »óÀ§ ºÎÇ° ´ÜÀ§´ç ÇÊ¿äÇÑ ÇÏÀ§ ºÎÇ° °³¼ö) ¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò¾î¿À´Â Äõ¸®¹®À» UNION ALL ¿¬»êÀÚ·Î °áÇÕÇÕ´Ï´Ù. µÎ ¹ø° Äõ¸®¹®ÀÇ INNER JOIN ¹®Àå ¾È¿¡ CarPartsCTE ¶ó´Â À̸§À» °¡Áø °øÅë Å×ÀÌºí ½Ä(CTE) ÀÚü¿¡ ´ëÇÑ ÂüÁ¶ (Àç±Í ÂüÁ¶) ¸¦ Æ÷ÇÔÇÏ´Â °ÍÀÔ´Ï´Ù. Àç±Í Äõ¸®¸¦ ÀÌ¿ëÇÑ 1~ 10±îÁö Äõ¸® WITH TEST AS( SELECT IDX = 1 UNION ALL SELECT IDX = IDX + 1 FROM TEST WHERE IDX < 10 )SELECT * FROM TEST 4. ÇÁ·Î½ÃÁ®¿Í CTE¸¦ ÀÌ¿ëÇÑ Æ®¸®±¸Á¶ ¸¸µå´Â ¿¹Á¦... CREATE PROCEDURE TREE_CALL (@url1 varchar(100)) as BEGIN ; with cte (board_idx,m_name, m_step, m_sex, m_homepage,url_name,m_writeday, m_level , path1) as ( select board_idx,m_name, m_step, left(m_jumin2,1) as m_sex, m_homepage,url_name, m_writeday, 1 as m_level, convert(varchar(1000), ' > ' + m_homepage) path1 from demo005_member where (m_homepage is not null) and (m_homepage<>'') and (m_homepage=@url1) union all select A.board_idx, A.m_name, A.m_step, left(A.m_jumin2,1) as m_sex, A.m_homepage, A.url_name , A.m_writeday, m_level+1 , convert(varchar(1000), path1 + ' > ' + A.m_homepage) from demo005_member A, cte B where a.url_name = b.m_homepage and (A.m_homepage is not null) and (A.m_homepage<>'') ) select board_idx, m_name, m_step, m_sex, m_homepage, url_name , m_writeday, m_level , path1 from cte order by path1 asc end
|