2016-06-29 2 views
0

Я стараюсь управлять командой доставки. Поэтому я хочу отобразить таблицу. Первая строка будет завершена днем. И следующие строки будут заполнены состояниями и их продолжительностью. Строка «дата» должна содержать все дни месяца. Даже если никто не работает.SQL ACCESS - Left Join? Просмотреть все дни месяца

- First table (typeState) - 
deliveryStatusDuration //State Time (seconds) INTEGER 
deliveryStatus //Type Status     INTEGER 
startStatus //Start of the state    DATE 
endStatus //End of the state     DATE 
deliveryCarNum //deliverer identifier   INTEGER 


- Second table (dateTable) - 
dateInt // Just an integer (from 1 to 31)  INTEGER 

My SQL запрос:

SELECT SUM(deliveryStatusDuration) AS DURATION, deliveryStatus, datetable.dateInt 
FROM datetable      
LEFT JOIN typeState ON datetable.dateInt = DAY(typeState.startStatus) 
WHERE deliveryCarNum = :CarNum AND 
startStatus >= :DateStart AND 
endStatus <= :DateEnd AND 
(
typeState.startStatus Is Null OR 
typeState.deliveryStatus Is Null OR 
datetable.dateInt <= DAY(:DateEnd) 
) 
GROUP BY datetable.dateInt, deliveryStatus 

Я знаю, что он должен изменить "Left Join", но я не вижу, каким образом?

Цель, независимо от месяца: 1 2 3 4 5 6 7 8 9 ... [последний день месяца] ................... .................................................. ......... enter image description here

enter image description here

+1

вход и выход образцов было бы очень полезно здесь. «Изображение стоит тысячи слов», безусловно, верно для SO SQL-вопросов. –

+0

Я использую SQL в FastReport, знаете ли вы? – DataCube

ответ

0
SELECT SUM(BB.deliveryStatusDuration) AS DURATION, BB.deliveryStatus,  
AA.dateInt 
FROM 

(select dateInt FROM datetable) AA LEFT JOIN 

(SELECT startStatus, deliveryStatus, deliveryStatusDuration FROM typeState WHERE deliveryCarNum = :CarNum AND 
    startStatus >= :DateStart AND 
    endStatus <= :DateEnd 
) BB ON AA.dateInt = DAY(BB.startStatus) WHERE 
1=1 AND (
BB.startStatus Is Null OR 
BB.deliveryStatus Is Null OR 
AA.dateInt <= DAY(:DateEnd)) 


GROUP BY AA.dateInt, BB.deliveryStatus ORDER BY AA.dateInt 
+0

Мне не нужно было создавать даты, потому что у меня есть таблица дат – DataCube

+0

, которая представляет собой только целочисленное значение, содержащее таблицу. Вам нужно создать даты из этой таблицы, используя любой запрос, например 'concat (1, month(), Year())' и увеличивать его по одному. ИЛИ вы можете использовать динамическое создание даты, когда все даты генерируются – Riad

+0

Но это работа с Integer. Проблема заключается в следующем: если вы возьмете таблицу в моей теме, результат будет равен: 1,2,4,12 Но я хочу 1,2,3,4,5,6,7,8,9,10,11 , 12, 13 .... 31 – DataCube

0

я должен был сделать что-то похожее на это и придумал 2 варианта;

Вариант 1

Вы не можете создавать даты в Excel, как «2016-01-01» до требуемой даты и сбросить эти значения в таблицу DateDefinition. Затем вы можете присоединиться к вашему запросу с этой таблицей.

Вариант 2

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

Declare @todate datetime, @fromdate datetime 
 
Select @fromdate='2016-01-01', @todate='2016-12-31' 
 
    
 
;With DateSequence(Date) as 
 
(
 
    Select @fromdate as Date 
 
     union all 
 
    Select dateadd(day, 1, Date) 
 
     from DateSequence 
 
     where Date < @todate 
 
) 
 
    
 
--select result 
 
Select * from DateSequence option (MaxRecursion 1000)

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

UPDATE 1

Для плаката; можете ли вы проверить, работает ли следующее?

SELECT SUM(deliveryStatusDuration) AS DURATION, deliveryStatus, datetable.dateInt 
 
FROM datetable      
 
LEFT JOIN typeState ON datetable.dateInt = DAY(typeState.startStatus) 
 
WHERE deliveryCarNum = :CarNum AND 
 
(
 
startStatus >= :DateStart AND 
 
endStatus <= :DateEnd AND 
 
datetable.dateInt <= DAY(:DateEnd) 
 
) 
 
GROUP BY datetable.dateInt, deliveryStatus

Надеется, что это помогает

+0

У меня есть таблица дат «dateTable» (1,2,3,4,5 .... 31) – DataCube

+0

Ваша таблица дат просто целые числа от 1 до 31. Вы не должны реализовывать его таким образом, потому что не все месяцы имеют одинаковое количество дней. Вы также должны учитывать високосные годы. –

+0

Как и в предложении WHERE, вы определили две даты, ваше соединение работает только для дат, найденных в таблице typestate. Предложение WHERE должно содержать только ссылку на datetable –

0

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

SELECT SUM(deliveryStatusDuration) AS DURATION, 
 
\t deliveryStatus, 
 
\t datetable.dateInt 
 
FROM datetable      
 
LEFT JOIN typeState ON 
 
\t datetable.dateInt = DAY(typeState.startStatus) 
 
\t AND typeState.deliveryCarNum=:CarNum 
 
\t AND (
 
\t \t \t typeState.startStatus Is Null OR 
 
\t \t \t typeState.deliveryStatus Is Null OR 
 
\t \t \t datetable.dateInt <= DAY(:DateEnd) 
 
\t \t) 
 
\t AND 
 
\t \t typeState.startStatus >= :DateStart 
 
\t AND 
 
\t \t typeState.endStatus >= :DateEnd 
 
GROUP BY datetable.dateInt, deliveryStatus 
 
ORDER BY dateInt

+0

Благодарим за помощь .. У меня ошибка «неподдерживаемого объединения» – DataCube

+0

Какой механизм базы данных вы работаете? –

+0

Я ошибся с одним из имен столбцов. Обновлен мой ответ. Вы можете проверить еще раз? –