Чи можете ви створити вкладені фрази WITH для загальних виразів таблиці?


Відповіді:


302

Хоча це не строго вкладено, ви можете використовувати загальні вирази таблиці для повторного використання попередніх запитів у наступних.

Для цього була б форма заяви, яку ви шукаєте

WITH x AS 
(
    SELECT * FROM MyTable
), 
y AS 
(
    SELECT * FROM x
)
SELECT * FROM y

2
Велике спасибі. Мені вдалося це зробити в Oracle: З J AS (ВИБІР 1 ЯК З ДВОЙНОГО), Q AS (ВИБІР Дж. *, 2 КАК ДВОЙ З J) ВИБІР * ВІД Q
Jason TEPOORTEN

5
це не вкладено
симбіонт

14
По суті, повідомлення означає, що ви не можете цього зробити , але це не є великою проблемою.
петерх

2
Так, це прийнятна відповідь, тому що те, що я намагався досягти за допомогою гніздування, - це те саме, що все одно мені дають
Джо Філіпс

2
Повідомлення, що це не вкладено, лише тому, що запит 2 не знаходиться в дужках запиту 1, звучить як слабкий аргумент. Я думаю, що це вкладене (не рекурсивно вкладене), тому що запит 2 використовує результат запиту 1, який виникає і при вкладенні. Чи визначено, що гніздування може бути лише тоді, коли дитина знаходиться у своїх батьківських (або подібних) символах?
Крістіан Вестербек

11

Ви можете зробити наступне, що називається рекурсивним запитом:

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

7

З не працює вбудований, але він працює послідовно

;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B

EDIT Виправлено синтаксис ...

Також подивіться наступний приклад

SQLFiddle DEMO


0

Ці відповіді досить хороші, але що стосується правильного замовлення товарів, вам краще переглянути цю статтю http://dataeducation.com/dr-output-or-how-i-learned-to-stop -боріти-і-любити-зливати

Ось приклад його запиту.

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

Моє первісне запитання ніколи нічого не говорило про об'єднання даних разом. Це може бути так само легко приєднатися до даних
Джо Філіпс

0

Я намагався виміряти час між подіями за винятком того, який один запис, який має кілька процесів між початком і кінцем. Мені це було потрібно в контексті інших процесів, що стосуються однієї лінії.

Я використовував select із внутрішнім приєднанням як мій оператор select у межах Nth cte. Другий cte мені знадобився витягнути дату початку на X та кінцеву дату на Y і використав 1 як значення id для лівого об'єднання, щоб поставити їх в один рядок.

Для мене працює, сподіваюся, це допомагає.

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


0

Вкладений "З" не підтримується, але ви завжди можете використовувати другий З як підзапит, наприклад:

WITH A AS (
                --WITH B AS ( SELECT COUNT(1) AS _CT FROM C ) SELECT CASE _CT WHEN 1 THEN 1 ELSE 0 END FROM B --doesn't work
                SELECT CASE WHEN count = 1 THEN 1 ELSE 0 END AS CT FROM (SELECT COUNT(1) AS count FROM dual)
                union all
                select 100 AS CT from dual
           )
              select CT FROM A

-1

ми можемо створити вкладений cte.please, див. нижче приклад

;with cte_data as 
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)

select * from cte_data,cte_data1

4
Ви трохи запізнюєтесь на вечірку;)
Джо Філіпс

4
і це поспіль CTE, не вкладені CTE
Meower68
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.