Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Разбиране на рекурсивната проверка за прекратяване на CTE

Ето по-добър пример за използване на дати. Да приемем, че искаме да съставим таблица с дати. 1 ред за всеки месец за 2017 г. Създаваме @startDate като котва и @endDate като терминатор. Задаваме ги на 12 месеца, тъй като искаме една година. След това рекурсията ще добави един месец чрез DATEADD функция към @startDate докато не се срещне терминаторът в WHERE клауза. Знаем, че ще са необходими 11 рекурсии, за да достигнем 12 месеца... тоест 11 месеца + началната дата. Ако зададем MAXRECURSION до нещо по-малко от 11, тогава ще се провали, тъй като 11 са необходими за изпълнение на WHERE клауза в нашия рекурсивен CTE , това е терминаторът...

declare @startDate datetime = '20170101'
declare @endDate datetime = '20171201'

;WITH Months
as
(
    SELECT @startDate as TheDate       --anchor
    UNION ALL
    SELECT DATEADD(month, 1, TheDate)  --recursive
    FROM Months
    WHERE TheDate < @endDate           --terminator... i.e. continue until this condition is met

)


SELECT * FROM Months OPTION (MAXRECURSION 10) --change this to 11

За вашето запитване би било достатъчно просто присъединяване.

select 
  firstName
  ,lastName
  ,orderDate
  ,productID
from
  customers c
inner join
  orders o on o.customerID = c.id

Виждам обаче, че се опитвате да върнете това в странен формат, който трябва да се обработва в каквото и приложение за отчитане, което използвате. Това ще ви доведе до затваряне без рекурсия.

with cte as(
select 
  firstName
  ,lastName
  ,orderDate
  ,productID
  ,dense_rank() over(order by c.id) as RN
from
  customers c
inner join
  orders o on o.customerID = c.id)


select distinct
  firstName
  ,lastName
  ,null
  ,null
  ,RN
from 
  cte
union all
select
  ''
  ,''
  ,orderDate
  ,productID
  ,RN
from 
  cte
order by RN, firstName desc



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Извличане на идентификатора на вмъкнат запис:Php &MS SQL SERVER

  2. SQL Server convert изберете колона и я преобразувайте в низ

  3. Само един израз може да бъде посочен в списъка за избор, когато подзаявката не е въведена с EXISTS

  4. Внедряване на отказ в MS SQL Server 2017 Standard

  5. Скрити подобрения в производителността и управляемостта в SQL Server 2012 / 2014