Можете ли вы создать вложенные предложения WITH для общих табличных выражений?
-
06-07-2019 - |
Вопрос
WITH y AS (
WITH x AS (
SELECT * FROM MyTable
)
SELECT * FROM x
)
SELECT * FROM y
Работает ли что-то подобное?Я пробовал это раньше, но у меня не получилось заставить это работать.
Решение
Хотя они не являются строго вложенными, вы можете использовать общие табличные выражения для повторного использования предыдущих запросов в последующих. Р>
Для этого форма искомого выписки должна быть
WITH x AS
(
SELECT * FROM MyTable
),
y AS
(
SELECT * FROM x
)
SELECT * FROM y
Другие советы
Вы можете сделать следующее, что называется рекурсивным запросом:
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
Вам может не понадобиться эта функция. Я сделал следующее, чтобы лучше организовать свои запросы:
WITH y
AS
(
SELECT *
FROM MyTable
WHERE [base_condition]
),
x
AS
(
SELECT *
FROM y
WHERE [something_else]
)
SELECT *
FROM x
With не работает встроенным, но он работает последовательно
;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B
Редактировать Исправлен синтаксис...
Кроме того, взгляните на следующий пример
ДЕМОНСТРАЦИЯ SQLFiddle
Эти ответы довольно хороши, но если вам нужно правильно оформить заказ, вам лучше взглянуть на эту статью. http: // dataeducation.com/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge р>
Вот пример его запроса.
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
мы можем создать вложенный cte.пожалуйста, смотрите ниже cte в примере
;with cte_data as
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)
select * from cte_data,cte_data1
Я пытался измерить время между событиями, за исключением одной записи, в которой есть несколько процессов между началом и концом. Мне это нужно в контексте других однострочных процессов.
Я использовал выбор с внутренним объединением в качестве оператора выбора в N-м городе. Во втором cte мне нужно было извлечь начальную дату по X и конечную дату по Y и использовать 1 в качестве значения идентификатора для левого соединения, чтобы поместить их в одну строку. Р>
У меня работает, надеюсь, это поможет. Р>
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
),
.... другие ctes