<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55
global $wpdb2;
global $failure;
global $file_hist;
///// echo '<H2><b>Старт загрузки</b></H2><br>';
$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
///// echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
{ foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\
Основная сложность присвоить порядковый номер в запросе. Интересное решение через свое поле Ключ, но этот вариант применим, если есть такие поля, по которым можно его посчитать. Если просто передавать в запрос только список чисел, то так сделать уже не получится.
Ради интереса написал запрос, который выполняет нумерацию заданных значений. В нем есть заранее установленное ограничение на максимальное количество одинаковых чисел (в примере 256).
Показать
(1) NeviD, Согласен. Если мы ищем медиану числового ряда, написанного на бумаге или отрисованного на мониторе, то каждый элемент уникален хотя бы своим физическим расположением на носителе (бумага, монитор), даже если содержит одинаковые значения. Поэтому не прокатит
Сильно важно это понимать.
Вариант с ключом применим в принципе всегда. Просто иногда придётся содержать служебные таблицы (регистр сведений, например) с полями: «Объект», «Ключ». Тип объекта составной, тип ключа — число. ok.
Вместо ЦеныНоменклатуры.Регистратор.Дата лучше использовать ЦеныНоменклатуры.Период, быстрее будет.
(3) bulpi, верно, упустил! Благодарю, поправил
Да, интересный ход! Плюсую.
Идея составления ключа интересная, работающая. Тот же прием (сложение числа из периода со значением) используется, например, при решении задачи 4 в статьеМинимализмы .
Но в этой задаче, кажется, легче было разделить записи при равенстве цены дополнительной проверкой, то есть записать условие в виде
Вообще, если цен много, то запрос получится (из-за использования знака неравества) трудоемким. Простого решения этой проблемы в общем случае нет, но вот если бы номенклатура была единственной, то медиану цены можно было бы найти таким приемом: записать таблицу N/2 пустых записей ПЕРЕД таблицей цен, а затем выбрать ПОСЛЕДНЮЮ 1 ИЗ ПЕРВЫХ N записей.
Для иллюстрации приведу текст запроса, с которым можно поэкспериментировать в консоли. В зависимости от переданного в запрос номера он выбирает соответствующую запись из НЕПРОНУМЕРОВАННОЙ таблицы Дано:
Показать
В свое время рассчитал медиану средствами СКД…, может кому этот путь покажется проще..
но тут есть ограничение… обязательная сортировка по параметру для которого считается медиана
Статья на тему …
Статистическая обработка информации в SQL
(6) Проще Выбрать максимум из n/2 первых, отсортированных по возрастанию, ничего не добавляя в исходные данные
Но Вот Вопрос — как выбрать первые n/2 записей, если это значение не известно?
В чистом SQL для этого можно было бы воспользоваться процедурой sp_executesql
(10) Ovrfox, понятно, что первые n/2 решают эту задачу. Динамическое построение запроса в 1С тоже поможет.
Я предложил добавить искусственную таблицу перед основной, чтобы запрос не переформировывать, чтобы можно было твердо написать ПЕРВЫЕ 256, например.
Записал сюда как идею, чтобы ее не забыть. Для меня это пример приема использования искусственных таблиц в запросах.
Задача с медианой не очень жизненная. Другой задачи на этот прием пока в голову не приходит. Может, задача и найдется со временем. А прием уже вот, готовый.
Если бы задача с медианой действительно была актуальной, ее можно было бы быстро решить (в запросе) последовательным делением пополам, но это — из пушки по воробьям.
(11) Почитал (9) и прозрел.
Тема старая, но может кто-то ответит. А как посчитать 25,75 и любые другие перцентили по массиву непоименованных значений?
(13)https://infostart.ru/public/1157774/