2016-01-24 2 views
0

У меня есть две таблицы в SQL Server:Нужна помощь по запросу DATE на SQL-сервере?

  1. EMP
  2. On_Vacation с colums EmpId, LeaveType, StartingFrom, EndingTo,RejoiningDate

В On_Vacation таблица хранит информацию о служащих, которые находятся в отпуске.

enter image description here

Я пытаюсь запросить таблицу таким образом, что мой запрос имеет следующие столбцы:

EmpId, 24-1-2016, 25-1-2016, 26-1-2016, 27-1-2016, 28-1-2016 

столбцов результата запроса являются даты этой недели. Если в эти даты Employee не находится в отпуске, он должен написать available. В противном случае он должен написать тип отпуска.

Я очень новой для этого типа запросов, пожалуйста, помогите мне .. экспертов

+0

Создайте реальную или динамическую таблицу календаря (по одной строке на дату), а затем присоедините ее к таблице праздничных дней. После того, как у вас есть результаты, вы можете развернуть его в разные макеты. –

+0

Спасибо, Джеймс. Но мне нужны даты в виде столбцов? – Programmer2015

+0

Это то, что точка для –

ответ

1

Вы не можете изменить имя столбца без динамического sQL (что усложняет вопросы). Вот еще одно предложение: что вы изменить таблицу дат включает название дня недели, как это:

CREATE TABLE DaysWeeks 
    (CalYear SMALLINT NOT NULL, 
    WeekNumber TINYINT NOT NULL, 
    CalDate DATE NOT NULL, 
    DayOfWeekNumber TINYINT, 
    DayOfWeekName VARCHAR(9) 
    CONSTRAINT PK_DaysWeeks PRIMARY KEY CLUSTERED (CalYear, WeekNumber, CalDate) 
    ) 

со значениями вроде этого:

INSERT INTO dbo.DaysWeeks 
     (CalYear, WeekNumber, CalDate,DayOfWeekNumber,DayOfWeekName) 
VALUES (2016, 4, '01/24/2016',1,'Sunday'), 
     (2016, 4, '01/25/2016',2,'Monday'), 
     (2016, 4, '01/26/2016',3,'Tuesday'), 
     (2016, 4, '01/27/2016',4,'Wednesday'), 
     (2016, 4, '01/28/2016',5,'Thursday'), 
     (2016, 4, '01/29/2016',6,'Friday'), 
     (2016, 4, '01/30/2016',7,'Saturday') 

Теперь вы можете иметь запрос, который вращается на основе дня недели:

WITH cte AS (
SELECT EmpDays.Employee, EmpDays.CalDate, EmpDays.DoWName, ISNULL(v.Leave_Type,'Available') AS Available 
FROM dbo.On_Vacation v 
RIGHT OUTER JOIN 
(SELECT e.EmpID AS Employee, dw.CalDate AS CalDate, dw.DayOfWeekName AS DoWName 
    FROM dbo.DaysWeeks dw, 
     dbo.Employee e 
     WHERE dw.CalYear = 2016 AND dw.WeekNumber = 4) AS EmpDays 
ON 
    v.EmpID = EmpDays.Employee 
    AND v.StartingFrom <= empdays.CalDate 
    AND v.EndingTo >= empdays.CalDate 
) 
SELECT * FROM cte 
PIVOT (MAX(cte.Available) FOR DoWName IN (['Sunday'],['Monday'],['Tuesday'],['Wednesday'],['Thursday'],['Friday'],['Saturday']) 

Если вы действительно нужны фактические даты в ваших колонках я отрегулировал бы это использовать динамический SQL. Но прежде чем это сделать (что, IMHO, делает код намного сложнее читать и поддерживать, а не то, что это так просто), я бы спросил, как вы собираетесь представлять данные и, следовательно, может ли это быть обработано в отчете или уровень представления.

1

Вы бы сделать это с помощью условной агрегации:

select e.empid, 
     coalesce(max(case when '2016-01-24' between v.startdate and v.enddate 
         then leave_type end), 
       'available') as [2016-01-14], 
     coalesce(max(case when '2016-01-25' between v.startdate and v.enddate 
         then leave_type end), 
       'available') as [2016-01-15], 
     . . . 
from emp e left join 
    from vacation v 
    on e.empid = v.empid 
group by e.empid; 
+0

Спасибо, Гордон, это прекрасно работает. Но как динамически использовать даты, поскольку я сохранил даты в другой таблице. Имя таблицы: «Даты и недели», которая имеет два столбца (1.Date и 2. WeekNo). Есть ли способ, если я даю только weekno, то указанный выше запрос должен выполняться для всех дат этой недели, а не для записи каждой даты? – Programmer2015

+0

@ Programmer2015. ,, Динамические даты - это гораздо более сложный вопрос, а не вопрос, который вы задали. Вы можете задать другой вопрос, но, вероятно, проще просто «динамический pivot» для SQL Server. –