Вставьте отсутствующую дату в указанный диапазон дат для пользователя - PullRequest
0 голосов
/ 19 июня 2019

У меня есть таблица tblprocesstimekeeping, которая содержит следующие данные:

enter image description here

Допустим, у меня есть диапазон дат 2019-05-01 - 2019-05-15

Я пытаюсь вставить отсутствующую дату между заданным диапазоном в данные tblprocesstimekeeping по empCompID.

Вот мойкод:

$begin = new DateTime('2019-05-01'); // Get Begin Date
$end = new DateTime('2019-05-15'); // Get End Date
$end = $end->modify( '+1 day' ); // Increment +1 Day

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end); // Get Date Range


foreach($daterange as $date){

    $dateNumber = $date->format("Y-m-d"); // counter date + 1 day

    //Select company access id and date from tblprocesstimekeeping
    $query = $this->db->query("SELECT * FROM tblprocesstimekeeping where companyAccessID = '$companyAccessID'");                
        foreach ($query->result() as $row){ 

            $empCompID = $row->empCompID;
            $date = $row->date;                     
            //echo $date .' = '. $empCompID.'<br>';

            if ($date == $dateNumber) {
                echo $date .' = '. $empCompID.' = GOOD <br>';
            } else{
                echo $dateNumber .' = '. $empCompID.' = NO DATA <br>';
            }




    }                   



}

Вывод должен быть:

2019-05-01 = 11007 - NO DATA
2019-05-01 = 20003 - NO DATA
2019-05-02 = 11007 - GOOD
2019-05-02 = 20003 - GOOD
2019-05-03 = 11007 - GOOD
2019-05-03 = 20003 - GOOD
2019-05-04 = 11007 - GOOD
2019-05-04 = 20003 - GOOD
2019-05-05 = 11007 - NO DATA
2019-05-05 = 20003 - NO DATA
2019-05-06 = 11007 - NO DATA
2019-05-06 = 20003 - GOOD
2019-05-07 = 11007 - GOOD
2019-05-07 = 20003 - GOOD
2019-05-08 = 11007 - GOOD
2019-05-08 = 20003 - GOOD
2019-05-09 = 11007 - GOOD
2019-05-09 = 20003 - GOOD
2019-05-10 = 11007 - GOOD
2019-05-10 = 20003 - GOOD
2019-05-11 = 11007 - GOOD
2019-05-11 = 20003 - GOOD
2019-05-12 = 11007 - NO DATA
2019-05-12 = 20003 - NO DATA
2019-05-13 = 11007 - NO DATA
2019-05-13 = 20003 - NO DATA
2019-05-14 = 11007 - GOOD
2019-05-14 = 20003 - GOOD
2019-05-15 = 11007 - GOOD
2019-05-15 = 20003 - GOOD

Но вместо этого я получаю этот вывод:

2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-01 = 11007 = NO DATA 
2019-05-01 = 20003 = NO DATA 
2019-05-02 = 11007 = GOOD 
2019-05-02 = 20003 = GOOD 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-02 = 11007 = NO DATA 
2019-05-02 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = GOOD 
2019-05-03 = 20003 = GOOD 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-03 = 11007 = NO DATA 
2019-05-03 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = GOOD 
2019-05-04 = 20003 = GOOD 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-04 = 11007 = NO DATA 
2019-05-04 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-05 = 11007 = NO DATA 
2019-05-05 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 20003 = GOOD 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-06 = 11007 = NO DATA 
2019-05-06 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = GOOD 
2019-05-07 = 20003 = GOOD 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-07 = 11007 = NO DATA 
2019-05-07 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = GOOD 
2019-05-08 = 20003 = GOOD 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-08 = 11007 = NO DATA 
2019-05-08 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = GOOD 
2019-05-09 = 20003 = GOOD 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-09 = 11007 = NO DATA 
2019-05-09 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = GOOD 
2019-05-10 = 20003 = GOOD 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-10 = 11007 = NO DATA 
2019-05-10 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = GOOD 
2019-05-11 = 20003 = GOOD 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-11 = 11007 = NO DATA 
2019-05-11 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-12 = 11007 = NO DATA 
2019-05-12 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-13 = 11007 = NO DATA 
2019-05-13 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-14 = 11007 = GOOD 
2019-05-14 = 20003 = GOOD 
2019-05-14 = 11007 = NO DATA 
2019-05-14 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = NO DATA 
2019-05-15 = 20003 = NO DATA 
2019-05-15 = 11007 = GOOD 
2019-05-15 = 20003 = GOOD 

РЕДАКТИРОВАТЬ:

ЕСЛИ я изменяю свой запрос на этот

SELECT * FROM tblprocesstimekeeping where companyAccessID = '$companyAccessID' and date='$dateNumber'

Он показывает только этот вывод:

2019-05-02 = 11007 = GOOD 
2019-05-02 = 20003 = GOOD 
2019-05-03 = 11007 = GOOD 
2019-05-03 = 20003 = GOOD 
2019-05-04 = 11007 = GOOD 
2019-05-04 = 20003 = GOOD 
2019-05-06 = 20003 = GOOD 
2019-05-07 = 11007 = GOOD 
2019-05-07 = 20003 = GOOD 
2019-05-08 = 11007 = GOOD 
2019-05-08 = 20003 = GOOD 
2019-05-09 = 11007 = GOOD 
2019-05-09 = 20003 = GOOD 
2019-05-10 = 11007 = GOOD 
2019-05-10 = 20003 = GOOD 
2019-05-11 = 11007 = GOOD 
2019-05-11 = 20003 = GOOD 
2019-05-14 = 11007 = GOOD 
2019-05-14 = 20003 = GOOD 
2019-05-15 = 11007 = GOOD 
2019-05-15 = 20003 = GOOD 

Пропущенная дата все еще не отображается ..

Ответы [ 3 ]

0 голосов
/ 19 июня 2019

Ваш алгоритм неверен. Поскольку вы не фильтруете данные таблицы по дате, для каждой даты в диапазоне дат вы выбираете все строки в таблице tblprocesstimekeeping и печатаете результат для всех них (поэтому у вас есть 21 строка для каждой даты).

Я не знаком с php, поэтому я не буду публиковать здесь код, но вот мои предпочтения:

Сначала нужно узнать идентификаторы сотрудников Вы можете получить их из базы данных с помощью этого запроса:

“select distinct empCompId from FROM tblprocesstimekeeping where companyAccessID = '$companyAccessID'" 

и сохранить их как-нибудь (возможно, в массиве)

затем, чтобы выполнить то, что вы хотите, вам нужно будет выполнить два цикла

// first iterate by date
foreach($daterange as $date)
  // then, for each date iterate by employee
    foreach($employees as $empId){
     // check existance on record
     If (exists on data base)
        Echo ‘good’
    else
        echo ‘nodata’

Для «проверки наличия в базе данных» вы можете просто изменить свой запрос, чтобы отфильтровать данные таблицы по дате и

$query = $this->db->query("SELECT * FROM tblprocesstimekeeping where companyAccessID = '$companyAccessID' and date='$dateNumber'
 "); 

Но вы должны иметь это в виду:

Вы делаете столько же последовательных вызовов в базу данных, сколько дат в вашем диапазоне дат.

Если это возможно, рассмотрим алгоритм, который делает только один вызов для данных и возвращает все данные от начала до конца вашего диапазона дат (до цикла foreach $ daterange) И вы просто фильтруете эти данные, чтобы проверить существование определенной даты в коде.

Если количество задействованных записей не так велико (здесь у вас всего 21), производительность с этим решением будет намного, намного лучше

0 голосов
/ 20 июня 2019

Я подумал о вашей проблеме и думаю, что у меня есть лучшее решение.

Создайте процедуру хранения (SP), чтобы сделать всю работу за вас.

Это создаст SP, который имеет параметры для передачи идентификатора компании, даты начала и окончания диапазона дат, который вы хотите отобразить, и возвращает желаемый результат (date, employeeid и флаг 'found', который возвращает 0 когда нет записи, нет таблицы tblprocesstimekeeping или 1, если она существует.

DELIMITER //

DROP PROCEDURE IF EXISTS myListing //

CREATE PROCEDURE myListing(companyId int, startdate date, endDate date)
BEGIN
  WITH RECURSIVE days(day) AS 
  (
    select startdate  UNION ALL 
    select DATE_ADD(day,INTERVAL 1 DAY) FROM days WHERE day<= endDate 
  )
  select days.day as date, Employees.Id as empCompId, case when Time.date IS NULL THEN 0 else 1 end as found
  FROM days
  cross join 
  (select distinct empCompId as Id from tblprocesstimekeeping where companyAccessID = companyId and date >= startdate and date <= endDate) AS Employees
  LEFT JOIN
  (select * from tblprocesstimekeeping where companyAccessID = companyId and date >= startdate and date <= endDate) AS Time on days.day = Time.date and Employees.Id = Time.empCompId
  order by days.day, Employees.Id;
END
//

DELIMITER ;

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

set @startdate  = '2019-05-01';
set @endDate  = '2019-05-15';
set @companyId = 1;

CALL myListing(@companyId, @startdate, @enddate);

Se DBfiddler здесь

0 голосов
/ 19 июня 2019

Вот ваша проблема: вы создаете строки в вашей таблице, которые не существуют.Для дня, которого нет в таблице, вы создаете строку, которая указывает на отсутствие строки в таблице.

Это делает эту проблему немного хитрой в подходе, который вы выбрали.Вы можете создать сложный запрос MYSQL для обработки этого или обработать его в PHP.

Лучший способ сделать это - проходить через всех пользователей и каждый день.

// List of all users to find
$users = ['11007', '20003'];

foreach ($daterange as $date) {
    // Get date in database format
    $dateNumber = $date->format("Y-m-d"); // counter date + 1 day

    // Go through all users
    foreach ($users as $user) {
        // Find all accesses for that user and day
        $query = $this->db->query("SELECT * FROM tblprocesstimekeeping WHERE companyAccessID = '$companyAccessID' AND empCompID = '$user' AND date = '$dateNumber'");

        // If there is a row, then paste it, otherwise past NO DATA
        if ($query->num_rows()) {
            echo $dateNumber.' = '.$user->id.' = GOOD <br>';
        } else {
            echo $dateNumber.' = '.$user->id.' = NO DATA <br>';
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...