Bagikan melalui


Ekspresi Tabel Umum Berlapis (CTE) dalam pergudangan data Fabric (Transact-SQL)

Berlaku untuk:Titik akhir analitik SQL dan Gudang di Microsoft Fabric

Ekspresi Tabel Umum (CTE) dapat menyederhanakan kueri kompleks dengan mendekonstruksi kueri yang biasanya kompleks menjadi blok yang dapat digunakan kembali.

Ada empat jenis CTE, termasuk CTE standar, berurutan, rekursif, dan berlapis .

  • CTE standar tidak mereferensikan atau menentukan CTE lain dalam definisinya.
  • Definisi CTE berlapis termasuk menentukan CTE lain.
  • Definisi CTE berurutan dapat mereferensikan CTE yang ada tetapi tidak dapat menentukan CTE lain.
  • CTE rekursif mereferensikan dirinya sendiri dalam definisinya.

Di Microsoft Fabric, Fabric Data Warehouse dan titik akhir analitik SQL mendukung CTE standar, berurutan, dan berlapis , tetapi bukan CTA rekursif.

Untuk informasi selengkapnya tentang ekspresi tabel umum, lihat WITH common_table_expression (Transact-SQL).

Sintaks

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
    )

Panduan untuk membuat dan menggunakan CTE berlapis

Selain panduan untuk membuat dan menggunakan CTE standar, berikut adalah panduan tambahan untuk CTE berlapis:

  • CTE berlapis hanya dapat digunakan dalam pernyataan SELECT. Ini tidak dapat digunakan dalam pernyataan UPDATE, INSERT, atau DELETE.
  • Tidak ada pernyataan UPDATE, INSERT, atau DELETE yang diizinkan dalam definisi CTE berlapis.
  • Nama CTE pada tingkat berlapis yang sama tidak dapat diduplikasi.
  • CTE berlapis hanya terlihat oleh CTE berlapis atau CTE berurutan yang berada di tingkat yang lebih tinggi.
  • Kueri lintas database diizinkan dalam definisi CTE berlapis.
  • Petunjuk kueri (yaitu klausa OPTION) tidak diperbolehkan dalam definisi CTE berlapis.
  • CTE berlapis tidak dapat digunakan dalam CREATE VIEW.
  • AS OF tidak didukung dalam definisi CTE berlapis.
  • CTE berlapis didukung dalam definisi subkueri CTE, tetapi tidak dalam subkueri umum.
  • Untuk pengalaman terbaik, batasi tingkat berlapis hingga 64.
  • CTE berlapis dapat dibuat di Fabric Query Editor atau SQL Server Management Studio (SSMS). Intellisense SSMS tidak mengenali sintaks CTE berlapis tetapi ini tidak memblokir pembuatan CTE berlapis.

Contoh

Perbedaan antara CTEs standar, berurutan, dan berlapis

-- 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;

Cakupan nama CTE dibatasi untuk cakupannya

Nama CTE dapat digunakan kembali pada tingkat berlapis yang berbeda. Nama CTE pada tingkat berlapis yang sama tidak dapat diduplikasi. Dalam contoh ini, nama cte1 digunakan dalam cakupan luar dan dalam.

;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
    )

CTE berlapis kompleks dengan gabungan, gabungan semua, berpotangan, dan kecuali

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;

CTE berlapis didukung dalam definisi subkueri CTE tetapi tidak dalam subkueri umum

Kueri ini gagal dengan kesalahan berikut: 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;

Referensi ke CTE tidak boleh melebihi cakupannya

Kueri ini gagal dengan kesalahan berikut: 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;