Ответы пользователя по тегу MySQL
  • Как найти дни рождения в json наборе?

    @alexalexes
    Лучше детей писать в отдельную таблицу.
    А если очень хочется, то только так колхозить:
    -- MySQL
    select u.user_id, child_bdays.bday
      from user u,
            JSON_TABLE(u.children, '$[*]' COLUMNS (
                    bday VARCHAR(10)  PATH '$'
             )) child_bdays
           where STR_TO_DATE(child_bdays.bday, "%Y-%m-%d") >= DATE(now() - INTERVAL 7 DAY)
             and STR_TO_DATE(child_bdays.bday, "%Y-%m-%d") <= DATE(now() + INTERVAL 7 DAY);
    
    -- MariaDB
    select u.user_id, JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')) as bday
      from user u,
         (select 0 idx union select 1 union select 2 union
          select 3 union select 4 union select 5 union
          select 6 union select 7 union select 8 union
          select 9 union select 10 union select 11) idx_table /* впомогательная выборка для генерации индексов в диапазоне 0...11 */
      where idx_table.idx < json_length(u.children) /* отсекаем обращения к несуществующим индексам элементов в JSON*/
        and STR_TO_DATE(JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')), "%Y-%m-%d") >= DATE(now() - INTERVAL 7 DAY)
        and STR_TO_DATE(JSON_EXTRACT(u.children, concat('$[', idx_table.idx, ']')), "%Y-%m-%d") <= DATE(now() + INTERVAL 7 DAY)
    Ответ написан
  • Как взять значение с определенного поля и изменить другое определенное поле на данные из первого поля?

    @alexalexes
    Как говорите, так и составляйте запрос в SQL.
    update определенная_таблица т1
    set т1.определенное_поле_2 = т1.определенное_поле_1
    where т1.определенное_поле_x = опреленное_значение -- использовать опционально для конкретных записей
    Ответ написан
  • Как заполнить столбец с foreign key?

    @alexalexes
    Это делается апдейтом с подзапросами.
    update table tb
          set tb.type_id = (select tp.id from types tp where tp.name = tb.type_name limit 1) -- выбираем подзапросом id из справочника по совпадению наименования поля в обновляемой таблице
     where tb.type_id is null -- страховка, что будем обновлять не установленные значения
         and exists(select 1 from types tp where tp.name = tb.type_name) -- будем ставить ключ, если есть наименование в справочнике types

    PS: Прежде чем выполнять update, убедитесь при помощи select с тем же where, что вы вставите нужные для вас значения в поля секции set. По принципу поговорки: "Семь раз select-ни - один раз update-ни".
    PPS: Желательно, избегать ситуаций, когда вам периодически нужно нормализовывать структуру данных, в идеале, при insert-е нужно сразу определять ключик, а поле наименования использовать только тогда, когда нужного наименования нет в справочнике.
    Ответ написан
  • Почему Удаляются записи из БД, ООП, php?

    @alexalexes
    ... на глобальном сбой.

    Вероятно, нужно докопаться до текста ошибки, чтобы понять, в чем дело?
    Но можно предположить, что от места выполнения у вас чувствительна вот эта строчка:
    $this->go_to_back_one_stap = explode('.ru', $_SERVER['HTTP_REFERER']);

    Выведите в отладочный файл значение $_SERVER['HTTP_REFERER'] на боевом окружении и посмотрите, то ли вы ожидаете в ней значение, чтобы разделить ее по '.ru' и взять элемент с индексом 1.
    Ответ написан
  • Можно ли работать двумя программами с одной базой данных?

    @alexalexes

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

    Основываясь на этом комментарии, могу сказать, что вам нужно познакомиться с теорией: шаблоном проектирования "Планировщик"
    и системы на основе очереди задач.
    Помимо "двух программ", в вашем случае это воркеры (исполнители), в вашей системе должен еще присутствовать планировщик, имеющий приоритет над воркерами, который будет формировать задачи.
    Назначать задачи исполнителям может как планировщик, так и сами исполнители.
    Каждая задача должна иметь идентификатор, статус выполнения, назначенный исполнитель, а также перечень объектов, которые должен обработать исполнитель. Как раз перечень объектов и будет ограничивать работу одного исполнителя, чтобы они "не лезли на одни и те же записи в таблицах".
    Конечно, нужно познакомиться с транзакциями и уровнями блокировки таблиц - это только часть инструментов реализации системы, но без планировщика вам не обойтись.
    Ответ написан
    Комментировать
  • Почему слетела кодировка и как всё исправить?

    @alexalexes
    Укажите перед выводом данных в php, в какой кодировке собираетесь его делать.
    header('Content-Type: text/html; charset=utf8', true);
    Ответ написан
  • Как избежать явного первичного ключа?

    @alexalexes
    Можно сделать локальный id истории, уникальный в пределах одного контакта.
    Получается, будет уникальный id контакта + id истории. Вы емкость одного идентификатора размажете на два.
    Сортировать можно, находить нужную запись истории можно. Какая запись истории появилась раньше у соседних контактов - скорее всего нельзя выяснить, если нет сквозного id.
    На первый взгляд такие возможности и недостатки.
    Ответ написан
  • При выборке двух таблиц с БД одним запросом, на выводе получаются дубликаты. В чем может быть проблема?

    @alexalexes
    Если просто нужен флаг, что товар в корзине, то достаточно этого запроса.
    SELECT p.*,
                case
                   when exists(SELECT 1 from cart c where c.products_id = p.id)
                   then 1
                   else 0
                end is_exists_in_cart -- есть товар к корзине? 0 - нет, 1 - есть
    FROM table_products p

    Если нужны параметры товара, а не только его наличие, то как минимум будет такая конструкция:
    SELECT p.*, c.*
    FROM table_products p
    left join cart c on c.products_id = p.id

    PS: Конструкция запроса может сильно меняться от того, какие свойства вам нужно извлечь, чтобы вывести в итоговую выборку.
    Ответ написан
    Комментировать
  • Как мне с одной базы с таблицы скопировать в другую базу таблицы?

    @alexalexes
    1. Используете импорт/экспорт базы/таблиц в каком-нибудь инструменте, например, phpmyadmin.
    или
    2. Пишете скрипт с двумя коннектами. По первому коннекту делаете порционную выборку, по второму - вставляете результат выборки из первого коннекта.
    Ответ написан
    Комментировать
  • Как исправить ошибку при добавлении строки phpmyadmin?

    @alexalexes
    Ограничения по внешним ключам прямо говорят о том, чтобы по идентификаторам player_id и категории в справочниках players и categories существовали нужные записи, но и сами идентификаторы были того же типа данных, что и первичные ключи справочников.
    Ответ написан
  • Как написать SQL запрос для данного случая?

    @alexalexes
    Сначала обновите записи в таблице checkanaliz:
    update  checkanaliz set id_napravlenie = 1 where id_napravlenie = 2

    Потом удалите из таблицы napravlenie записи:
    delete from napravlenie where id = 2
    Это же элементарные действия, которые вам доступны в SQL.
    Ответ написан
  • Как вывести не id элемента, а слово, которое к нему привязано?

    @alexalexes
    После этой строчки:
    $countryN->execute([':id' => $countries_id]);
    ... вам нужно применить один из методов:
    $rows = $countryN->fetchAll();
    var_dump($rows);

    или
    $row = $countryN->fetch();
    var_dump($row);

    Почитать тут и тут.
    Вкратце, работа с базой идет по таким этапам:
    1) Подключение к БД (хост, логин пароль и тд)
    1.1) Обработка ошибок подключения
    2) Передача параметров кодировки, форматов даты/время, локали и тд
    3) Подготовка запроса (prepare функция)
    3.1) Обработка синтаксических ошибок текста запроса.
    4) Подготовка входных и выходных параметров запроса (bind функция)
    4.1) Обработка ошибок параметров (результат возврата значения bind функции).
    5) Выполнение (execute функция).
    5.1) Обработка ошибок выполнения (обычно, смотрят состояние возврата значения execute функции).
    6) Выборка результата (фетчинг, используем fetch-функции).
    *) https://www.php.net/manual/ru/pdo.errorinfo.php получение состояния ошибки на любом этапе.
    Ответ написан
    Комментировать
  • Как составить SQL запрос?

    @alexalexes
    Зачем вам таблица t1?
    У продукта могут быть несколько родителей?
    Если нет, то t1 избыточна, вам будет достаточно в каждой записи продукта указывать, кто у нее parent.
    Если нужно найти самый дешевый продукт в пределах одного родителя, то делается это так:
    select *
    from (select parent, product,
                        rank() over (partition by parent order by price) price_rnk
               from t2
             )  a
    where price_rnk = 1

    Клауза over partition поддерживается mySQL не ниже 8 версии. Самым распространенным версиям (5 или 6, не помню), нужно делать велосипед из пользовательских переменных @.
    Ответ написан
    1 комментарий
  • Можно ли сохранить последовательность вывода полей?

    @alexalexes
    Все таки сделайте динамически формируемым данные об интервалах, то есть inters можно представить в виде таблицы или генерировать на основе prepod.
    Для "нет данных" можно определить интервал [null, null]:
    select case
             when a.begin is null and a.end is null then 'нет данных'
             when a.begin is not null and a.end is not null then concat(a.end, '-', a.begin)
             when a.begin is null and a.end is not null then concat('ранее ', a.end + 1)
             when a.begin is not null and a.end is null then concat('от ', a.begin)
           end interval_str,
           cnt
    from
    (
    select inters.begin, inters.end, count(prepod.name) cnt
    from
    (
      select null begin, 1969 end union all
      select 1970 begin, 1979 end union all
      select 1980 begin, 1989 end union all
      select 1990 begin, 1999 end union all
      select 2000 begin, null end union all
      select null begin, null end -- запись для тех, у кого нет данных др.
    ) inters -- таблица с интервалами
    left join 
    (
      select 'a' name, STR_TO_DATE('2013-02-11', '%Y-%m-%d') date_r union all
      select 'aa' name, STR_TO_DATE('2010-09-01', '%Y-%m-%d') date_r union all
      select 'b' name, STR_TO_DATE('1968-02-11', '%Y-%m-%d') date_r union all
      select 'bb' name, STR_TO_DATE('1969-01-21', '%Y-%m-%d') date_r union all
      select 'c' name, STR_TO_DATE('1980-02-11', '%Y-%m-%d') date_r union all
      select 'd' name, STR_TO_DATE('1989-02-11', '%Y-%m-%d') date_r union all
      select 'z' name,  null date_r -- препод, у которого нет данных др.
    ) prepod on inters.begin <= year(prepod.date_r) and inters.end >= year(prepod.date_r)
             or inters.begin is null and inters.end >= year(prepod.date_r)
             or inters.begin <= year(prepod.date_r) and inters.end is null
             or prepod.date_r is null and inters.begin is null and inters.end is null
    group by inters.begin, inters.end
    order by inters.begin desc, inters.end desc
    ) a
    Ответ написан
    4 комментария
  • Как разделить число на 100 и прибавить получившейся результат к сумме которую делим?

    @alexalexes
    Если округлять центы в пользу пользователя, то:
    UPDATE dle_users
    SET user_balance = user_balance + round(user_balance / 100.0, 2)

    Если округлять центы в пользу системы, то:
    UPDATE dle_users
    SET user_balance = user_balance + ceil(user_balance / 100.0 * 100) / 100.0
                                                                    ^       ^
                                              корректировка ceil по 2 знакам после запятой
    Ответ написан
    1 комментарий
  • Как проще всего сделать выборку количества каждого типа?

    @alexalexes
    У вас практически готово решение, только отвязать привязку user_id в подзапросах, если вам нужно получить общее кол-во записей по типам из таблицы example.
    SELECT count(e.id) "кол-во записей example со статусом 1",
           (
               select count(type_id)
               from example e_1
               where type_id = 1
                  and e_1.status = 3
           ) "кол-во для типа 1",
           (
               select count(type_id)
               from example e_3
               where type_id = 3
                  and e_3.status = 3
           ) "кол-во для типа 3",
           (
               select count(type_id)
               from example e_4
               where type_id = 4 
                and e_4.status = 3
           ) "кол-во для типа 4"
    FROM example e
    WHERE e.status = 1
         and e.user_id = 53;

    Если получаемая статистика в пределах одного пользователя, то можно использовать такую конструкцию:
    SELECT count(e.id) "кол-во записей example со статусом 1",
                 count(case when e.type_id = 1
                  and e.status = 3 then 1 end)  "кол-во для типа 1",
           count(case when e.type_id = 3
                  and e.status = 3 then 1 end)  "кол-во для типа 3",
         count(case when e.type_id = 4
                  and e.status = 3 then 1 end)  "кол-во для типа 4"
    FROM example e
    WHERE e.status = 1
         and e.user_id = 53;

    Вариант 3.
    SELECT count(case when e.status = 1 then 1 end) "кол-во записей example со статусом 1",
                 count(case when e.type_id = 1
                  and e.status = 3 then 1 end)  "кол-во для типа 1",
           count(case when e.type_id = 3
                  and e.status = 3 then 1 end)  "кол-во для типа 3",
         count(case when e.type_id = 4
                  and e.status = 3 then 1 end)  "кол-во для типа 4"
    FROM example e
    where e.user_id = 53

    Вариант 4.
    -- Считаем статус 1, игнорируем типы
    SELECT 'with_status_1' type_query, null type_id, count(*) cnt
    FROM example e
    where e.status = 1
    and e.user_id = 53
    union all
    -- Считаем остальные типы со статусом 3
    SELECT 'with_another_types' type_query, e.type_id, count(*) cnt
    FROM example e
    where e.status = 3
    and e.user_id = 53
    group by e.type_id
    Ответ написан
    5 комментариев
  • Как применить INNER JOIN к результату запроса?

    @alexalexes
    Было бы с чем соединять...
    SET @var = 4;
    
    Select * from
    (
    -------------Ваш сложный подзапрос --------------------
    SELECT *
    FROM menu
    WHERE FIND_IN_SET(ID,(SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
    SELECT @pv:=(SELECT GROUP_CONCAT(ID SEPARATOR ',')
    FROM menu WHERE submenu IN (@pv)) AS lv FROM menu
    JOIN (SELECT @pv:=@var)tmp
    WHERE submenu IN (@pv)) a))
    
    UNION ALL
    SELECT *
    FROM menu
    WHERE ID = @var
    ORDER BY ID
    -------конец сложного подзапроса--------------
    ) complicated_menu
    inner join ваша_таблица vt on complicated_menu.id = vt.id
    Ответ написан
    1 комментарий
  • OpenWRT+PHP7 "Ошибка Call to undefined function mysqli_connect()" не понимаю что делать?

    @alexalexes
    Поиск по OpenWRT ресурсам говорит, что, возможно, проблема в конкретной сборке OpenWRT.
    Попробуйте воспользоваться советом:
    Try this. Check /etc/php7/

    Rename 20_mysqli.ini to 30_mysqli.ini, or delete 20_mysqli.ini if both exist. If you also have 20_openssl.ini there, rename that to 10_openssl.ini.
    Above change is needed to load the modules in the correct order.
    This should now be fixed in the latest builds, but you could be running older code, or suffering from the bug that was there earlier.
    Ответ написан
    1 комментарий
  • Как правильно преобразовать text в дату?

    @alexalexes
    Используйте STR_TO_DATE() вместо DATE_FORMAT, атрибута DOC_TIME это тоже касается.
    PS: Использование этого поля без функции преобразования для операций сравнения не имеет смысла. В этом преступление предыдущего разработчика, выбравшего не тот тип данных.
    Ответ написан
    Комментировать
  • Как сделать выборку в сгруппированном формате?

    @alexalexes
    Я отвечал на подобный вопрос.
    Как произвести правельную выборку статей со всеми тегами?
    В вашем случае посты превращаются в группы, а теги - в занятия групп.
    Ответ написан
    Комментировать