具有通用表表达式的SQL Server查询

时间:2019-02-07 07:36:32

标签: sql-server

我有一个名为Dim_Zone的表,具有以下架构:

(Zone_ID int, Zone_RecursID int, Zone_Label varchar(50), zone level int, zone_active bit)

ZoneRecurs_IDZone_ID的父ID

Zone level 0 stands for World
Zone level 1 stands for Continent_ID
Zone level 2 stands for Country_ID
Zone level 3 stands for Superregion_ID
Zone level 4 stands for region_ID
Zone level 5 stands for departement_ID

我需要一个查询,该查询为我提供以下列:

departement_ID, region_ID,  Superregion_ID, Country_ID  ,continent_id,  departement_label,  region_label,   Superregion_label,  Country_label,  continent_label ,dimItem_level

所以我需要一个像这样的最终结果:

departement_ID  region_ID   Superregion_ID  Country_ID  continent_id    departement_label   region_label    Superregion_label           Country_label       continent_label     dimItem_level
NULL            NULL        NULL            NULL        404             NULL                NULL            NULL                        NULL                Europe              1
NULL            NULL        NULL            158         406             NULL                NULL            NULL                        Itali               Europe              2
NULL            NULL        12              1           406             NULL                NULL            Centre                      France              Europe              3
NULL            139         137             1           406             NULL                Mayotte         Collectivités d'Outre Mer   France              Europe              4
20              18          12              1           406             Oise                Picardie        Bassin Parisien             France              Europe              5

我尝试了以下代码:

WITH departements
     AS (SELECT DZ.zone_id,
                zone_recursid,
                zone_label,
                zone_level,
                zone_active
         FROM   dim_zone DZ
         WHERE  zone_level = 5
                AND zone_active = 1),
     regions
     AS (SELECT DZ.zone_id,
                zone_recursid,
                zone_label,
                zone_level,
                zone_active
         FROM   dim_zone DZ
         WHERE  zone_level = 4
                AND zone_active = 1),
     superregions
     AS (SELECT DZ.zone_id,
                zone_recursid,
                zone_label,
                zone_level,
                zone_active
         FROM   dim_zone DZ
         WHERE  zone_level = 3
                AND zone_active = 1),
     country
     AS (SELECT DZ.zone_id,
                zone_recursid,
                zone_label,
                zone_level,
                zone_active
         FROM   dim_zone DZ
         WHERE  zone_level = 2
                AND zone_active = 1),
     continents
     AS (SELECT DZ.zone_id,
                zone_recursid,
                zone_label,
                zone_level,
                zone_active
         FROM   dim_zone DZ
         WHERE  zone_level = 1
                AND zone_active = 1) SELECT NULL       AS departement_ID,
       NULL       AS region_ID,
       NULL       AS SuperRegion_ID,
       NULL       AS Country_ID,
       zone_id    AS continent_id,
       NULL       AS departement_label,
       NULL       AS region_label,
       NULL       AS SuperRegion_label,
       NULL       AS Country_label,
       zone_label AS continent_label,
       1          AS dimItem_level
FROM   continents
UNION
SELECT D.zone_id     AS departement_ID,
       R.zone_id     AS region_ID,
       SR.zone_id    AS SuperRegion_ID,
       P.zone_id     AS Country_ID,
       C.zone_id     AS continent_id,
       D.zone_label  AS departement_label,
       R.zone_label  AS region_label,
       SR.zone_label AS SuperRegion_label,
       P.zone_label  AS Country_label,
       C.zone_label  AS continent_label,
       CASE
         WHEN D.zone_id IS NOT NULL THEN 5
         WHEN R.zone_id IS NOT NULL THEN 4
         WHEN SR.zone_id IS NOT NULL THEN 3
         WHEN P.zone_id IS NOT NULL THEN 2
         WHEN C.zone_id IS NOT NULL THEN 1
         ELSE 0
       END           AS dimitem_level
FROM   continents C
       LEFT JOIN country P
              ON C.zone_id = P.zone_recursid
       LEFT JOIN superregions SR
              ON P.zone_id = SR.zone_recursid
       LEFT JOIN regions R
              ON SR.zone_id = R.zone_recursid
       LEFT JOIN departements D
              ON R.zone_id = D.zone_recursid 

有人知道为什么吗或建议任何其他方式吗?

1 个答案:

答案 0 :(得分:1)

我认为问题在于FROM子句。您正在从各大洲开始,并针对较低级别进行LEFT JOIN。这样只会显示1级,而不会显示全部6级。

您希望看到6个不同的结果集,因此您需要6个SELECT和5个UNION ALL,每个级别都有一次(departmentsregions,{{ 1}},superRegionscountriescontinents)。

我强烈建议为每个CTE创建不同的视图,这将使编写更具可读性。

我将以最复杂的2为例,您可以添加其余部分:

world