Pouvez-vous créer des clauses WITH imbriquées pour les expressions de table communes?
-
06-07-2019 - |
Question
WITH y AS (
WITH x AS (
SELECT * FROM MyTable
)
SELECT * FROM x
)
SELECT * FROM y
Est-ce que quelque chose comme ça marche? Je l'ai essayé plus tôt, mais je n'ai pas réussi à le faire fonctionner.
La solution
Bien que cela ne soit pas strictement imbriqué, vous pouvez utiliser des expressions de table communes pour réutiliser les requêtes précédentes dans les requêtes suivantes.
Pour ce faire, la forme de la déclaration que vous recherchez serait
WITH x AS
(
SELECT * FROM MyTable
),
y AS
(
SELECT * FROM x
)
SELECT * FROM y
Autres conseils
Vous pouvez effectuer les opérations suivantes, appelées requêtes récursives:
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
Vous n’avez peut-être pas besoin de cette fonctionnalité. J'ai organisé les opérations suivantes pour mieux organiser mes requêtes:
WITH y
AS
(
SELECT *
FROM MyTable
WHERE [base_condition]
),
x
AS
(
SELECT *
FROM y
WHERE [something_else]
)
SELECT *
FROM x
Avec ne fonctionne pas, mais il fonctionne consécutivement
;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B
MODIFIER Correction de la syntaxe ...
Regardez également l'exemple suivant
DÉMO SQLFiddle
Ces réponses sont plutôt bonnes, mais en ce qui concerne la commande des articles, vous feriez mieux de regarder cet article. http: // dataeducation.com/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge
Voici un exemple de sa requête.
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
nous pouvons créer un cte imbriqué. Veuillez voir le cte ci-dessous dans l'exemple
;with cte_data as
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)
select * from cte_data,cte_data1
J'essayais de mesurer le temps entre les événements à l'exception d'une entrée comportant plusieurs processus entre le début et la fin. J'avais besoin de cela dans le contexte d'autres processus monolignes.
J'ai utilisé une sélection avec une jointure interne comme instruction de sélection au sein du Nième chapitre. Le deuxième cte j'avais besoin d'extraire la date de début sur X et la date de fin sur Y et utilisais 1 comme valeur id à joindre à gauche pour les placer sur une seule ligne.
Cela fonctionne pour moi, espérons que cela aide.
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
),
.... autres ctes