Aracılığıyla paylaş


Doku veri ambarında İç İçe Ortak Tablo İfadesi (CTE) (Transact-SQL)

Şunlar için geçerlidir:Microsoft Fabric'te SQL analiz uç noktası ve Ambarı

Ortak Tablo İfadeleri (CTE'ler), normalde karmaşık sorguları yeniden kullanılabilir bloklar halinde yapılandırarak karmaşık sorguları basitleştirebilir.

standart, sıralı, özyinelemelive CTE iç içe dahil olmak üzere dört tür CTE vardır.

  • Standart bir CTE tanımında başka bir CTE'ye başvurmaz veya tanımlamaz.
  • İç içe yerleştirilmiş bir CTE'nin tanımı başka bir CTE tanımlamayı içerir.
  • Sıralı CTE'nin tanımı mevcut bir CTE'ye başvurabilir ancak başka bir CTE tanımlayamaz.
  • Özyinelemeli bir CTE, tanımında kendisine başvurur.

Microsoft Fabric'te Doku Veri Ambarı ve SQL analiz uç noktası standart, sıralı ve iç içe yerleştirilmiş CTE'leri destekler, ancak özyinelemeli CTE'leri desteklemez.

Yaygın tablo ifadeleri hakkında daha fazla bilgi için bkz. WITH common_table_expression (Transact-SQL).

Sözdizimi

WITH <NESTED_CTE_NAME_LEVEL1> [ (column_name , ...) ] AS
    (WITH <NESTED_CTE_NAME_LEVEL2> [ (column_name , ...) ] AS
        (
            ...
                WITH <NESTED_CTE_NAME_LEVELn-1> [ ( column_name , ...) ] AS
                (
                    WITH <NESTED_CTE_NAME_LEVELn> [ ( column_name , ...) ] AS
                    (
                        Standard_CTE_query_definition
                    )
                    <SELECT statement> -- Data source must include NESTED_CTE_NAME_LEVELn
                )
                <SELECT statement> -- Data source must include NESTED_CTE_NAME_LEVELn-1
            ...
        )
    <SELECT statement> -- Data source must include NESTED_CTE_NAME_LEVEL2
    )

İç içe CTE oluşturma ve kullanma yönergeleri

Standart CTE'leri oluşturma ve kullanma yönergelerine ek olarak, iç içe yerleştirilmiş CTE'ler için ek yönergeler şunlardır:

  • İç içe CTE yalnızca select deyiminde kullanılabilir. UPDATE, INSERT veya DELETE deyimlerinde kullanılamaz.
  • İç içe CTE tanımında UPDATE, INSERT veya DELETE deyimlerine izin verilmez.
  • Aynı iç içe yerleştirme düzeyindeki CTE adları çoğaltılamaz.
  • İç içe yerleştirilmiş bir CTE yalnızca iç içe yerleştirilmiş CTE veya hemen daha yüksek düzeyde olan sıralı CTE'ler tarafından görülebilir.
  • İç içe geçmiş bir CTE tanımında veritabanları arası sorgulara izin verilir.
  • İç içe CTE tanımında sorgu ipuçlarına (option yan tümcesi gibi) izin verilmez.
  • İç içe CTE CREATE VIEW'da kullanılamaz.
  • AS OF iç içe bir CTE tanımında desteklenmez.
  • İç içe yerleştirilmiş CTE'ler bir CTE alt sorgusu tanımında desteklenir, ancak genel bir alt sorguda desteklenmez.
  • En iyi deneyim için iç içe yerleştirme düzeylerini 64 ile sınırlayın.
  • İç içe CTE, Doku Sorgu Düzenleyicisi'nde veya SQL Server Management Studio'da (SSMS) oluşturulabilir. SSMS intellisense iç içe CTE söz dizimlerini tanımaz ancak bu, iç içe CTE oluşturmayı engellemez.

Örnekler

Standart, sıralı ve iç içe yerleştirilmiş CTE'ler arasındaki farklar

-- Standard CTE
;WITH Standard_CTE AS (
    SELECT * FROM T1
)
SELECT * FROM Standard_CTE;

-- Sequential CTE
;WITH CTE1 AS (
    SELECT * FROM T1
),
CTE2 AS (SELECT * FROM CTE1),
CTE3 AS (SELECT * FROM CTE2)
SELECT * FROM CTE3

-- Nested CTE
;WITH OUTER_CTE AS (
    WITH INNER_CTE AS (
        SELECT * FROM T1
    )
    SELECT * FROM INNER_CTE
)
SELECT * FROM OUTER_CTE;

CTE'nin ad kapsamı kapsamıyla sınırlıdır

CTE adları farklı iç içe yerleştirme düzeylerinde yeniden kullanılabilir. Aynı iç içe yerleştirme düzeyindeki CTE adları çoğaltılamaz. Bu örnekte, cte1 adı hem dış hem de iç kapsamda kullanılır.

;WITH
    cte1 AS (
        WITH
            inner_cte1_1 AS (
                SELECT * FROM NestedCTE_t1 WHERE c1 = 1
            ),
            inner_cte1_2 AS (
                SELECT * FROM inner_cte1_1 WHERE c2 = 1
            )
        SELECT * FROM inner_cte1_2
    ),
    cte2 AS (
        WITH
            cte1 AS (
                SELECT * FROM NestedCTE_t1 WHERE c3 = 1
            ),
            inner_cte2_2 AS (
                SELECT * FROM cte1 WHERE c4 = 1
            )
        SELECT * FROM inner_cte2_2
    )

Birleşim, birleşim tümü, kesişen ve dışındaki karmaşık iç içe geçmiş CTE

CREATE TABLE NestedCTE_t1 (
    c1 INT,
    c2 INT,
    c3 INT
);
GO

INSERT INTO NestedCTE_t1
VALUES (1, 1, 1);

INSERT INTO NestedCTE_t1
VALUES (2, 2, 2);

INSERT INTO NestedCTE_t1
VALUES (3, 3, 3);
GO

WITH
    outermost_cte_1 AS (
        WITH
            outer_cte_1 AS (
                WITH
                    inner_cte1_1 AS (
                        SELECT * FROM NestedCTE_t1 WHERE c1 = 1
                    ),
                    inner_cte1_2 AS (
                        SELECT * FROM inner_cte1_1
                        UNION SELECT * FROM inner_cte1_1
                    )
                SELECT * FROM inner_cte1_1
                UNION ALL SELECT * FROM inner_cte1_2
            ),
            outer_cte_2 AS (
                WITH
                    inner_cte2_1 AS (
                        SELECT * FROM NestedCTE_t1 WHERE c2 = 1
                        EXCEPT SELECT * FROM outer_cte_1
                    ),
                    inner_cte2_2 AS (
                        SELECT * FROM NestedCTE_t1 WHERE c3 = 1
                        UNION SELECT * FROM inner_cte2_1
                    )
                SELECT * FROM inner_cte2_1
                UNION ALL SELECT * FROM outer_cte_1
            )
        SELECT * FROM outer_cte_1
        INTERSECT SELECT * FROM outer_cte_2
    ),
    outermost_cte_2 AS (
        SELECT * FROM outermost_cte_1
        UNION SELECT * FROM outermost_cte_1
    )
SELECT * FROM outermost_cte_1
UNION ALL SELECT * FROM outermost_cte_2;

İç içe CTE, CTE alt sorgu tanımında desteklenir ancak genel alt sorguda desteklenmez

Bu sorgu şu hatayla başarısız oluyor: Msg 156, Level 15, State 1, Line 3. Incorrect syntax near the keyword 'WITH'.

SELECT * FROM
(
    WITH
        inner_cte1_1 AS (SELECT * FROM NestedCTE_t1 WHERE c1 = 1),
        inner_cte1_2 AS  (SELECT * FROM inner_cte1_1)
    SELECT * FROM inner_cte1_2
) AS subq1;

CTE başvuruları kapsamını aşamaz

Bu sorgu şu hatayla başarısız oluyor: Msg 208, Level 16, State 1, Line 1. Invalid object name 'inner_cte1_1'.

;WITH
    outer_cte_1 AS (
        WITH
            inner_cte1_1 AS (
                SELECT * FROM NestedCTE_t1 WHERE c1 = 1
            ),
            inner_cte1_2 AS (
                SELECT * FROM inner_cte1_1 WHERE c2 = 1
            )
        SELECT * FROM inner_cte1_2
    ),
    outer_cte_2 AS (
        WITH inner_cte2_1 AS (
            SELECT * FROM NestedCTE_t1 WHERE c3 = 1
        )
        SELECT
            tmp2.*
        FROM
            inner_cte1_1 AS tmp1,
            inner_cte2_1 AS tmp2
        WHERE
            tmp1.c4 = tmp2.c4
    )
SELECT * FROM outer_cte_2;