Ответы пользователя по тегу SQL
  • Выборка из двух таблиц в SQL?

    @alexalexes
    Что-то про поля нет конкретики, в первом случае будет так.
    select t1.*, t2.*
     from table1 t1
      join table2 t2 on t2.field1 = t1.field1
                           and t2.field2 = t1.field2
                           and ... -- сравниваем все поля

    Во втором нужно вычитать:
    select t1.* from table1 t1
    UNION
    select t2.* from table2 t2
    MINUS
    select t1.*
     from table1 t1
      join table2 t2 on t2.field1 = t1.field1
                           and t2.field2 = t1.field2
                           and ... -- сравниваем все поля
    Ответ написан
    Комментировать
  • Взаимная замена в SQL?

    @alexalexes
    А почему нельзя использовать решение влоб?
    Проход по таблице всего лишь один раз происходит.
    UPDATE provodka p
     SET p.code = CASE
    when p.code = 20501 then 20502
    when p.code = 20502 then 20501
    else p.code
    END
    Ответ написан
    Комментировать
  • Как защищится от sql инекции без ооп в php?

    @alexalexes
    А причем тут боязнь ООП?
    В документации описаны, как прикрепить параметры к запросу как в объектно-ориентированном стиле, так и в процедурном. Реализовать общение с СУБД можно и в том, и в другом стиле, если речь идет про MySQl.
    php.net/manual/ru/mysqli-stmt.bind-param.php

    PS: Вы просто боитесь усваивать документацию, пробовать различные примеры реализации. Вот и все.
    Ответ написан
    3 комментария
  • Как организовать поиск в 5-и таблицах БД PostgreSQL?

    @alexalexes
    Обратите внимание на форму кавычек.
    Если используется " " - то переменные внутрь вставлять можно напрямую "text $search какой-то текст".
    Если ' ', то переменную можно только приклеить 'text ' . $search . ' какой-то текст'.
    Если текст - это текст запроса, то за вставку или приклеивание параметров напрямую разработчика надо ругать и бить.

    PS: Устаю напоминать, никогда не склеивайте параметры запроса с текстом запроса напрямую - это дверь для sql-инъекции!
    php.net/manual/ru/function.pg-query-params.php
    Ответ написан
    Комментировать
  • Как изменить значения в одной таблице, взяв значения из другой?

    @alexalexes
    А где первичные ключи в табличках?
    Вообще, если таблицы - некие копии друг друга, то обновления записей проворачивают как-то так.
    update tab1 t1, tab2 t2   // таблицы, участвующие в Update
    set  t1.key = ?                      // устанавливаем параметр key, только непонятно, что задаем
    where t1.id = t2.id          // соответствие записей по первичным ключам

    Если нужно сделать сложное обновление, сопоставив некую совокупность атрибутов, не привязываясь к ключам, то как-то так.
    update tab1 t1, tab2 t2   // таблицы, участвующие в Update
    set t1.key = ?                      // устанавливаем параметр key, только непонятно, что задаем
    where t1.SecondName = t2.SecondName // допустим, пусть будет обновление key у тех записей, у которых есть полное соответствие атрибутов.
       and t1.LastName = t2.LastName
      and t1.ThirdName = t2.ThirdName
    Ответ написан
    Комментировать
  • Как реализовать SQL запрос, выборка по дате?

    @alexalexes
    При этом достаю только те значения, которые имеют самый старший "ключ"

    Ваш запрос не выбирает "самым-самый", ваш запрос выбирает нечто с фиксированным параметром:

    WHERE tab2.dateMessage > 0 and tab1.indexObject = 11222

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

    @alexalexes
    Сможете воспроизвести Oracle выражение Rank() over (partition by ... order by ...) в MS SQL, то будет легко.
    select last_move.book_id, last_move.rack_id, last_move.board_id,  -- последнее местонахождение книги
               first_move.date_from, -- дата первого появления на складе
               last_move.date_to -- дата последнего перемещения
    from
    -- подзапрос, получаем первые записи появления каждой книги на складе
    (select *
       from (select t.*, rank() over (partition by t.book_id order by t.date_from) rnk
                  from table t)
    where rnk = 1) first_move
    
    join
    -- подзапрос, получаем последние записи перемещения каждой книги на складе
    (select *
       from (select t.*, rank() over (partition by t.book_id order by t.date_from DESC) rnk
                  from table t)
    where rnk = 1) last_move
    
    -- сопоставляем записи
    on first_move.book_id = last_move.book_id
    Ответ написан
    3 комментария
  • Запрос периода времени в течение дня?

    @alexalexes
    Если вам нужно дать номер интервала для каждой записи, то вот запрос.
    Потом используйте любую группировку и аналитику для расширения запроса, как вам удобно.
    SELECT t.event_date,             -- атрибут таблицы типа datetime, для которого определяем интервал, выведен для того, чтобы наблюдать за процессом отладки
    case                                                                         -- SQL-конструкция вида "case  when ... then ... else ... end", с помощью которой можно выводить не только конкретное значение атрибута, но и задавать условие, при котором конечное значение  результата будет вычисляться по-разному в пределах одной выбранной записи.
      when TIME_TO_SEC(t.event_date) >= inter.begin AND TIME_TO_SEC(t.event_date) <= inter.end                           -- если t.event_date, выраженное в суточных секундах, находится в отрезке [inter.begin,  inter.end], также выраженных в суточных секундах,...
      then floor((TIME_TO_SEC(t.event_date) - inter.begin) / inter.width)           -- ... то вычисляем количество полных  интервалов
      else null         -- иначе, если время не попадает в период отслеживания, то выводим "пусто", чтобы явно указать, что значение не находится в интересуемом периоде
    end as full_interval_number      -- кол-во прошедших полных интервалов, начинается с 0
    FROM table t,                     -- ваша таблица
        (select TIME_TO_SEC('09:00:00') as begin,            -- начало дневного периода
                TIME_TO_SEC('18:00:00') as end,                 -- конец дневного периода
                TIME_TO_SEC('00:15:00') as width                -- ширина интервала
         ) inter                    -- параметрический подзапрос, все настраиваемые константы в одном месте - удобно при отладке
    Ответ написан
  • Формирование запроса?

    @alexalexes
    А почему не сразу в запросе?
    SELECT *
       from (SELECT  servers.id,
                               servers.game,
                               servers.votes,
                               @n := @n + 1 AS rank
                     FROM servers, (SELECT @n := 0) r
              ORDER BY servers.votes DESC) a 
    where id = 3
    Ответ написан
    6 комментариев
  • Как составить запрос?

    @alexalexes
    Решить это можно только в процедурном контексте программирования при постобработки результатов запроса, например, на PHP.
    /*Функция преобразования выборки в матрицу */
    function get_matrix($rows)
    {
      // получаем все значения по id - измерению матрицы (строки матрицы)
     // можно сделать запросом select distinct id from table order by id
      foreach($rows as $row)
        $id_dem[$row['id']] = 1;
    
     // получаем все значения по date - измерению матрицы (столбцы матрицы)
     // можно сделать запросом select distinct date from table order by date
      foreach($rows as $row)
        $date_dem[$row['date']] = 1;
    
    $map = null;   // если нет значений размерности матрицы, то функция вернет null
    
    // получаем карту не-null значений - непустые ячейки матрицы
      foreach($rows as $row)
        $map[$row['id']][$row['date']] = $row['count'];
    
    // дополняем карту null значениями - получаем полноценную матрицу
      if(isset($id_dem) && isset($date_dem))
        foreach($id_dem as $id => $val_id)
          foreach($date_dem as $date => $val_date)
            $map[$id][$date] = array_key_exists($id, $map) && array_key_exists($date, $map[$id])
                                 ? $map[$id][$date] : null;
       return $map;
    }
    Ответ написан
    Комментировать
  • Как правильно сформировать sql запрос при связи n:n?

    @alexalexes
    А в чем проблема?
    users - это одно множество;
    wallets - это другое множество;
    wallet_address - пересечение множеств (таблица с хордами [user_id, wallet_id]).
    Нужно просто склеить все таблицы по соответствующим ключам и вывести те записи из users, которые пересекаются с записями wallets с непустым value.
    select u.user_id, w.wallet_id, wa.value as address
      from users u
       join wallet_address wa on wa.user_id = u.user_id
       join wallets w on w.wallet_id = wa.wallet_id
    where wa.value is not null

    PS: А вы уверены, что адрес кошелька должен определяться по комбинации [user_id, wallet_id], это разве не самостоятельное свойство кошелька, то есть конкретной записи wallets?
    Если это так, то value будет относиться к wallets, а таблица wallet_address не будет иметь отношение к адресу, она просто будет хранить два внешних ключа user_id и wallet_id, чтобы выполнять исключительно функцию хранения хорд пересечений n:n.
    Ответ написан
  • Как можна сделать так чтоб если повторяются user_id то не добавить в count?

    @alexalexes
    Пока вы не сказали, что хотите посчитать, и на какой СУБД, количество от записей по уникальным user_id будет выглядеть примерно так:
    select count(*) as cnt
    from (select user_id
                from table
         group by user_id)

    Если нужно отобразить в выборке еще какие-то нюансы, то запрос кардинально изменится.
    Ответ написан
    Комментировать