Я пытаюсь создать список часов по компании и дате, даже если у компании нет данных на эту дату. Я пробовал LEFT JOINing к таблице Calendar и Grouping по ее датам, а затем Company, но безрезультатно.

SELECT cal.date, comp.name, comp.hours
FROM company AS comp
LEFT JOIN calendar AS cal ON cal.date=comp.date
GROUP BY cal.date, comp.name

Я ожидаю получить NULL, когда у Компании нет часов для этой даты, например:

2018-01-01   Company A   100
2018-01-01   Company B   NULL
2018-01-02   Company A   NULL
2018-01-02   Company B   NULL
2018-01-03   Company A   100
2018-01-03   Company B   50

Но он возвращает только те строки, в которых можно найти данные, как если бы я использовал INNER JOIN. Любая помощь будет оценена. Спасибо!

0
aks0020 8 Окт 2018 в 19:28

2 ответа

Лучший ответ

Вы сделали 3 ошибки, 2 из которых актуальны:

  1. Вы поменяли порядок таблиц в объединении (легко исправить)
  2. Ваш запрос не отражает заявленное вами намерение (сложнее исправить)
  3. Вы используете GROUP BY, когда в нем нет необходимости (несущественно в данном конкретном случае)

Я сосредоточусь на 2. Вы близки к своей цели, но не все. Исправляя первую и третью ошибки, вот ваш запрос:

SELECT cal.date, comp.name, comp.hours
FROM calendar AS cal
LEFT JOIN company AS comp ON cal.date=comp.date

Это будет делать что-то вроде следующего:

For each cal_row in calendar:
    For each comp_row in company:
        If cal_row.date equals comp_row.date:
            Create output row and append to output
    If no rows created:
        Create output row, fill with NULLs, and append to output

Таким образом, ваш запрос гарантирует не менее 1 выходной строки на дату. Вам нужна 1 строка вывода на дату для каждой компании . Один из способов сделать это - создать промежуточную таблицу и присоединиться к ней слева:

SELECT tbl.date, tbl.name, comp.hours
FROM (
    SELECT DISTINCT cal.date, comp.name
    FROM calendar AS cal
    CROSS JOIN company as comp
) AS tbl
LEFT JOIN LEFT JOIN company AS comp ON
    tbl.date = comp.date AND tbl.name= comp.name

http://sqlfiddle.com/#!9/517b4e/11/0

Это соответствует вашему желаемому результату.

0
shadowtalker 8 Окт 2018 в 17:23

Вы можете использовать календарь как левую таблицу, в этом случае вы получите всю дату

SELECT cal.date, comp.name, comp.hours
FROM calendar  AS cal  
LEFT JOIN company AS comp ON cal.date=comp.date

Я не нашел никакой агрегатной функции, поэтому удалил группу

0
Zaynul Abadin Tuhin 8 Окт 2018 в 17:19