Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
Приветствую!
Такой вопрос:
в рекурсивных запросах нельзя 2 раза выборку делать ?
пример:
with cte as (select a, b from aa)
select top 1 a from cte
select top 1 a from (select top 2 a from cte order by b desc)

если так, то какой выход может быть, еще 1 рекурсивный запрос писать такой же и из него делать выборку?
18 мар 16, 15:14    [18948743]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Glory
Member

Откуда:
Сообщений: 104751
mishanya3624
в рекурсивных запросах нельзя 2 раза выборку делать ?

2 раза делать выборку - это у вас значит вернуть два разных результата ?

mishanya3624
если так, то какой выход может быть

Что вы пытаетесь соорудить ?
18 мар 16, 15:20    [18948786]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37228
cte -- это чать одного запроса.
18 мар 16, 15:20    [18948788]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
нет, 2 разных числа, это я упрощенный пример просто привел, чтобы не мудрить и понять можно ли из cte делать несколько запросов.
цель такая:
есть запрос который возвращает даты и числа(кол-во проходов)
необходимо посчитать "последняя дата - предыдущая дата"
даты с числами формируются каждый час, то есть надо "последний час - предыдущий час" (кол-во проходов за последний час)
18 мар 16, 15:41    [18948955]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Glory
Member

Откуда:
Сообщений: 104751
mishanya3624
необходимо посчитать "последняя дата - предыдущая дата"

И зачем для этого 2 select-а ?
18 мар 16, 15:43    [18948969]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
Glory,

думал это сделать через переменные, вида:
declare @q int , @qq int
set @q = (1 select из cte)
set @qq = (2 select из cte)

select @q - @qq 

но так он не хочет, потому что походу бредовая идея:)

а какой вариант может быть?
18 мар 16, 15:48    [18949031]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Glory
Member

Откуда:
Сообщений: 104751
mishanya3624
а какой вариант может быть?

Вы не можете одиним select-ом выбрать два значеняи из таблицы ?
18 мар 16, 15:50    [18949040]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
нет я это сделал конечно, но получился большой запрос, уверен можно сделать лучше и быстрее
18 мар 16, 15:50    [18949043]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Glory
Member

Откуда:
Сообщений: 104751
mishanya3624
но получился большой запрос, уверен можно сделать лучше и быстрее

select max(case when <condition 1> then <value1> end), max(case when <condition 2> then <value2> end)
from mytable
18 мар 16, 15:52    [18949071]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
Glory,

Я конечно извиняюсь за свое недопонимание:) но как это поможет в моей задаче

таблица получается такого вида :

2016-03-18 10:59:57.000 678
2016-03-18 09:59:57.000 583
2016-03-18 08:59:57.000 245
2016-03-18 07:59:57.000 20

то есть мне надо 678 - 583 это один момент(соответственно я заведомо не знаю эти числа и не могу их внести в условие вручную)
второй когда делаю группировку по дням и выкатываю отчет "разность прохода текущего дня от предыдущего, или недельной давности", то первое число из которого вычитаю не всегда больше предыдущего
18 мар 16, 16:38    [18949479]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
вот как я сделал, убого, согласен, самому не нравится, поэтому и думаю как по другому:
with cte as (
select top 1 (SELECT top 1 SUM (Traffic.[RealIn]) as RealIn 	      
     
  FROM [RStatData].[dbo].[Traffic] as Traffic
  LEFT JOIN [RStatData].[dbo].[Sensors] as S ON Traffic.SensorID = S.ID
  left join [RStatData].[dbo].[GroupsEntries] as G ON G.EntryID = S.EntryID 

  where CONVERT(datetime, Traffic.DateCreated ) >=  '2016-01-01' 
  and G.GroupID = 1
  group by CONVERT(datetime, Traffic.DateCreated ) 
  order by CONVERT(datetime, Traffic.DateCreated ) desc) as rr ,
  (SELECT top 1 * from (select top 2 SUM (Traffic.[RealIn]) as RealIn2 	      
     
  FROM [RStatData].[dbo].[Traffic] as Traffic
  LEFT JOIN [RStatData].[dbo].[Sensors] as S ON Traffic.SensorID = S.ID
  left join [RStatData].[dbo].[GroupsEntries] as G ON G.EntryID = S.EntryID 

  where CONVERT(datetime, Traffic.DateCreated ) >=  '2016-01-01' 
  and G.GroupID = 1
  group by CONVERT(datetime, Traffic.DateCreated ) 
  order by CONVERT(datetime, Traffic.DateCreated ) desc ) as rt order by RealIn2 asc) as ii
   from 
   [RStatData].[dbo].[Traffic] as Traffic
  LEFT JOIN [RStatData].[dbo].[Sensors] as S ON Traffic.SensorID = S.ID
  left join [RStatData].[dbo].[GroupsEntries] as G ON G.EntryID = S.EntryID )
  select rr - ii from cte
18 мар 16, 17:10    [18949685]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
iljy
Member

Откуда:
Сообщений: 8711
mishanya3624,

жесть ваще. Если я хоть примерно понял, что надо сделать, то вот
;with src(dt, cnt) as
(
	select '2016-03-18 10:59:57.000',	678 union all
	select '2016-03-18 09:59:57.000',	583 union all
	select '2016-03-18 08:59:57.000',	245 union all
	select '2016-03-18 07:59:57.000',	20
),
tab as
(
	select ROW_NUMBER() over(order by dt) rn, * from src
)
select t2.dt, t2.cnt - t1.cnt
from tab t1 join tab t2 on t1.rn + 1 = t2.rn



кстати, не указали версию сервера, если 2012 и выше, то гуглите LAG-LEAD.
21 мар 16, 00:17    [18956857]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
iljy,

Спасибо!
версия древняя к сожалению
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 Copyright (c) 1988-2008 Microsoft Corporation Express Edition on Windows NT 6.1 <X86> (Build 7601: Service Pack 1)

а в чем разница, если я буду 2 рекурсии делать, или все в одной, по выполнению - одинаково, или правильно все же разделять?
;with src(id ,dt, cnt) as
(
	SELECT top 1 ROW_NUMBER() over(order by CONVERT(datetime, Traffic.DateCreated )) , 
	CONVERT(datetime, Traffic.DateCreated ), SUM (Traffic.[RealIn]) RealIn 	      
     
  FROM [RStatData].[dbo].[Traffic]  Traffic
  LEFT JOIN [RStatData].[dbo].[Sensors]  S ON Traffic.SensorID = S.ID
  left join [RStatData].[dbo].[GroupsEntries]  G ON G.EntryID = S.EntryID 

  where CONVERT(datetime, Traffic.DateCreated ) >=  '2016-01-01' 
  and G.GroupID = 1
  group by CONVERT(datetime, Traffic.DateCreated ) 
  order by CONVERT(datetime, Traffic.DateCreated ) desc
)
select t2.dt , t2.cnt - t1.cnt
from src t1 join src t2 on t1.id + 1 = t2.id
21 мар 16, 11:06    [18957766]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
Glory
Member

Откуда:
Сообщений: 104751
mishanya3624
если я буду 2 рекурсии делать

cte - это не синоним рекурсии
Ни в вашем примере, ни в примере iljy нет никакой рекурсии.
21 мар 16, 12:16    [18958321]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсия  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
Glory,

провал в теории...
Вы правы, совсем не рекурсия.
21 мар 16, 12:52    [18958515]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить