2014-02-11 4 views
0

Предположим следующую таблицу:Рекурсия с SQL Server 2012

SQL Fiddle

Сервер 2012 Настройка схемы MS SQL:

CREATE TABLE entries 
    (
    [entryID] [uniqueidentifier] NOT NULL, 
    [bOpen] [bit] NULL, 
    [nextEntryID] [uniqueidentifier] NULL, 
    ); 

INSERT INTO entries 
(entryID, bOpen, nextEntryID) 
VALUES 
('21572F4C-BA63-489B-9205-AD1451CEE411', 0, NULL), 
('FF4ADC83-1270-418B-8E31-FD1AEA2C1ADF', 0, '21572F4C-BA63-489B-9205-AD1451CEE411'), 
('7ED7AF83-6595-4848-AFDF-4F7D54889F80', 1, NULL), 
('C7AA25D3-B70D-45CB-A143-CF380E6FD0D3', 1, '7ED7AF83-6595-4848-AFDF-4F7D54889F80'), 
('ADA3312E-6FF2-4EC6-9FE3-C994D2FCD16F', 1, 'C7AA25D3-B70D-45CB-A143-CF380E6FD0D3'), 
('9BE0F5FA-09F0-423C-8173-98AD73522412', 0, NULL), 
('5019558E-73FC-4A10-B526-49DB2253B9B9', 1, 'B2EF093A-45B4-4780-A5F5-ECEE02A26274'), 
('B2EF093A-45B4-4780-A5F5-ECEE02A26274', 0, NULL) 

Query 1:

select * from entries 

Results:

|        ENTRYID | BOPEN |       NEXTENTRYID | 
|--------------------------------------|-------|--------------------------------------| 
| 21572F4C-BA63-489B-9205-AD1451CEE411 |  0 |        (null) | 
| FF4ADC83-1270-418B-8E31-FD1AEA2C1ADF |  0 | 21572F4C-BA63-489B-9205-AD1451CEE411 | 
--------------------------------------------------------------------------------------- 
| 7ED7AF83-6595-4848-AFDF-4F7D54889F80 |  1 |        (null) | 
| C7AA25D3-B70D-45CB-A143-CF380E6FD0D3 |  1 | 7ED7AF83-6595-4848-AFDF-4F7D54889F80 | 
| ADA3312E-6FF2-4EC6-9FE3-C994D2FCD16F |  1 | C7AA25D3-B70D-45CB-A143-CF380E6FD0D3 | 
--------------------------------------------------------------------------------------- 
| 9BE0F5FA-09F0-423C-8173-98AD73522412 |  0 |        (null) | 
--------------------------------------------------------------------------------------- 
| 5019558E-73FC-4A10-B526-49DB2253B9B9 |  1 | B2EF093A-45B4-4780-A5F5-ECEE02A26274 | 
| B2EF093A-45B4-4780-A5F5-ECEE02A26274 |  0 |        (null) | 

Как вы уже заметили, у меня есть поле nextEntryID, который содержит связанный entryID.
В результате я разделил пары на hypens.

Самая интересная пара - две последние записи. Оба связаны друг с другом, но имеют другое значение bOpen (1 и 0 соответственно).

Теперь я хотел бы узнать все записи/пары в моей таблице, где начальная запись имеет bOpen = 1 и связана с другой записью с bOpen = 0.

Теоретически, могут быть неограниченные записи, связанные друг с другом, поэтому я предполагаю, что в этом случае нам нужна какая-то рекурсия?
Или есть другой способ для этого?


Дополнительная информация (спасибо @ david.pfx):

  • структура, как это, и я не хотел бы изменить структуру, хотя можно было бы добавить изменения.
  • «Глубина» связанных записей не фиксируется на 2 или 3; Я предполагаю, что глубина не будет больше 4 раз, но это возможно.
  • IDs глобально уникальный
  • Любой подход/предложение было бы здорово
+0

Требуется определение большей необходимости. Является ли эта структура данных жестко определена или вы ее создали? Можете ли вы изменить структуру? Является ли глубина привязки фиксированной на 2 или 3, или она может быть глубже? Являются ли идентификаторы глобально уникальными? Вы настойчивы в ответе, который является одним SQL-запросом или хранимой процедурой или алгоритмическим кодом? –

+0

@ david.pfx Смотрите мое обновление выше. – seph

+0

@KumarHarsh Что? Я полностью понимаю, что записи, которые я генерирую с помощью NEWID(), получают ... новый идентификатор. Я сделал это, потому что это просто неважно. Я думал, что это ясно из вопроса, но это, похоже, вызывает путаницу, поэтому я все равно отредактирую. – seph

ответ

0

не complete.try что-то вроде этого.

declare @entries TABLE 
    ([entryID] [uniqueidentifier] NOT NULL,[bOpen] [bit] NULL,[nextEntryID] [uniqueidentifier] NULL 
    ); 

INSERT INTO @entries 
(entryID, bOpen, nextEntryID) 
VALUES 
('21572F4C-BA63-489B-9205-AD1451CEE411', 0, NULL), 
('FF4ADC83-1270-418B-8E31-FD1AEA2C1ADF', 0, '21572F4C-BA63-489B-9205-AD1451CEE411'), 
('7ED7AF83-6595-4848-AFDF-4F7D54889F80', 1, NULL), 
('C7AA25D3-B70D-45CB-A143-CF380E6FD0D3', 1, '7ED7AF83-6595-4848-AFDF-4F7D54889F80'), 
('ADA3312E-6FF2-4EC6-9FE3-C994D2FCD16F', 1, 'C7AA25D3-B70D-45CB-A143-CF380E6FD0D3'), 
('9BE0F5FA-09F0-423C-8173-98AD73522412', 0, NULL), 
('5019558E-73FC-4A10-B526-49DB2253B9B9', 1, 'B2EF093A-45B4-4780-A5F5-ECEE02A26274'), 
('B2EF093A-45B4-4780-A5F5-ECEE02A26274', 0, NULL) 
--select * from @entries 
;With CTE as 
(select a.*,1 rn from @entries a 
where a.nextEntryID is not null and a.bopen=1 
union all 
select e.*,rn+1 from @entries E inner join cte C on c.nextEntryID=e.EntryID and e.bOpen=0 
) 

select a.* from cte a