Сценарий Mysql - получить все задачи, даже если нет записи?

0

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

  • Tasks со столбцами Taskid, Taskname
  • TaskAllocations со столбцами Taskid, EmpNum
  • TaskEntries со столбцами TaskId, EmpNum, WorkedDate, Hoursspent

Теперь я хочу получить все записи задач в течение определенной недели. Здесь моя проблема даже в том случае, если для конкретной задачи нет Taskentry, я должен получить по крайней мере строку с этим TaskId, а Taskname с 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, но из-за производительности я использую обычную группу по запросу.


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

Теги:
group-by
database-design
left-join

2 ответа

0
Лучший ответ

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

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 ;

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

1

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

так:

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

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

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

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

  • 0
    Да, я сделал то же самое .. использовал левое внешнее соединение. но мне нужно было внутреннее соединение на другом столе. так три таблицы с одним левым и одним внутренним соединением
  • 0
    зачем вам нужно внутреннее соединение, если вы видите, что оно не работает? если вы выполняете внутреннее объединение задач и серий задач (как в примере с кодом), вы получите строки только тогда, когда есть задача и запись в ней. вам нужны все задачи, даже те, которые не имеют записи, поэтому не используйте внутреннее соединение.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню