Ответы пользователя по тегу SQL
  • Как вывести id?

    @alexalexes
    1. Вычисляете агрегированную выборку - подзапрос A.
    2. Сортируете выборку в том порядке, как собираетесь нумеровать - подзарос B.
    3. Нумеруете строки доступной функцией в конкретной СУБД (в Oracle это rownum, в остальных средах есть row_number, в MySQL 5 версии нужно делать костыль из пользовательской переменной @ и if-a).
    select rownum, B.*
    from (select A.*
                from (SELECT v.user_id,
                      u.nickname,
                     COUNT(DISTINCT v.meme_id) as meme_count
                    FROM views as v
                       join  users u on u.id = v.user_id
                   GROUP BY v.user_id, u.nickname) A
            order by A.meme_count desc) B
    Ответ написан
  • Как сделать категории в интернет магазине?

    @alexalexes
    Пишется один рекурсивный запрос одного из видов (или оба вида, чтобы два раза не вставать).
    1) Получения списка детей, если известны параметры родителя (до определенного уровня, с пропуском неважных уровней).
    2) Получения списка предков (до определенного уровня, с пропуском неважных уровней), если известны параметры ребенка.
    Выносите эти запросы в секцию with, даете им понятные псевдонимы.
    Далее ниже по тексту пишите уже привычные запросы, используя эти псевдонимы, словно это view или кеш-таблицы.

    PS: Если иерархическая выборка нужна в подзапросе, и она зависит от изменяемых в ходе выборки входных параметров ребенка/родителя, то тут нужно выносить 1 и 2 в хранимые функции, где результат функции будет табличный курсор. При использовании результата этого курсора, обычно, делают преобразование результата функции в тип "таблица" через выражения cast.
    Ответ написан
    Комментировать
  • Что такое выражение в SQL?

    @alexalexes
    Выражение, это значит, что в месте между, например, select и запятой может не только выбираться значение столбца (выполняться тривиальное действие):
    select col1, -- извлекли содержимое колонки - вполне тривиальное действие
               col2 from table1

    Но выполнятся более функциональное действие, требующее от планировщика запросов разобрать что-то, что находится до селекта и запятой (почему что-то? - это и есть выражение))) ):
    select (col1 + col2) * 10 as result, -- а тут уже применили ариф. операции - написали выражение
               col2 from table1

    В аргументах функции вы можете передавать не только значения, которые содержатся в колонках, но и как-то предварительно их вычислять с помощью арифметики, склеивания строк, преобразования типа, выбора логического варианта с помощью case, вставлять другую функцию и т.д.
    Ответ написан
    Комментировать
  • Как сделать логи изменения отдельной таблицы в MariaDB?

    @alexalexes
    Стандартная практика ведения истории изменения данных таблицы.
    Вешаете триггер по операциям UPDATE, INSERT, DELETE перед их выполнением (опция before) на интересуемую таблицу и вставляете данные из атрибутов old.* триггера в таблицу истории.
    Таблица истории:
    history_id - идент. записи истории
    next_history_id - идент. следующей записи истории в пределах одной записи отслеживаемой таблицы (у последней он null)
    oper_type - тип операции (UPDATE, INSERT, DELETE - можно числами записать)
    old.* - все атрибуты таблицы, значения до выполнения операции.
    new.* - все атрибуты таблицы, которые пытались внести операциями UPDATE или INSERT. Этот набор нужен, если вы следите за историей на транзакциях, которые были откатаны назад (неудачные попытки). В этом случае, в триггере нужно указать специальную опцию, чтобы он работал в режиме автономной транзакции.
    При внесении новой записи истории, в предыдущей записи по такому же первичному ключу отслеживаемой таблицы нужно добавлять next_history_id от history_id новой записи.
    Таким образом в отслеживаемой таблице будет актуальное состояние записи, а в таблице истории - цепочка изменений записей.
    По каждому первичному ключу записи отслеживаемой таблицы можно построить цепочку изменений по history_id и next_history_id.
    А по next_history_id is null можно быстро получить последнее изменение из этой цепочки.
    Естественно, к этим полям нужно добавить индексы.
    Ответ написан
    Комментировать
  • Как реализовать получение уникального айди из базы данных?

    @alexalexes
    Ну, insert вы для себя открыли.

    я хотел сделать отдельный параметр в бд, который проверяется

    посмотрите, как пользоваться select-ом, да еще с входными параметрами, чтобы извлечь строку.

    заменить в ней значение,

    Ищем как пользоваться запросом c update, да еще с параметрами.
    PS: Если еще посмотрите, как пользоваться delete, то CRUD комплект вы изучили, как взаимодействовать с базой.
    PPS: cursor после выполнения insert может содержать свойство last insert id, но это не точно.
    Ответ написан
    Комментировать
  • Как правильно организовать таблицы?

    @alexalexes
    1. Сделать правильную таблицу Client с полем год.
    2. Создать индекс на поле год.
    3. Сделать импорт из таблиц Client_ГОД в таблицу Client с указанием поля года.
    4. Переписать запросы, чтобы присутствовала таблица Client в контексте нужного года (выборка с параметром год).
    5. Если очень нужно ограничить выборку по нужному году (по соображениям разграничения прав), то для определенных запросов сделать view по нужному году, выдать права на view для определенного пользователя.
    Ответ написан
    Комментировать
  • Как получить timestamp,обрезав пустое время?

    @alexalexes
    komino, это проблема разработчика, а не конфига драйвера СУБД, как он будет интерпретировать значение даты в конкретном запросе, если ему не подходит статичный шаблон nls_date_format. Такой шаблон не имеет в себе лексического интерпретатора, способного выполнять условные операторы.
    Решение:
    select
    -- вариант 1
    to_char(sysdate, 'DD.MM.YYYY' || decode(sysdate - trunc(sysdate), 0, '', ' HH24:MI:SS')) as your_format_date_1, 
    -- вариант 2
    case
      when sysdate - trunc(sysdate) > 0
      then to_char(sysdate, 'DD.MM.YYYY HH24:MI:SS')
      else to_char(sysdate, 'DD.MM.YYYY')
    end as your_format_date_2
    from dual;
    Ответ написан
  • Почему sql запрос не определяет имя таблицы, если записывать имя через prepare?

    @alexalexes
    1. В качестве входных параметров никогда не использовались имена таблиц в подготовленных запросах - это попытка забивать микроскопом гвозди.
    2. Метки для входных параметров - это не тип данных, это просто название места куда будет подставлено значение этой метки по ключу из массива значений.
    Причем, именованные метки нужно связывать со значением с помощью специальной функции:
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = :metka_parametra_identifikatora");
    $stmt->bindParam(':metka_parametra_identifikatora', 123);
    $stmt->execute();

    Но можно не использовать именованные метки (если их несколько в запросе, то нужно вставлять значения по порядку)
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = ?");
    $stmt->execute([123]);

    Можно использовать связывающую функцию, указав порядок метки.
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = ?");
    $stmt->bindParam(1, 123); // 1 - это номер метки, 123 - значение параметра
    $stmt->execute();
    Ответ написан
    Комментировать
  • Есть ли бесплатное API для получения всех улиц и домов конкретного города?

    @alexalexes
    https://fias.nalog.ru/Updates
    Тут есть полный архив адресов и разностные файлы на определенную дату.
    Ответ написан
    Комментировать
  • Подсчёт кол-ва детей у сотрудников access?

    @alexalexes
    Подскажите пожалуйста - в каком направлении думать.

    Подтянуть знания:
    1. Псевдонимы таблиц и полей в SQL.
    2. Соединения таблиц (join, left/right/cross join).
    3. Использование группировок в выборке.
    4. Агрегирующие функции (count, max, min и т.д.).
    В перспективе:
    5. Оконные функции.
    6. Подзапросы для получения скалярного значения (используется в секции select или в where)
    7. Подзапросы в секции from
    Select w.`Код`, w.`Фамилия`, w.`Имя`, w.`Отчество`, 
               count(ch.*) as Child_Count -- кол-во детей
               -- count(distinct ch.`Фамилия`, ch.`Имя`, ch.`Отчество`, ch.`Дата рождения`) as Child_Count -- кол-во детей по группе уникальных полей по таблице Дети, без использования идентификатора
    from `Список` w
    join `Дети` ch on ch.`КодСотрудника`  = w.`Код`
    group by w.`Код`, w.`Фамилия`, w.`Имя`, w.`Отчество`
    Ответ написан
  • Как правильно составить запрс с двумя INNER JOIN?

    @alexalexes
    Очевидно, что нужны алиасы к таблицам, особенно к тем, которые несколько раз присоединяются.
    select psc.*, 
      pt1.`value` as `picture`, 
      pt2.`value` as `sort_pos`
     from `pref_site_content` as psc
        inner join `pref_site_tmplvar_contentvalues` as pt1 on pt1.`contentid` = psc.`id` and pt1.`tmplvarid` = 37 
        inner join `pref_site_tmplvar_contentvalues` as pt2 on pt2.`contentid` = psc.`id` and pt2.`tmplvarid` = 111 
        where psc.`id` not in (898, 899, 900, 902)
           and (`template` = 40 and `published` = 1) -- тут, возможно, тоже можно добавить, если в таблицах поля одинаково названы
    Ответ написан
  • Как внутри echo или переменной выполнить цикл и ещё одно echo?

    @alexalexes
    // Вы определитесь:
    $table = /* либо копите результат верстки в переменной table, а потом после обработки выводите все содержимое на строке N */
     '
        <tr>
        <td>'. $trtd .'</td> //отрисовывает первым столбиком таблицы номер сотрудника в таблице бд
        <td>'. $array[0]++ .'</td> //отрисовывает вторым столбиком таблицы имя сотрудника в таблице бд
        '. // зачем тут перед for конкатенация ?
    
    for ($td=1; $td<=$daysinmonth; $td++){
    // Либо сразу выводите результат через echo, не накапливая ничего для вывода контента
    echo '<td>тут какое-то значение, в будующем должен быть код с операторами if и т.д.</td>';}.' //отрисосывает оставшиеся столбцы в зависимости от кол-ва дней в месяце
        </tr>';// если вы множите ячейки дней месяца, то наверное, строку таблицы нужно закрывать не в теле цикла?
      /*строка N */  echo ($table); // вывод всего накопленного содержимого

    Оператор .= вам в помощь, чтобы добавить еще что-то к $table.
    Ответ написан
  • Как получить строки с большими значениями?

    @alexalexes
    Как мне получить 12 строчек,

    применить в запросе клаузу limit

    по убывающей значения numberofVisits


    применить в запросе клаузу order by с опцией desc по данному полу выборки.
    Ответ написан
    Комментировать
  • Как мне составить правильный SQL запрос?

    @alexalexes
    SELECT  *
    FROM  multfilms as m
    where m.title like '%Шрек%'
    union
    SELECT  *
    FROM  multserials as m
    where m.title like '%Шрек%'

    union будет работать, при условии, что выборках одинаковое кол-во колонок и данные в них одинакового типа.

    Но вообще, если вы под каждый тип контента создаете новую таблицу с почти однотипными атрибутами - значит, это признак того, что вы делаете ошибку проектирования с точки зрения архитектуры реляционных баз.
    Правильно сделать так:
    Сделать таблицу типа фильма по контенту:
    film_content_type
    С атрибутами:
    id - идент. типа
    full_name - полное название типа контента (фильм, мультфильм, сериал и т.д.)
    ... другие атрибуты типа фильма.

    И у вас будет единственная таблица с фильмами:
    films
    атрибуты
    id - идент. фильма
    content_type_id - тип фильмового контента (внешний ключ к таблице film_content_type)
    title - Название фильма
    ... другие атрибуты фильма

    Тогда запрос будет такой:
    SELECT  f.*, 
           t.full_name
    FROM  films f
    join film_content_type t on t.id = f.content_type_id
    where f.title like '%Шрек%'

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

    @alexalexes
    Ничего не понятно. Но из того, что привели в примере и проговорили словами можно слепить это:
    $table = Model::selectRaw('title, name_list, count(*) as count, sum(count_model * 2) as total, min(created_at) AS date') // в выбираемые поля нужно добавить title - вы же хотите его извлечь?
                ->groupBy('title, name_list') // сюда нужно прописать группируемые поля, которые не участвуют в агрегирующих функциях count, sum, min и т.д.
                ->orderBy('name_list', 'DESC') // тут пишите поле, по которому сортируете, ASC или DESC - направления сортировки
                ->take(10)
                ->get();
    Ответ написан
  • Как изменить данные в SQL таблице?

    @alexalexes
    Используйте подготовленные запросы, чтобы вставлять параметры в текст запроса.
    $stmt = mysqli_prepare($link, 'UPDATE your_table SET name = ? where ID = ?');
    mysqli_stmt_bind_param($stmt, 'si', $name, $id);
    mysqli_stmt_execute($stmt);
    echo "строк изменено: ".mysqli_stmt_affected_rows($stmt);
    Ответ написан
    Комментировать
  • Как сформировать json из двух запросов SQL?

    @alexalexes
    Вся проблема в том, что таблица clients_groups не нормализована до третьей нормальной формы. У вас атрибут id_clients пытается вобрать несколько значений, что неприменимо при по пытках построить запросы, где будет фигурировать связка с id_client к другим таблицам.
    Чтобы данной структурой можно было пользоваться, нужно провести такую нормализацию:
    Таблица groups:
    id_group - идентификатор группы
    name_group - наименование группы
    Таблица clients_groups - предназначена для формирования связи многим-ко-многим (связывает множественными связями справочник клиентов со справочником групп):
    id - идентификатор связи
    id_group - идентификатор группы
    id_client - идентификатор клиента
    Тогда такая структура будет иметь следующее содержание:
    Таблица groups:
    id_group, name_group
    1, 'Головна'
    2, 'Менеджер'
    Таблица clients_groups:
    id, id_group, id_client
    1, 1, 2
    2, 2, 2
    3, 2, 3
    Построение запроса:
    select g.id_group, cg.id_client, g.group_name
    from groups as g
    join clients_groups as cg on g.id_group = cg.id_group

    Далее собрать выборку в NodeJS, объединив по группам клиентов и перекодировать результат в JSON.
    Ответ написан
    Комментировать
  • Подзапросы. Сколько разных товаров заказывал каждый покупатель (по ФИО) в 1995 году?

    @alexalexes
    Вы просто не освоили group by. Те поля (или хитровычисляемые значения), которые не получены при помощи агрегированных функций, используемые в select и требуют группировки, нужно прописать в group by.
    Чтобы count считал уникальные значения по конечной выборке, не по числу строк, в него прописывают поле или выражение, которое будет определять, как идентифицировать уникальную часть выборки.
    SELECT O.CustomerID, C.ContactName, Count(distinct Od.ProductID) as Product_Unique_Count
                FROM Orders as O
                join Custimers as C on O.CustomerID = C.CustomerID
                join [Order Details] as Od on Od.OrderID = O.OrderID
                WHERE YEAR(O.OrderDate) = 1995
    group by O.CustomerID, C.ContactName
    Ответ написан
    1 комментарий
  • Есть ли программа, сервис, модуль для Excel, Calc для копирования из электронной таблицы в SQL?

    @alexalexes
    У вас очень специфичные требования к функционалу Excel. Все таки excel-файлы - это просто еще один вид получения отчета от информационной системы (в ИС входит как специализированный софт, так и СУБД - где структура базы спроектирована не просто набором таблиц, а именно по функциональным особенностям предметной области). Такие файлы не обязаны обладать внутренним функционалом импорта и экспорта данных, это просто выгрузка данных по какому-то информационному срезу. Excel хоть и имеет возможность выполнять вычисления по полям, но не надо возлагать на него то, что должен делать тот самый софт, которого у вас нет.
    Однако, MS Office имеет возможность добавлять в свои документы макросы. На макросах можно сделать то, что вы хотите. Но при каждом изменении вида экспорта и импорта вам придется привлекать программиста, чтобы поправил код макроса.
    Ответ написан
  • Как отсортировать товары по числу, если тип опций текстовое и с плавающей запятой?

    @alexalexes
    Попробуйте обойти экранирование перекодированием числа в нужный символ.
    &sortby = `{"CAST(replace(option_01,',',char(46)) AS DECIMAL(13,3))": "ASC"}`
    Ответ написан
    1 комментарий