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

SQL рекурсивен CTE:Намиране на обекти, свързани по свойство

Сблъсквате се с безкраен цикъл, причинен от цикли във вашите данни, например:1> 2> 3> 2> ... . Решението е да следите редовете, които вече са били "изконсумирани". Поради ограничения в CTE, това трябва да се направи чрез включване на историята във всеки CTE ред, напр. чрез сглобяване на пътя, следван, за да стигнете до всеки ред. Можете да декомментирате , Path на крайния select за да видите какво става.

-- Sample data.
declare @ACC as Table ( AccNo Int, Property Char );
insert into @ACC values
  ( 1, 'A' ), ( 1, 'B' ), ( 2, 'A' ), ( 2, 'C' ), ( 3, 'C' ), ( 4, 'D' );
select * from @ACC;

-- Recursive CTE.
with Groups as (
  select distinct AccNo, AccNo as LinkedAccNo,
    Cast( '|' + Cast( AccNo as VarChar(10) ) + '|' as VarChar(1024) ) as Path
    from @ACC
  union all
  select G.AccNo, A.AccNo, Cast( Path + Cast( A.AccNo as VarChar(10) ) + '|' as VarChar(1024) )
    from Groups as G inner join -- Take the latest round of new rows ...
      @ACC as AP on AP.AccNo = G.LinkedAccNo inner join -- ... and get the   Property   for each ...
      @ACC as A on A.Property = AP.Property -- ... to find new linked rows.
      where G.Path not like '%|' + Cast( A.AccNo as VarChar(10) ) + '|%' )
  select AccNo, LinkedAccNo -- , Path
    from Groups
    order by AccNo, LinkedAccNo;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Защо 1899-12-30 е нулевата дата в Access / SQL Server вместо 12/31?

  2. SqlBulkCopy от списък<>

  3. Грешка на SQL Server - HRESULT E_FAIL е върнат от повикване към COM компонент

  4. Как да активирате всички ограничения за проверка и външни ключове в база данни в SQL Server (примери за T-SQL)

  5. Как да предадете масив в съхранена процедура на SQL Server