Сценарий Mysql - получить все задачи, даже если нет записи? - PullRequest
0 голосов
/ 17 января 2010

У меня три таблицы

  1. Tasks с колонками Taskid, Taskname
  2. TaskAllocations с колонками Taskid, EmpNum
  3. TaskEntries с колонками TaskId, EmpNum, WorkedDate, Hoursspent

Теперь я хочу получить все записи о заданиях за определенную неделю. Здесь моя проблема в том, что даже если для какой-либо задачи нет Taskentry, я должен получить по крайней мере строку с этим TaskId и именем задачи с Hoursspent как Null в наборе результатов запроса. Я пытался получить это с помощью запроса ниже.

SELECT A.TaskId, 
       B.TaskName, 
       SUM( C.HoursSpent ) as TotalHours , 
       C.WorkedDate, C.Comments
    FROM TaskAllocations A
    LEFT OUTER JOIN TaskEntries C 
    ON A.TaskId = C.TaskId
    AND A.EmpNum = C.EmpNum
    INNER JOIN Tasks B 
    ON A.TaskId = B.TaskId
    WHERE A.EmpNum =123456
    AND C.WorkedDate
    IN ('2010-01-17','2010-01-18','2010-01-19',
        '2010-01-20','2010-01-21','2010-01-22','2010-01-23' )
    GROUP BY A.TaskId, C.WorkedDate
    ORDER BY A.TaskId,C.WorkedDate ASC ';

То, что я получаю для этого фрагмента SQL, - это если и только если есть запись для определенного идентификатора задачи, то только я получаю строку для этого. но я хочу получить по крайней мере по одной строке для каждой задачи, которая доступна для EmpNum. Даже если я получу одну строку для каждой комбинации TaskId и WorkedDate, никаких проблем. Пожалуйста, помогите мне с этим. Фактическое намерение этого состоит в том, чтобы создать двухмерную таблицу HTML с каждой записью задачи по дате и задаче, как показано ниже.

    ---------------------------------------------------------
    TaskId  TaskName   Sun  Mon  Tue  Wed  Thu  Fri  Sat
    ---------------------------------------------------------
    18      name1       2          3        4:30      3:30
    19      name2                                           
    20      name3       4                             2:30
    22      name4       2:30
    23      name5      
    24      name6       1:30               6                
    ---------------------------------------------------------

Так что это может быть обновлено пользователем для каждой годовой недели. Сначала я подумал о group_concat , но из-за производительности я использую обычную группу по запросу.


Примечание: для определенного идентификатора задачи и рабочей даты будет только одна запись в часах. Я почти построил интерфейс. Пожалуйста, помогите мне получить все идентификаторы задач, как указано выше, даже если нет записи. Нужно ли использовать подзапрос.

Ответы [ 2 ]

1 голос
/ 17 января 2010

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

так:

SELECT *
FROM tasks t
LEFT JOIN taskentries te
ON t.id = te.id

это то же утверждение, что и:

SELECT *
FROM tasksentries te
RIGHT JOIN tasks t
ON te.id = t.id

даст вам все задачи, даже если нет задачи

внутреннее объединение выберет строки только тогда, когда в обеих таблицах есть строки, левое объединение выберет все строки из левой (первой) таблицы и совпадение из другой строки (если такой строки нет, значение NULL будет равно все столбцы). правое объединение сделает противоположное: выберите все строки из правой (второй) таблицы и сопоставьте слева.

a LEFT JOIN b совпадает с b RIGHT JOIN a

0 голосов
/ 20 января 2010

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

SELECT Final.TaskId, 
       Final.TaskName, 
       Tmp.HoursSpent AS TotalHours, 
       Tmp.WorkedDate
    FROM (
        SELECT A.TaskId, B.TaskName, A.EmpNum
        FROM TaskAllocations A
                 INNER JOIN 
                 Tasks B 
            ON ( A.TaskId = B.TaskId ) 
        WHERE a.empnum = "333"
        )Final
    LEFT OUTER JOIN (
            SELECT New.TaskId, New.EmpNum, New.WorkedDate, New.HoursSpent
        FROM TaskEntries New
        WHERE New.WorkedDate
        IN 
              ('2010-01-17','2010-01-18','2010-01-19',
              '2010-01-20','2010-01-21','2010-01-22','2010-01-23' )
        OR New.WorkedDate IS NULL 
        AND New.EmpNum = "333"
        )Tmp 
    ON Tmp.TaskId = Final.TaskId
AND Tmp.EmpNum = Final.EmpNum
    ORDER BY Final.TaskId, Tmp.WorkedDate ASC ;

Первый мой запрос в вопросе не работал, так как я помещал условие в столбец правой таблицы при выполнении левого внешнего соединения. Спасибо всем за поддержку.

...