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


    надо что бы при запросе вывел где status= true, и count_id = количество id за 30 дней.
    |id|id_2|name|status|date| count_id |


    • количество записей считается COUNT при группировке по полям (см. GROUP BY), в данном случае по интервалу дат

    • но... в таком виде
      |id|id_2|name|status|date| count_id |
      вывести не получится! т.к. группировать по полям |id|id_2|name| не имеет смысла, они могут быть уникальны и никакого COUNT за интервал не получится, например как считать количество в интервале для id=1,2,3 ... ??? это группироваться никак не будет вообще, будет выводиться построчно для каждого id и количество будет Всегда равно =1 и так для всех id. определитесь что вам надо?! конкретно

    • можно выбрать записи со статусом true и посчитать количество в интервале, для этого поле date привести в некий интервальный формат, либо если надо за ПОСЛЕДНИЕ 30 дней, то просто:
      SELECT count(id) count_id
        FROM tbl
        WHERE status = 'true'
          AND date >= now() - interval 30 day
      ;




    см. пример на dbfiddle
    Ответ написан
  • Как сделать, чтобы дата отображалась количеством часов в БД?

    если предположить, что переменная типа DATETIME, то примерно так:

    -- дата начала
    DECLARE @t_start AS DATETIME = DATEADD(minute, -7410, GETDATE());
    -- дата конца
    DECLARE @t_finish AS DATETIME = GETDATE();
    -- разница между датами начала и конца в переменной типа DATETIME
    DECLARE @t_diff AS DATETIME = @t_finish - @t_start;
    
    -- разница между датами начала и конца
    SELECT @t_diff;
    
    SELECT DATEDIFF(second, DATEFROMPARTS(1900,1,1), @t_diff) / 3600.0 AS diff_h


    см. https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=9...
    Ответ написан
  • Как построить sql запрос?

    как-то так...

    SELECT
        c.title,
        ou.name,
        m.text,
        FROM_UNIXTIME(m.date) AS dt
      FROM chat_users cu
      INNER JOIN chat_users cuu ON cuu.chat_id = cu.chat_id AND cuu.user_id != cu.user_id
      INNER JOIN users ou ON ou.id = cuu.user_id
      INNER JOIN chat c ON c.id = cu.chat_id
      INNER JOIN messages m ON m.user_id = cuu.user_id AND m.chat_id = cu.chat_id
      WHERE cu.user_id = :ID_USER  -- ID пользователя по которому выбирать чаты.
      ORDER BY c.title ASC, m.date DESC
    Ответ написан
  • Как найти ошибку sql из лога MODX?

    Откройте файл /home/site.ru/core/xpdo/om/xpdoobject.class.php строка 240
    и посмотрите что там за запрос такой, который ошибку выдает.
    хотя это наврено PDO шный класс? хм... ну хотя бы посмотреть какой там объект/метод вызывается
    и в коде искать вызов этого места.

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

    Melkij , дело говорит )
    см. PostgreSQL CHECK Constraint

    ALTER TABLE persons 
       ADD CONSTRAINT persons_check_rols CHECK (rols in('registrator', 'coordinator', 'user'));
    Ответ написан
  • Как следует изменить запрос чтобы при выборке всех записей подзапрос возвращал по одному значению для каждого кортежа?

    Подзапрос который вставляется в список колонок должен возрващать только ОДНУ строку.
    либо перепишите подзапрос, чтобы он в любом случае возвращал только одну строку, либо джойните его или таблицу.
    Кроме того этот подзапрос никак не привязан к таблицам выборки ?? так и задуманно?

    какая вообще связь между таблицами, что это за таблицы? какой должен быть результат выборки?

    Вангую, что должно быть примерно так:

    SELECT
         w.Id
        ,w.IMO
        ,v.Name
        ,w.loginManager
        ,um.Name AS managerName
        ,w.loginStorekeeper
        ,umk.Name AS storekeeperName
        ,w.Date 
      FROM Waybill w
      INNER JOIN Vessel v ON w.IMO = v.IMO
      INNER JOIN User um  ON w.loginManager = um.Login
      INNER JOIN User umk ON w.loginStorekeeper = umk.Login
      ORDER BY w.Id
    Ответ написан
  • Избыточные данные или сложная логика запроса?

    Одни и те же вопросы с разных аккаунтов??

    я так понимаю что это тоже самое или суть аналогична: Получить строку с максимальным совпадением? ??
    вместо `movie_desc` - `setting_value` (смотри ниже запрос и примеры)

    через оконные функции надо делать, если на MySQL 8 (СУБД вы НЕ указали...), функция ранжирования - row_number()

    -- здесь я вынес параметры (домены, языки) в отдельное представление param,
    -- которое определяется перед SELECT
    -- это сделано, для того чтобы по всему запросу не искать и вписывать их
    -- меняется все в одном месте:
    WITH param AS (
      SELECT
          2 AS primary_domain_id,    -- id первичного домена
          1 AS secondary_domain_id,  -- id вторичного домена
          2 AS primary_language_id,  -- id первичного языка
          1 AS secondary_language_id -- id вторичного языка
        FROM dual
    )
    SELECT *
      FROM (
        SELECT m.*,
            row_number() over (
              partition by m.movie_id
              order by
              	case
              	  when m.domain_id = p.primary_domain_id then 100
              	  when m.domain_id = p.secondary_domain_id then 50
              	  else 1
                end DESC,
              	case
              	  when m.language_id = p.primary_language_id then 100
              	  when m.language_id = p.secondary_language_id then 50
              	  else 1
                end DESC
            ) rn
          FROM `movie_desc` m, param p
          WHERE (m.domain_id = p.primary_domain_id
              OR m.domain_id = p.secondary_domain_id
              OR m.domain_id IS NULL)
    	    AND (m.language_id = p.primary_language_id
              OR m.language_id = p.secondary_language_id
              OR m.language_id IS NULL)
      ) t
      WHERE t.rn = 1
    ;


    Примеры на:
    https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f46bf1...
    https://www.db-fiddle.com/f/8UigbxU6uNg6guU8ygKgrA/1

    PS: если MySQL более древний чем 8й, то попробуйте переписать как описано на второй странице той же статьи , ссылка на которую приведена выше.
    www.sql-tutorial.ru/ru/book_row_number_function/pa...
    Ответ написан
  • Как вытащить данные при вложенном запросе?

    У вас таблица oc_product внутри подзапроса, поэтому сначала нужно вывести там, а уже потом "сверху":

    SELECT
        name,
        sku,
        CONCAT('https://домен/', IF(ua2.keyword IS NULL,'',CONCAT(ua2.keyword, '/')), IF(ua3.keyword IS NULL,'',CONCAT(ua3.keyword, '/')), IF(ua4.keyword IS NULL,'',CONCAT(ua4.keyword, '/')), ua1.keyword) AS url
      FROM (
        SELECT
            name,
            p.sku,
            CONCAT( 'product_id=', p.product_id ) AS product_query,
            CONCAT( 'category_id=', pc.category_id ) AS category_query,
            CONCAT( 'series_id=', ps.series_id ) AS series_query,
            CONCAT( 'subcategory_id=', psc.subcategory_id ) AS subcategory_query
          FROM `oc_product_description` pd
          LEFT JOIN oc_product p ON (p.product_id=pd.product_id)
          LEFT JOIN oc_product_to_category pc ON (pc.product_id=p.product_id)
          LEFT JOIN oc_product_to_series ps ON (ps.product_id=p.product_id)
          LEFT JOIN oc_product_to_subcategory psc ON (psc.product_id=p.product_id)
          WHERE p.date_available <= NOW()
            AND p.status = '1'
      ) pd
      LEFT JOIN oc_url_alias ua1 ON ( pd.`product_query` = ua1.`query` )
      LEFT JOIN oc_url_alias ua2 ON ( pd.`category_query` = ua2.`query` )
      LEFT JOIN oc_url_alias ua3 ON ( pd.`series_query` = ua3.`query` )
      LEFT JOIN oc_url_alias ua4 ON ( pd.`subcategory_query` = ua4.`query` )
    ;


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

    Потому что у вас не задан альяс колонки для подзапроса
    (SELECT DISTINCT(Name) AS storekeeperName FROM User, Waybill WHERE (Waybill.loginStorekeeper = User.login))


    укажите альяс через AS

    например:
    SELECT
        Waybill.Id, Waybill.IMO, Vessel.Name, Waybill.loginManager, User.Name, Waybill.loginStorekeeper,
        (SELECT DISTINCT(Name) AS storekeeperName FROM User, Waybill WHERE (Waybill.loginStorekeeper = User.login))  AS storekeeperName,
        Waybill.Date 
      FROM Waybill, Vessel, User 
      WHERE (Waybill.IMO = Vessel.IMO)
        AND (Waybill.loginManager = User.Login)
        AND (Waybill.loginManager = User.Login)
      ORDER BY Waybill.Id


    PS: скобки в условии не обязательны и без них сначала выполняется оператор = а затем AND
    Ответ написан
  • Запрос по двум таблицам PostgresSQL?

    SELECT id FROM (
      SELECT id FROM tbl1
      UNION
      SELECT id FROM tbl2 WHERE is_active = 1
    ) WHERE id = SOME_ID
    Ответ написан
  • Как получить данные из 2 таблиц по разным условиям?

    SELECT *
      FROM setting_salue sv
      JOIN setting s ON s.id = sv.setting_id
      WHERE (sv.domain_id = DOMAIN_ID OR sv.domain_id IS NULL)
        AND (sv.language_id = LANG_ID OR sv.language_id IS NULL)
    Ответ написан
  • Как найти телефон в sql с помощью match against?

    UPD:
    немного неверно написал ранее, т.к. это поиск по части номера, то естественно надо LIKE
    $sql = "SELECT * FROM tbl WHERE replace(replace(replace(replace(phone,'(',''),')',''),' ',''),'-','') LIKE concat(replace(replace(replace(replace('".$num."','(',''),')',''),' ',''),'-',''), '%')";


    UPD2:
    PS:
    Не совсем понимаю как это реализовать с помощь полнотекстового поиска.

    а зачем вообще реализовывать это с помощью полнотекстового поиска??
    если номер телефона хранится в отдельном поле, в определенном формате?
    1. либо приводите обе стороны "искомого" к одному формату (т.е. удаляете все лишнее) как например выше.
    2. либо, если номера в базе хранятся в одном формате приводите искомый (вводимый) номер к формату хранения в базе + знак % и поиск LIKE
    3. либо делаете поиск через REGEXP соответствующим образом формируя рег.выражение из PHP
      но это несколько сложнее, надо ее динамически формировать в зависимости от введенных цифр.
      вот регулярка для проверки телефона практически в любом варианте написания:
      ^\+?7[ -]?\(?\d{3}\)?[ -]?\d{3}[ -]?\d{2}[ -]?\d{2}$

      под MySQL сами перепишите... см. ссылку выше, там другие классы символов.
    4. либо, если все же таки нужен полнотекстовый поиск, то искомое значение НЕОБХОДИМО приводить к формату в базе и искать отформатированное значение
    Ответ написан
  • Как исправить ошибку при выводе из 2-х таблиц?

    1. а если INNER JOIN ?

    SELECT `zadachi`.id AS id_zadacha,`zadachi`.*,`users`.* 
      FROM `zadachi`
      INNER JOIN `users` ON `users`.id_1c = `zadachi`.autor
      WHERE `zadachi`.komy = '$id' OR (`zadachi`.autor = '$id' AND `zadachi`.komy = '$id') 
      ORDER BY `zadachi`.id DESC


    2.
    а: Группа новых задач...
    б: Группа просроченных задач...
    в: Группа поставленных задач кому то...


    3 запроса, объединить через UNION ALL
    типа
    SELECT 'NEW' as group, .... FROM ... 
    UNION ALL
    SELECT 'EXPIRED' as group, ... FROM ...
    UNION ALL
    SELECT 'OTHER' as group, ... FROM ...
    Ответ написан
  • Как вывести факт отсутствия данных?

    Необходимо в приложении заложить правильную логику, либо обработку количества записей, либо с эксепшн.
    а по вопросу - FULL OUTER JOIN
    -- выбираем несуществующую запись
    SELECT pt.pid, t.id, t.text FROM (SELECT 1 AS pid) pt
      FULL OUTER JOIN (
        SELECT 1 AS pid, tt.*
          FROM tbl tt
          -- условие запроса:
          WHERE tt.id = 10
      ) AS t ON pt.pid = t.pid
    ;

    см. пример на dbfiddle

    так же и LEFT OUTER JOIN, но условие по запросу ставить внутрь скобок ( ) в подзапрос, см dbfiddle:
    -- выбираем несуществующую запись
    SELECT pt.pid, t.id, t.text FROM (SELECT 1 AS pid) pt
      LEFT OUTER JOIN (
        SELECT 1 AS pid, tt.*
          FROM tbl tt
          -- условие запроса:
          WHERE tt.id = 10
      ) AS t ON pt.pid = t.pid
    ;


    можно еще UNION подзапроса с NULL , но он всегда будет вставляться.
    SELECT id, text FROM tbl
    WHERE id = 10
    UNION
    SELECT NULL, NULL
    ;


    пример там же, выше.
    Ответ написан
  • Как объединить подзапросы?

    erge
    @erge Автор вопроса
    PS: извиняюсь, поспешил, таки пропустил... по параметрам что выбрал, оба запроса были пустые.

    Все работает:

    SELECT
        DECODE(NVL(an.id,0), 0,ao.id, an.id) AS id,
        DECODE(NVL(an.id,0), 0,ao.dt_beg, an.dt_beg) AS dt_beg,
        DECODE(NVL(an.id,0), 0,ao.dt_end, an.dt_end) AS dt_end
      FROM
      (.....) ao
      FULL OUTER JOIN (.....) an ON ao.id = an.id
      WHERE (an.id is null OR ao.id is null)
        AND (ao.id = _NUMBER_ OR an.id = _NUMBER_)
    ;
    Ответ написан
  • Почему не редактируются данные в БД?

    первичный ключ, которым должен быть по идее id, у вас не указан как primary key, во все строках равен 0 - почему!?

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

    правда все строки у вас идентичные и их никак не различить...
    поэтому можно сделать так:

    set @i = 0;
    
    update `grey_csgo_gifts_list`
      set id = @i := @i + 1;
    
    alter table `grey_csgo_gifts_list` modify `id` int(11) auto_increment primary key;


    см. пример на dbfiddle
    Ответ написан
  • Два переноса строки и как написать update с использованием REPLACE sql?

    • зачем вы знак % вставляете?
      PS: знак % работает только в LIKE
    • строка должна заключаться в ' ' (одинарные кавычки), хотя для MySQL может это и не критично
    • вы точно хотите 3 тэга заменить на 1 ?
    • имхо, это вообще не критично - 2 переноса строки, или это требование по феншую? ))


    Все работает
    select
        replace(
           text
          ,CONCAT('</table>', CHAR(10), CHAR(10),'</li>',CHAR(10),'</ul>')
          , '</table>'
        ) as text
      from tbl;
    
    set @a = CONCAT('</table>', CHAR(10), CHAR(10),'</li>',CHAR(10),'</ul>');
    
    update tbl
      set text = replace(text, @a, '</table>');


    пример на sqlfiddle

    UPD:

    Solodukha,
    Если update не обрабатывает строки, это значит только одно:
    • что там переносы строк не CHR(10), либо посмотрите какие там переносы, либо попробуйте CHR(10), CHR(13) = Это один перенос строки (либо наоборот), либо еще как вариант, только CHR(13),
    • либо.. скорее всего после </table> или в тэгах есть побельные символы (пробел, табуляция и пр.) и/или "белые пробелы".


    (но нам то это неизвестно, данные у ВАС)


    Поэтому:
    • Либо разбор текста будет более сложный, необходимо строчными функциями искать table внутри li , сабстринг и пр. что как бы заморочно, оформлять это скорее всего хранимой процедурой.
    • Либо писать скрипт на чем угодно (bash, php, perl, python ... etc), выбирать записи и построчно: обрабатывать регуляркой, записывать обратно в бд.
    • Либо, ЕСЛИ у вас MySQL 8, все это можно сделать в БД, одним запросом используя REGEXP_REPLACE():

      примерно так:
      update tbl
        set text = REGEXP_REPLACE(
           text
          ,'<[[:blank:][:space:]]*\/table>[[:blank:][:space:]]+<[[:blank:][:space:]]*\/li>[[:blank:][:space:]]+<[[:blank:][:space:]]*\/ul>[[:blank:][:space:]]*'
          ,'</table>'
          )

      см. на dbfiddle



    другого, имхо, не дано...
    Ответ написан
  • Сортировка по просмотрам за день / неделю / месяц - как построить запрос?

    Примерно, как-то так, если не ошибаюсь:

    SELECT
          `ID`
        , `post_title`
        , pv30.cnt_month
        , COALESCE(pv7.cnt_week, 0) cnt_week
        , COALESCE(pv1.cnt_day, 0) cnt_day
      FROM `wp_posts` AS p
      INNER JOIN (
        SELECT id, count(id) cnt_month
          FROM `wp_post_views` pv
          WHERE pv.time >= CURDATE() - INTERVAL 30 DAY
          GROUP BY pv.id
        ) AS pv30
        ON pv30.id = p.id
      LEFT JOIN (
        SELECT id, count(id) cnt_week
          FROM `wp_post_views` pv
          WHERE pv.time >= CURDATE() - INTERVAL 7 DAY
          GROUP BY pv.id
        ) AS pv7
        ON pv7.id = p.id
      LEFT JOIN (
        SELECT id, count(id) cnt_day
          FROM `wp_post_views` pv
          WHERE pv.time >= CURDATE() - INTERVAL 1 DAY
          GROUP BY pv.id
        ) AS pv1
        ON pv1.id = p.id
      ORDER BY pv30.cnt_month DESC, pv7.cnt_week DESC, pv1.cnt_day DESC
      LIMIT 10;
    Ответ написан
  • Ошибка преобразования массовой загрузки данных?

    Importing data from a CSV file

    BULK INSERT LR1.dbo.Company
    FROM '\\Mac\Home\Descktop\DB\data\Company.txt'
    WITH (FORMAT = 'CSV'
          , FIRSTROW=1
          , FIELDTERMINATOR = ';'
          , ROWTERMINATOR = '0x0a');


    PS: так же попробуйте с , FIELDQUOTE = '\''
    хотя в этом случае кажется каждое значение должно быть в апострофах, а не только строки.

    Так же попробуйте указать CODEPAGE
    Ответ написан