2014-01-17 2 views
0

У меня есть 2 таблицы sql по имени mtblAttendance и mtblLeave_Data.Как соединить таблицы sql по-моему

Мне нужно получить все даты от mtblLeave_Data, когда Пользователь находился в отпуске в зависимости от отсутствия в mtblAttendance.

В моем mtblAttendance для каждой покинуть есть ряд, но если пользователь в отпуск на период, так нет уникальной строки, есть только две колонки Leave_From и Leave_To (или это может быть одна запись, где Leave_From= Leave_To) ,

Для получения отсутствующих дат пользователя Я написал запрос

USE [ILeave] 

ALTER procedure [dbo].[Attendance_Report] 
@Date1 datetime, 
@Date2 datetime, 
@User_Id nvarchar(50) 
as begin 


SELECT distinct 
a.Sno, 
a.[Login_Date], 
a.[Week_Day], 
a.[In_Time], 
a.[Out_Time], 
a.Attendance_Status, 
a.Half_Full, 
a.Leave_Type, 

(convert(varchar(max),floor (abs(cast(datediff(mi, a.Out_Time, a.In_Time) AS int)/60)))+ '.'+ convert(varchar(max),(abs(cast(datediff(mi, a.Out_Time, a.In_Time) AS int) % 60)))) as Hrs 


, l.[Sno] 
, l.[Leave_ID] 
, l.[User_Id] 
, l.[Dept_To] 
, l.[Leave_Type] 
, l.[Total_Leave_HR] 
, l.[Leave_From] 
, l.[Leave_To] 
, l.[Leave_Half_Full] 
, l.[Comments] 
, l.[Leave_Status] 
FROM 
[mtblAttendance] a 
LEFT JOIN [mtbl_Leave_Data] l 
    ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To] 
    AND l.[User_Id] = a.[User_Id] where a.Login_Date between @Date1 and @Date2 and [email protected]_Id order by Login_Date 
end 

enter image description here

+1

Я думаю, у меня есть идея, что вы имеете в виду, но я не уверен. Пример с некоторыми реальными данными был бы приятным. Это делает ваш вопрос более ясным. Правильно ли я понимаю, что ваша проблема заключается главным образом в том, что вам нужны записи в результате с датами, которые являются частью периода? Таким образом, вы не можете выбрать дни, но вам нужен способ динамически генерировать дни периодов? – SonOfGrey

+0

Если ваша проблема в том, что я думаю, вы должны иметь возможность присоединиться к таблице или функции, которая содержит все даты за период. [Здесь] (http://stackoverflow.com/questions/510012/get-a-list-of-dates-between-two-dates) являются хорошими примерами того, как это сделать. Простейшее начало: создайте таблицу с столбцом даты, которая содержит даты в течение многих лет. Вы можете присоединиться к нему, когда захотите. – SonOfGrey

ответ

0

Join выражения не ограничиваются использованием знака равенства. Используйте «между» в выражении объединения. Что-то вдоль этих (непроверенных) строк должно работать.

select distinct A.Login_Date 
from mtblAttendance A 
inner join mtbl_Leave_Data L 
    on A.User_id = L.User_id 
    and A.Login_date between L.Leave_From and L.Leave_To 
where A.User_Id = 'sasi' AND A.Attendance_Status='A' 

В зависимости от того, что вы пытаетесь сделать, вам может потребоваться изменить внутреннее соединение на левое внешнее соединение. Левое внешнее соединение сохранит все даты входа из mtblAttendance, независимо от того, удовлетворяют ли они условиям соединения. (Эти строки будут отфильтрованы по ИНЕК, конечно.)

+0

дает повторяющиеся строки. – Gaurav

+0

Это связано с тем, что у вас есть несколько строк в файле mtbl_Leave_Data, которые удовлетворяют условию соединения для некоторых значений mtblAttendance.Login_Date, или у вас есть несколько строк в mtblAttendance, которые имеют одинаковое значение для даты входа. Использование 'SELECT DISTINCT' устранит их. Вставьте инструкции CREATE TABLE и инструкции INSERT в свой вопрос для получения более подробной информации. –

0

Следующий запрос должен возвращать запись отпуска назначенной

SELECT 
    a.[Login_Date] 
    , l.[Sno] 
    , l.[Leave_ID] 
    , l.[User_Id] 
    , l.[Dept_To] 
    , l.[Leave_Type] 
    , l.[Total_Leave_HR] 
    , l.[Leave_From] 
    , l.[Leave_To] 
    , l.[Leave_Half_Full] 
    , l.[Comments] 
    , l.[Leave_Status] 
FROM 
    [mtblAttendance] a 
    LEFT JOIN [mtbl_Leave_Data] l ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To] 
WHERE 
    a.User_Id = 'sasi' 
    AND a.Attendance_Status='A' 

Я положил его в fiddle, но без каких-либо данных, поэтому все, что я могу скажем, что запрос анализирует.

Как уже говорилось ранее, обычно имеют таблицы с датами, в результате чего запросы, требующие каждой даты в течение 2 лет, могут быть быстро оценены.

Обновлено SQL:

SELECT DISTINCT 
    a.[Login_Date] 
    , l.[Sno] 
    , l.[Leave_ID] 
    , l.[User_Id] 
    , l.[Dept_To] 
    , l.[Leave_Type] 
    , l.[Total_Leave_HR] 
    , l.[Leave_From] 
    , l.[Leave_To] 
    , l.[Leave_Half_Full] 
    , l.[Comments] 
    , l.[Leave_Status] 
FROM 
    [mtblAttendance] a 
    LEFT JOIN [mtbl_Leave_Data] l 
     ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To] 
     AND l.[userId] = a.[user_id] -- Ensure only attendance/leave for the same user being linked 
WHERE 
    a.User_Id = 'sasi' 
    AND a.Attendance_Status='A' 
+0

он также дает повторяющиеся строки. – Gaurav

+0

см. Мой новый запрос – Gaurav

+0

Если они полностью повторяются, вы можете сделать «SELECT DISTINCT», как вы обновите скрипт, который я создал, чтобы включить некоторые данные, чтобы нам было легче видеть, помогаем ли мы. Существуют ли повторяющиеся или противоречивые записи для пользователя «sasi» в посещаемости или оставить таблицы? (т. е. есть ли две записи для одной даты?) Я заметил, что мой запрос не ограничивал идентификатор пользователя в таблице «Отпуск», поэтому возможно, что это вызывает проблему, так как если другой пользователь уйдет на дату, которая перекрывает посещаемость «sasi», будет несколько строк. – talegna

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