简体   繁体   中英

SQL Server SELECT from multiple tables

I'm creating a timesheet app and have the following tables...

tblTimeEntry :

-entryID (int)
-entryDate (datetime)
-enteredDate (datetime)
-entryUser (int)
-entryJob (int)
-entryTask (int)
-entryWeekNo (int)

tblWagesWeeks :

-weekID (int)
-weekDay (int)
-date (datetime)

tblWagesWeeks contains weekID which is an int assigning an int to each week. weekDay is an int from 1-7 allocating an int to each day of the week. Three years worth of dates have been entered into tblWagesWeeks with the corresponding weekDay numbers and weekID numbers.

tblTimeEntry is used to record time entries which are allocated to a date.

tblTimeEntry.entryWeekNo matches tblWagesWeeks.weekID and is an int to represent the week number. tblTimeEntry.entryDate matches tblWagesWeeks.date and is a datetime .

So for the front end I display a listview displaying the weeks. The users clicks on a week and the days in that week are displayed. When the user clicks on a day they are able to enter a time entry.

The problem I have is when I try to list the time entries for a week using the following query...

SELECT 
    *,   
    CONVERT(varchar(19),CONVERT(date,date,106),103) AS dateFormatted,
    CASE 
       WHEN entryHalfDay = '1' 
          THEN 'Half Day' 
       WHEN entryHalfDay = '0' 
          THEN '' 
    END AS [entryHalfDayString], 
    CASE 
       WHEN entryFullDay = '1' 
         THEN 'Full Day' 
       WHEN entryFullDay = '0' 
         THEN '' 
    END AS [entryFullDayString], 
    CASE 
       WHEN enteredDate IS NULL 
          THEN '' 
          ELSE 'Entry Complete' 
    END AS dayStatus 
FROM 
    tblWagesWeeks AS a 
LEFT JOIN 
    tblTimeEntry AS b ON a.[date] = b.entryDate 
WHERE 
    (entryUser = '1' OR entryUser IS NULL) AND weekID = '25'

The problem I have is that if the user I'm searching on ('1' in the query above) does not have a time entry on a particular date but another user does, the empty date is not show in the list so the user does not have an opportunity to enter time for that day

Below is output from the query above to demonstrate...

weekID  weekDay date    entryID entryDate   enteredDate entryUser   entryJob    entryTask   entryFullDay    entryHalfDay    entryWeekNo dateFormatted   entryHalfDayString  entryFullDayString  dayStatus
25  1   2015-06-15  23  2015-06-15  2015-07-14  1   5   5   1   0   25  15/06/2015      Full Day    Entry Complete
25  2   2015-06-16  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    16/06/2015  NULL    NULL    
25  3   2015-06-17  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    17/06/2015  NULL    NULL    
25  4   2015-06-18  26  2015-06-18  2015-07-14  1   2   2   1   0   25  18/06/2015      Full Day    Entry Complete
25  5   2015-06-19  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    19/06/2015  NULL    NULL    
25  7   2015-06-21  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    21/06/2015  NULL    NULL    

As you can see, day 6 is missing.

When I search for the same week using entryUser = 25 you can see that there is a entry for day 6...

SELECT *, CONVERT(varchar(19),CONVERT(date,date,106),103) AS dateFormatted,
CASE WHEN entryHalfDay='1' THEN 'Half Day' WHEN entryHalfDay='0' THEN '' END AS [entryHalfDayString], 
CASE WHEN entryFullDay='1' THEN 'Full Day' WHEN entryFullDay='0' THEN '' END AS [entryFullDayString], 
CASE WHEN enteredDate IS NULL THEN '' ELSE 'Entry Complete' END AS dayStatus 
FROM tblWagesWeeks AS a LEFT JOIN tblTimeEntry AS b ON a.[date] = b.entryDate 
WHERE (entryUser = '25' OR entryUser IS NULL) AND weekID = '25'

weekID  weekDay date    entryID entryDate   enteredDate entryUser   entryJob    entryTask   entryFullDay    entryHalfDay    entryWeekNo dateFormatted   entryHalfDayString  entryFullDayString  dayStatus
25  1   2015-06-15  23  2015-06-15  2015-07-14  1   5   5   1   0   25  15/06/2015      Full Day    Entry Complete
25  2   2015-06-16  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    16/06/2015  NULL    NULL    
25  3   2015-06-17  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    17/06/2015  NULL    NULL    
25  4   2015-06-18  26  2015-06-18  2015-07-14  1   2   2   1   0   25  18/06/2015      Full Day    Entry Complete
25  5   2015-06-19  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    19/06/2015  NULL    NULL    
25  7   2015-06-21  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    21/06/2015  NULL    NULL    

so I need to know how I can always show all week days in the list, blank and populated for a single user and a single week number.

Any help would be massively appreciated.

You need to make the user condition of the join and the week a condition of the main table like this:

SELECT *, CONVERT(varchar(19),CONVERT(date,date,106),103) AS dateFormatted,
CASE WHEN entryHalfDay='1' THEN 'Half Day' WHEN entryHalfDay='0' THEN '' END AS [entryHalfDayString], 
CASE WHEN entryFullDay='1' THEN 'Full Day' WHEN entryFullDay='0' THEN '' END AS [entryFullDayString], 
CASE WHEN enteredDate IS NULL THEN '' ELSE 'Entry Complete' END AS dayStatus 
FROM tblWagesWeeks AS a 
LEFT JOIN tblTimeEntry AS b ON a.[date] = b.entryDate AND b.entryUser = 25
WHERE a.weekID = '25'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM