Ortak Tablo İfadeleri için iç içe geçmiş yan tümceleri oluşturabilir misiniz?


Yanıtlar:


302

Tam olarak iç içe olmasa da, önceki sorguları sonraki sorgularda yeniden kullanmak için ortak tablo ifadelerini kullanabilirsiniz.

Bunu yapmak için, aradığınız ifadenin şekli

WITH x AS 
(
    SELECT * FROM MyTable
), 
y AS 
(
    SELECT * FROM x
)
SELECT * FROM y

2
Çok teşekkür ederim. Oracle bunu yapmak mümkün: İLE J A.Ş. (DUAL biri olarak SELECT 1), Q, Q, (SEC J. *, J 2 OLARAK İKİ) SELECT *
Jason TEPOORTEN

5
bu iç içe değil
symbiont

14
Aslında yazı, bunu yapamayacağınız anlamına gelir, ancak bu büyük bir sorun değildir.
peterh - Monica'yı yeniden başlatın

2
Evet, bu kabul edilebilir bir cevap çünkü yuvalama ile elde etmeye çalıştığım şey, bunun bana yine de verdiği şeyle aynı
Joe Phillips

2
Sorgu 2'nin sorgu 1 parantezinin içinde olmaması nedeniyle bunun iç içe geçmediğini belirtmek zayıf bir argüman gibi geliyor. Sorgu 2 çok yuvalama ile oluşan sorgu 1, sonucunu kullandığından, (özyinelemeli iç içe değil) iç içe düşünüyorum. Yuvalamanın yalnızca bir çocuk ana parantez (veya benzeri) sembolleri içinde olduğunda tanımlanabilir mi?
Christiaan Westerbeek

11

Yinelemeli sorgu olarak adlandırılan aşağıdakileri yapabilirsiniz:

WITH y
AS
(
  SELECT x, y, z
  FROM MyTable
  WHERE [base_condition]

  UNION ALL

  SELECT x, y, z
  FROM MyTable M
  INNER JOIN y ON M.[some_other_condition] = y.[some_other_condition]
)
SELECT *
FROM y

Bu işlevselliğe ihtiyacınız olmayabilir. Sorgularımı daha iyi düzenlemek için aşağıdakileri yaptım:

WITH y 
AS
(
  SELECT * 
  FROM MyTable
  WHERE [base_condition]
),
x
AS
(
  SELECT * 
  FROM y
  WHERE [something_else]
)
SELECT * 
FROM x

7

İle gömülü çalışmıyor, ancak ardışık çalışıyor

;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B

EDIT Sözdizimi düzeltildi ...

Ayrıca, aşağıdaki örneğe bir göz atın

SQLFiddle DEMO


0

Bu cevaplar oldukça iyi, ancak öğeleri düzgün bir şekilde sipariş etmek kadar, bu makaleye bakmaktan daha iyi olurdu http://dataeducation.com/dr-output-or-how-i-learned-to-stop -worrying-ve-sevgi-birleştirme

İşte sorgusunun bir örneği.

WITH paths AS ( 
    SELECT 
        EmployeeID, 
        CONVERT(VARCHAR(900), CONCAT('.', EmployeeID, '.')) AS FullPath 
    FROM EmployeeHierarchyWide 
    WHERE ManagerID IS NULL

    UNION ALL

    SELECT 
        ehw.EmployeeID, 
        CONVERT(VARCHAR(900), CONCAT(p.FullPath, ehw.EmployeeID, '.')) AS FullPath 
    FROM paths AS p 
        JOIN EmployeeHierarchyWide AS ehw ON ehw.ManagerID = p.EmployeeID 
) 
SELECT * FROM paths order by FullPath

Asıl sorum, verileri bir araya getirme hakkında hiçbir şey söylemedi. Verilere kolayca katılıyor olabilir
Joe Phillips

0

Başlangıç ​​ve bitiş arasında birden çok işlem olan bir giriş dışında olaylar arasındaki süreyi ölçmeye çalışıyordum. Buna diğer tek hat süreçleri bağlamında ihtiyaç duydum.

Nth cte içinde select deyim olarak iç birleştirme ile bir select kullandım. İkinci cte, X üzerinde başlangıç ​​tarihini ve Y üzerinde bitiş tarihini almam gerekiyordu ve 1'i tek bir satıra koymak için sol birleşmeye bir kimlik değeri olarak kullandım.

Benim için çalışıyor, umarım bu yardımcı olur.

cte_extract
as 
(
    select ps.Process as ProcessEvent
        , ps.ProcessStartDate 
        , ps.ProcessEndDate 
        -- select strt.*
    from dbo.tbl_some_table ps 
    inner join (select max(ProcessStatusId) ProcessStatusId 
                    from dbo.tbl_some_table 
                where Process = 'some_extract_tbl' 
                and convert(varchar(10), ProcessStartDate, 112) < '29991231'
                ) strt on strt.ProcessStatusId = ps.ProcessStatusID
), 
cte_rls
as 
(
    select 'Sample' as ProcessEvent, 
     x.ProcessStartDate, y.ProcessEndDate  from (
    select 1 as Id, ps.Process as ProcessEvent
        , ps.ProcessStartDate 
        , ps.ProcessEndDate
        -- select strt.*
    from dbo.tbl_some_table ps 
    inner join (select max(ProcessStatusId) ProcessStatusId 
                    from dbo.tbl_some_table 
                where Process = 'XX Prcss' 
                and convert(varchar(10), ProcessStartDate, 112) < '29991231'
                ) strt on strt.ProcessStatusId = ps.ProcessStatusID
    ) x
    left join (
        select 1 as Id, ps.Process as ProcessEvent
            , ps.ProcessStartDate 
            , ps.ProcessEndDate
            -- select strt.*
        from dbo.tbl_some_table ps 
        inner join (select max(ProcessStatusId) ProcessStatusId
                    from dbo.tbl_some_table 
                    where Process = 'YY Prcss Cmpltd' 
                    and convert(varchar(10), ProcessEndDate, 112) < '29991231'
                    ) enddt on enddt.ProcessStatusId = ps.ProcessStatusID
            ) y on y.Id = x.Id 
),

.... diğer sandıklar


0

İç içe 'İle' desteklenmez, ancak her zaman ikinci İle'yi alt sorgu olarak kullanabilirsiniz, örneğin:

WITH A AS (
                --WITH B AS ( SELECT COUNT(1) AS _CT FROM C ) SELECT CASE _CT WHEN 1 THEN 1 ELSE 0 END FROM B --doesn't work
                SELECT CASE WHEN count = 1 THEN 1 ELSE 0 END AS CT FROM (SELECT COUNT(1) AS count FROM dual)
                union all
                select 100 AS CT from dual
           )
              select CT FROM A

-1

iç içe cte oluşturabiliriz. lütfen aşağıdaki cte örneğine bakın

;with cte_data as 
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)

select * from cte_data,cte_data1

4
Partiye biraz geç
Joe Phillips

4
ve bu ardışık
CTE'ler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.