2014-12-15 2 views
0

У меня есть база данных, в которой хранятся вход и выход из работы, но у нас нет работы по выходным. Мой руководитель хочет, чтобы формат отчета DTR (я использую отчет RDLC) включает выходные дни. (прилагается изображение)включают выходные по sql-запросу

enter image description here

Изображение выше ожидаемый выходной формат для DTR. Я просто хочу знать, как включать выходные, хотя мои данные находятся только в будние дни. Можно ли это сделать с помощью SQL Query? Если да, следует ли использовать цикл в sql здесь?

SQL код:

select user_id,log_date,login_time,logout_time 
from table_DTR 
where user_id = 'USER1' 
AND log_date BETWEEN '11/21/2014' AND '12/09/2014' 
+0

@ DeepakPawar: да. но у моей базы данных нет выходных, потому что у нас нет работы по выходным дням, поэтому, если дата = выходные дни, тогда отображается СУББОТА ИЛИ ВОСКРЕСЕНЬЕ. Я обновляю свой пост выше. – Waelhi

ответ

2

Используйте общее выражение таблицы и создайте диапазон дат с и до даты, а затем используйте CTE в качестве левого соединения с фактической таблицей. Я не использовал user_id фильтр в левой присоединиться поэтому применять его к вашему запросу:

DECLARE @TMEP TABLE 
    (
     [Date] DATE, 
     [IN] VARCHAR(10), 
     [OUT] VARCHAR(10) 
    ) 

    INSERT INTO @TMEP VALUES ('2014-11-11','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-12','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-13','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-14','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-15','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-18','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-19','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-20','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-21','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-22','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-25','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-26','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-27','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-28','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-11-29','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-12-1','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-12-2','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-12-3','7:30','5:30') 
    INSERT INTO @TMEP VALUES ('2014-12-4','7:30','5:30') 

    DECLARE @FromDate DATE 
    SET @FromDate = '2014-11-11 06:00:00.000' 
    DECLARE @ToDate DATE 
    SET @ToDate = '2014-12-11 06:00:00.000' 

    ;WITH CTE_TableDate ([CTEDate]) as 
    (
     SELECT @FromDate 
     UNION ALL 
     SELECT DATEADD(DAY,1,CTEDate) FROM CTE_TableDate WHERE [CTEDate] < @ToDate 
    ) 
    SELECT 
     CTE_TableDate.CTEDate, 
     CASE WHEN DATEPART(DW, CTE_TableDate.CTEDate) = 7 THEN 'SATURDAY' 
    WHEN DATEPART(DW, CTE_TableDate.CTEDate) = 1 THEN 'SUNDAY' 
    ELSE TEMP.[In] END AS [IN], 
    CASE WHEN DATEPART(DW, CTE_TableDate.CTEDate) = 7 THEN 'SATURDAY' 
    WHEN DATEPART(DW, CTE_TableDate.CTEDate) = 1 THEN 'SUNDAY' 
    ELSE TEMP.[OUT] END AS [OUT] 
    FROM CTE_TableDate 
    LEFT JOIN 
    (
     select 
      [Date], 
      [IN], 
      [OUT] 
     from 
      @TMEP) TEMP 
    ON 
     CTE_TableDate.CTEDate = TEMP.[Date] 
+0

не работает над скриптом sql ... – Waelhi

+0

@ Unknownymous2 Я попробовал это на своем компьютере и его работе. Я проверил его на скрипте sql, но, похоже, проблема с сайтом, потому что сообщение об ошибке говорит: «МОДИФИКАЦИЯ ФАЙЛА встретила ошибку операционной системы 112 (на диске недостаточно места), пытаясь развернуть физический файл« – Sandeep

+0

, какую версию sql вы использовали ? – Waelhi

2

попытка ниже решения:

DECLARE @startdate DATE = '11/21/2014' -- your start date 
DECLARE @enddate DATE = '12/09/2014' -- your start date 
-- create list of all dates between min(log_date) and MAX(log_date) 
;WITH cte 
    AS (SELECT @startdate AS log_date 
     UNION ALL 
     SELECT Dateadd(dd, 1, log_date) log_date 
     FROM cte 
     WHERE log_date < @enddate) 
-- select the data using left outer join so that it will return missing dates too. 
SELECT t1.user_id, 
     c.log_date, 
     t2.login_time, 
     t2.logout_time 
FROM cte c 
     CROSS JOIN (SELECT DISTINCT user_id 
        FROM mytable) t1 
     LEFT OUTER JOIN mytable t2 
        ON t2.user_id = t1.user_id 
         AND t2.log_date = c.log_date 
ORDER BY t1.user_id,c.log_date 
OPTION(maxrecursion 1000) 

Он вернется null во время колонн в выходные дни. Примечание: если вы получаете ошибку: The statement terminated. The maximum recursion 100 has been exhausted before statement completion., тогда попробуйте использовать OPTION(maxrecursion 3000) или больше.

+0

Я получаю эту ошибку: 'Оператор завершен. Максимальная рекурсия 100 была исчерпана до завершения заявки. « – Waelhi

+0

@ Unknownymous2 Я внес некоторые незначительные изменения. Проверь сейчас. –

1

Вы можете создать таблицу календарь, как показано ниже:

CREATE TABLE dbo.Calendar 
(
    dt DATE PRIMARY KEY, -- use SMALLDATETIME if < SQL Server 2008 
    IsWorkDay BIT 
); 

DECLARE @s DATE, @e DATE; 
SELECT @s = '2000-01-01' , @e = '2029-12-31'; 

INSERT dbo.Calendar(dt, IsWorkDay) 
    SELECT DATEADD(DAY, n-1, '2000-01-01'), 1 
    FROM 
    (
    SELECT TOP (DATEDIFF(DAY, @s, @e)+1) ROW_NUMBER() 
     OVER (ORDER BY s1.[object_id]) 
     FROM sys.all_objects AS s1 
     CROSS JOIN sys.all_objects AS s2 
) AS x(n); 

SET DATEFIRST 1; 

-- weekends 
UPDATE dbo.Calendar SET IsWorkDay = 0 
    WHERE DATEPART(WEEKDAY, dt) IN (6,7); 

-- Christmas 
UPDATE dbo.Calendar SET IsWorkDay = 0 
    WHERE MONTH(dt) = 12 
    AND DAY(dt) = 25 
    AND IsWorkDay = 1; 

, а затем использовать так же, как

DECLARE @table_DTR TABLE 
(USER_ID VARCHAR(10), 
log_date DATE, 
login_time TIME, 
logout_time TIME) 
INSERT INTO @table_DTR VALUES ('USER1','11/21/2014','7:55:00','5:00:00') 



select CASE d.IsWorkDay WHEN 0 THEN datename(dw,d.dt) else DTR.user_id END AS user_id, 
d.dt AS log_date, 
DTR.login_time, 
DTR.logout_time 
from dbo.Calendar d 
LEFT JOIN @table_DTR DTR ON d.dt = DTR.log_date AND DTR.user_id = 'USER1' 
WHERE d.dt BETWEEN '11/21/2014' AND '11/26/2014' 

Для детального объяснения преимуществ таблицы календаря вы можете refer here..

Смежные вопросы