Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zrozumienie rekurencyjnego sprawdzania zakończenia CTE

Oto lepszy przykład z użyciem dat. Załóżmy, że chcemy zbudować tabelę dat. 1 wiersz na każdy miesiąc w roku 2017. Tworzymy @startDate jako kotwica i @endDate jako terminator. Ustawiliśmy je na 12 miesięcy, ponieważ chcemy jednego roku. Następnie rekursja doda jeden miesiąc za pomocą DATEADD funkcji do @startDate dopóki terminator nie zostanie spełniony w WHERE klauzula. Wiemy, że potrzeba 11 rekurencji, aby osiągnąć 12 miesięcy... czyli 11 miesięcy + data rozpoczęcia. Jeśli ustawimy MAXRECURSION do wartości mniejszej niż 11, to się nie powiedzie, ponieważ 11 jest potrzebnych do wypełnienia WHERE klauzula w naszym rekurencyjnym CTE , czyli terminator..

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

W przypadku zapytania wystarczy proste sprzężenie.

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

Widzę jednak, że próbujesz zwrócić to w dziwnym formacie, który powinien być obsługiwany w dowolnej aplikacji do raportowania, której używasz. Dzięki temu będziesz blisko bez rekurencji.

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. Jak wygenerować losowe dane na serwerze SQL

  2. Właściwość zależna w ReferentialConstraint jest mapowana do kolumny generowanej przez sklep

  3. Jaka jest różnica między CHAR i VARCHAR w SQL Server - SQL Server / T-SQL Tutorial, część 31

  4. Emisja wielu powiadomień SQL w aplikacji webowej ASP.Net podczas odświeżania strony

  5. Jak włączyć wyjście RPC za pomocą T-SQL