Циклы на SQL сервере - PullRequest
       4

Циклы на SQL сервере

1 голос
/ 10 февраля 2020

У меня следующий запрос, в котором я ввожу дату, и она дает мне результат. Тем не менее, мне нужно запустить это на 60 разных дат. Вместо того, чтобы выполнять это 1 на 1, есть ли способ автоматизировать его, чтобы он запускался каждый раз в разные даты?

  IF OBJECT_ID('tempdb..#1') IS NOT NULL DROP TABLE #1
    declare @d1 datetime = '2020-02-06' 
  select distinct [User] into #1
  from [X].[dbo].[Table1]
  where [status] = 'Success'
  and [Date] = @d1;

  select count(distinct [User])
  from #1
  inner join [Y].[dbo].[Table2]
  on #1.[User] = [Y].[dbo].[Table2].User
  where [Date2] between @d1 and @d1+1
  and [Checkname] in ('Check1','Check2')

Ответы [ 2 ]

0 голосов
/ 10 февраля 2020

Во-первых, я хочу сказать, что ответ gotqn является хорошим ответом - однако я думаю, что в исходном коде есть еще несколько вещей, которые можно улучшить - вот как я, вероятно, сделал бы это:

Предполагая, что даты являются последовательными, используйте общее табличное выражение для вычисления дат, используя dateadd и row_number.
Затем используйте другое общее табличное выражение, чтобы получить список дат и пользователей из table1,
, а затем выберите дату и количество отдельных пользователей для каждой даты из этого общего табличного выражения, объединенного с table2:

DECLARE @StartDate Date = '2020-02-06';
WITH Dates AS
(
    SELECT TOP (60) DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY @@SPID) -1, @StartDate) As Date
    FROM sys.objects
), CTE AS
(
    SELECT t1.[User], t1.[Date]
    FROM [X].[dbo].[Table1] AS t1
    JOIN Dates 
        ON t1.[Date] = Dates.[Date]
    WHERE [status] = 'Success'
)

SELECT cte.[Date], COUNT(DISTINCT [User])
FROM CTE 
JOIN [Y].[dbo].[Table2] As t1
    ON CTE.[User] = t1.[User]
    AND t1.[Date2] >= CTE.[Date]
    AND t1.[Date2] < DATEADD(Day, 1, CTE.[Date])
    AND [Checkname] IN ('Check1','Check2')
GROUP BY cte.[Date]

Если даты не являются последовательными, вы можете использовать переменную таблицы для хранения даты вместо их вычисления с использованием общего табличного выражения.

0 голосов
/ 10 февраля 2020

Циклы медленные и обычно плохая практика в контексте T- SQL. Вы можете использовать что-то вроде этого, чтобы получить количество пользователей для пакета дат:

DROP TABLE IF EXISTS #DataSource;

CREATE TABLE #DataSource
(
    [Date] DATETIME
   ,[UsersCount] INT
);

INSERT INTO #DataSource ([Date])
VALUES ('2020-02-06')
      ,('2020-02-07')
      ,('2020-02-08');


IF OBJECT_ID('tempdb..#1') IS NOT NULL DROP TABLE #1

select distinct DS1.[Date]
               ,DS1.[User] 
into #1
from [X].[dbo].[Table1] DS1
INNER JOIN #DataSource DS2
    ON DS1.[Date] = DS2.[Date]
where DS1.[status] = 'Success';

select #1.[date]
      ,count(distinct [User])
from #1
inner join [Y].[dbo].[Table2]
  on #1.[User] = [Y].[dbo].[Table2].User
where [Date2] between #1.[date] and #1.[date] + 1
  and [Checkname] in ('Check1','Check2')
GROUP BY #1.[date]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...