Рекурсивная функция подходит? - PullRequest
0 голосов
/ 07 мая 2020

Привет, ребята, не могли бы вы помочь мне с рекурсивным запросом в SQL. Или даже если рекурсивный запрос - правильный выбор. У меня есть такие столбцы, скажем,

ID | CUS | CASHIERID | RECEIPTID | PAYMENTNUM | ORIGINALRECEIPT

Теперь предположим, что есть такие данные:

+----------+--------+-------------+-------------+--------------+------------------+
|     ID   |  CUS   |  CASHIERID  |  RECEIPTID  |  PAYMENTNUM  |  ORIGINALRECEIPT |
+----------+--------+-------------+-------------+--------------+------------------+
|       1  |  jeff  |           2 |        123  |       00005  |  NULL            |
|       4  |  jeff  |           2 |        548  |       00005  |  123             |
|      16  |  jeff  |           2 |        897  |       00005  |  123             |
|     151  |  jeff  |           2 |       1095  |       00005  |  123             |
+----------+--------+-------------+-------------+--------------+------------------+

Теперь предположим, что база данных огромна и может быть X количество связанных квитанций, поскольку мы см. выше ID - оригинал, а все остальные связаны (возврат или что-то в этом роде). Теперь предположим, что мне дали RECEIPTID за любой из них. Чтобы получить все родительские / дочерние строки этого, каков лучший маршрут? Моя первая первоначальная мысль - просто сделать что-то вроде IF ELSE, и если ORIGINALRECEIPT не пусто, то сделать предложение where с тем, что в нем. Но в качестве аргумента вы сможете выполнить своего рода рекурсивный запрос, чтобы иметь возможность ввести любой идентификатор получения и получить обратно все 4 записи

EDIT

Привет, ребята Итак, небольшое изменение, поэтому у меня работает рекурсивная функция, но теперь вы видите, что база данных ОГРОМНА, и когда я выполняю рекурсивную функцию, которая находит все перевыпущенные квитанции (новые) после того, как пользователь вводит идентификатор квитанции, поэтому пользователь вводит идентификатор получения, Затем выполняется рекурсивный запрос, который получает все связанные более новые квитанции с использованием столбца prevRecep, в котором есть идентификатор до получения, например, цепочка, как указано в комментариях. У меня нет проблем с небольшой тестовой базой данных, но ОГРОМНАЯ БД работает очень медленно, прошло 40 минут и все еще не закончена. есть указатель по CU, cashierid, чеков, но, к сожалению, на данный момент у меня нет индекса для любого другого столбца. Итак, я знаю, что это уже действительно замедлит мой запрос, поскольку я использую в нем столбец prevRecep, но есть ли способ ускорить его или лучший подход? Ниже рекурсивный запрос

with cte as (
  select *
  from receipts
  where cus='jeff' and casherid='2' and receiptid= '548'

  union all

  select cur.*
  from receiptscur, cte
  where cur.prevRecep = cte.recieptID
)
select * from cte

1 Ответ

2 голосов
/ 07 мая 2020

Да, рекурсивный запрос должен подойти:

declare @ReceiptId int = 123;

with cte as (
  --These are the anchor (the parents)
  select *
  from Receipts
  where ReceiptId = @ReceiptId and OriginalReceipt is null  

  union all

  --These are the recursive childs. Could be multiple levels : parent, child, subchild, ...
  select Receipts.*
  from Receipts
       inner join cte on cte.ReceiptId = Receipts.OriginalReceipt
)
select * from cte;

Кстати, если ваши родительско-дочерние отношения не имеют более одного уровня, тогда запрос не не обязательно быть рекурсивным, достаточно простого UNION:

declare @ReceiptId int = 123;

select *
from Receipts
where ReceiptId = @ReceiptId 

union all

select Receipts.*
from Receipts
where OriginalReceipt = @ReceiptId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...