Задать вопрос
  • Как сделать умный поиск по базе?

    @Akina
    Сетевой и системный админ, SQL-программист.
    А если будем просто через LIKE то придет вот так (так не нужно): Иван, Ваня, Ивановы...

    Нет. Отбор записей и их сортировка - две совершенно независимые операции.
    SELECT word 
    FROM words 
    WHERE word LIKE '%$search%'
    ORDER BY LOCATE($search, word), word
    Ответ написан
    Комментировать
  • Doctrine как получить расхождение двух запросов?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Делаю так:
    SELECT * FROM tbl1 EXCEPT SELECT * FROM tbl2

    Структуры таблиц совпадают?

    Тогда
    SELECT t1.*
    FROM tbl1
    LEFT JOIN tbl2 ON tbl1.primary_key = tbl2.primary_key
    WHERE t2.primary_key IS NULL

    Это должно без проблем отображаться на синтаксис фреймворка.
    Ответ написан
  • Как спомощью SQL(oracle) отсортировать записи по статусу?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT * 
    FROM test
    ORDER BY CASE status WHEN 'cancelled'
                         THEN 1
                         ELSE 2
                         END;

    https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=30ad...
    Ответ написан
    Комментировать
  • Как защититься от двойного списания в многопоточном приложении?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Трата состоит из трех этапов. Чтение баланса пользователя, проверка хватает ли средств и собственно запись нового баланса.

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

    баланс юзера расчитывается на лету и не хранится в юзере. Расчитывсется на основе истории его пополнений/расходов.

    В этом случае - триггер, который посчитает актуальный баланс, проверит условие, и при недостатке средств сгенерирует ошибку. Хотя я бы всё же задумался о хранении актуального баланса, хотя бы на некий момент времени (скажем, на полночь, чтобы доподсчитывать только по операциям текущего дня, а не по всей истории). Редкие ошибки в нём, даже если их не удастся избежать, обойдутся дешевле, чем система, способная каждый раз считать баланс на лету и разводить конфликты.

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

    Как раз уровень изоляции. При правильно выбранном уровне хрен чего второй прочитает, пока первый не завершит свою транзакцию и не отпустит ресурсы.
    Ответ написан
    1 комментарий
  • Возможно ли win10 сделать приоритет Wi-Fi вместо Ethernet?

    @Akina
    Сетевой и системный админ, SQL-программист.
    при подключении провода подключение Wi-Fi автоматически гаснет.

    Что значит "гаснет"? физически отключается адаптер? логически отключается привязанный к нему сетевой интерфейс? Старайтесь использовать более вменяемые термины, Вы же технический специалист.

    Железка имеет DHCP, сразу выдаёт адрес

    Не только адрес, но и ещё горсть параметров, включая шлюз по умолчанию. При этом уже имеющийся немедленно получает увеличение метрики и перестаёт использоваться.

    Решение одно - после подключения кабеля удалить из таблицы маршрутизации оба дефолтных маршрута и заново добавить только один, нужный. Выполнять каждый раз после отключения/подключения/перезагрузки.

    Windows 10 игнорирует метрики, в зарубежных гайдах говорят "Перестала уважать метрики". Т.е. нет никакой разницы, если поставить "999" метрику на Ethernet и "1" на Wi-Fi

    Явная и откровенная глупость. Абсолютное непонимание того, что есть метрика интерфейса и как она влияет на маршрутизацию.
    Ответ написан
    5 комментариев
  • Поставить индексы на каждое поле?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если я на каждый столбец, который используется в WHERE добавлю одиночные индексы, не ухудшит ли это производительность?

    Абсолютно бессмысленное мероприятие - одна копия таблицы может использовать только один индекс. Так что надо делать композитные индексы. Немного - иначе просядут модифицирующие запросы, а композит может использоваться и по префиксу, и как покрывающий.

    пока не понятно, какие индексы нужны, а какие нет.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT b.`id`, b.`date`, l.`path` 
    FROM `buy` b
    INNER JOIN `em` e ON b.`em_id` = e.`id`
    INNER JOIN `ls` l ON FIND_IN_SET(l.`id`, b.`ls_id`)

    PS. Хранение данных в CSV - это денормализация, дурной тон, и вообще кривой переулок, ведущий прямо на поле с граблями...
    Ответ написан
    2 комментария
  • Запрос MySql. Как составить выборку из первой таблицы по нескольким параметрам из второй?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT ft.*, pt.*
    FROM fruit_table ft
    JOIN param_table pt ON ft.id=pt.id_fruit
    JOIN ( SELECT id_fruit
           FROM param_table
           WHERE id_param IN (10, 20)
           GROUP BY 1
           HAVING COUNT(DISTINCT id_param) = 2 ) ptx ON pt.id_param = ptx.id_param
    Ответ написан
    2 комментария
  • Как изменить свойства колонки, не удаляя текущие значения?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Целевое поле - вычисляемое. Значит, фраза "не удаляя её значения" по отношению к нему не имеет смысла. Даже если это поле - хранимое, а не виртуальное.
    Ответ написан
    Комментировать
  • Cортировка данных по вычислению из другой таблицы и постраничная выдача?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Нужно получать курс первого дня, для выбранного периода - first, и последнего дня - last. Чтобы высчитать разницу. После чего {last} - {first} = {Х}. И вот по этому {Х} делать сортировку выборки.

    Да запрос же тривиальный!
    SELECT DISTINCT 
           coin_uuid,
           FIRST_VALUE(price) OVER (PARTITION BY coin_uuid ORDER BY last_updated ASC) firstprice,
           FIRST_VALUE(price) OVER (PARTITION BY coin_uuid ORDER BY last_updated DESC) lastprice
    FROM exchange_rates
    ORDER BY coin_uuid, lastprice - firstprice
    Ответ написан
  • Сколько учетных записей должно быть у администратора?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Сколько учетных записей должно быть у администратора?

    У одного администратора должна быть одна учётная запись. Которая является членом кучи групп, и каждая из групп даёт минимально необходимый набор прав для выполнения вполне определённой функции/работы.

    Если администратору нужна вторая учётная запись, для одновременной работы с двумя записями, или учётная запись с некими ограниченными правами - он просто создаёт такую учётную запись, ограничивая срок её действия необходимым периодом времени, либо, если таковая уже существует, разблокирует её на нужный срок и при необходимости корректирует набор её прав включением в нужные группы либо исключением из ненужных групп.
    Ответ написан
    Комментировать
  • Насколько сложный пароль стоит иметь от БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Слишком абстрактный вопрос. И ответ такой же - возможно, имеет.

    Настоящий же ответ зависит от конкретных условий и списка потенциальных угроз, от которых следует защититься. Согласись, если это сервер домашней сети, не подключённый к Инету, то смыслу наворачивать на него суперсложный пароль - ноль. Если это непатченная ОС, торчащая голым задом в Инет, то тоже - ибо если хакнут, то скорее всего всю ОС, а сервер БД пойдёт просто за компанию.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Используем [NOT] EXISTS
    SELECT *
    FROM user_friend uf1
    WHERE [NOT] EXISTS ( SELECT NULL
                         FROM user_friend uf2
                         WHERE uf2.friend_user_id = uf1.user_id )

    При WHERE EXISTS выбираются пары друзей (записи, имеющие обратную пару), при WHERE NOT EXISTS - записи, не имеющие обратной пары.

    Если для записей, имеющих обратную, нужна только одна пара из двух - добавляем во WHERE внешнего запроса ещё одно условие AND friend_user_id > user_id.
    Ответ написан
    Комментировать
  • Восстановить таблицы в базе mysql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. Переместить файлы таблицы.
    2. Создать пустую таблицу, скопировав CREATE TABLE с другого сервера максимально близкой версии.
    3. DISCARD TABLESPACE.
    4. Заменить файлы на сохранённые.
    5. IMPORT TABLESPACE.

    Если какая-либо таблица не удаляется либо не создаётся - попробовать провести те же операции, перегрузив сервер в режиме отключенной безопасности.

    Если всё равно не получается - бэкапить всё, что бэкапится, после чего удалить сервер и поставить заново, затем вернуть бэкап. Бэкап базы MySQL предварительно внимательно просмотреть и вычистить оттуда всё, связанное с проблемными таблицами, в отдельные файлы. При необходимости - аккуратно восстанавливать и то, что убрано, но по одному запросу за раз, и хорошо подумав, какие это может повлечь последствия.
    Ответ написан
    Комментировать
  • Как производить переиндексацию в таблице SQLite?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вопрос - следствие абсолютного непонимания сути первичного индекса.

    Первичный индекс определяется в таблице для того, чтобы однозначно идентифицировать запись в течение всего времени жизни таблицы.

    Обрати особое внимание - в течение времени жизни именно таблицы. Не записи! То есть то, что запись удалена, ни на что не влияет - отсутствующее значение первичного индекса идентифицирует факт, что запись существовала, но была удалена.

    Если тебе очень нужна непрерывная нумерация записей - то для реализации этой функции следует создать дополнительное поле в таблице, и уже в нём заниматься нумерациями, перенумерациями и сжатиями. Или (что более правильно), рассчитывать такое значение непосредственно в запросе, в тот момент, когда это значение потребовалось. А с учётом того, что в подавляющем большинстве случаев на это значение никакой функции, кроме удобства просмотра, не возлагается, его можно вообще не считать. Как правило, средства отображения набора записей на клиенте имеют встроенную функцию нумерации записей по порядку - вот и пользуйся.
    Ответ написан
    Комментировать
  • Откуда в MySQL Workbench постоянно берется схема mydb и как от нее избавиться?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Очень мешает откуда-то самопроизвольно возникающая схема mydb, которую я не могу удалить.

    Проверьте свойства (подключения, профиля) - возможно, именно это имя БД указано как база по умолчанию. И добрый Workbench, чтобы не плеваться ошибками на несуществующую БД, просто создаёт её. Или БД по умолчанию вообще не указана, и Workbench вытаскивает это имя откуда-то из своего загашника с дефолтными значениями.

    таблицы стали создаваться именно в ней, а не в той схеме с которой я работаю

    Если при создании таблицы указано её имя с указанием имени БД (CREATE TABLE dbname.tablename ( .. );) - таблица будет создана именно в указанной БД. Если же имя БД не указать - таблица создаётся в текущей БД. Почему у Вас именно эта БД текущая, и почему Вы не меняете её перед созданием таблиц запросом USE - это именно к Вам вопросы, и именно Ваша вина в том, что таблицы создаются "не там".
    Ответ написан
    2 комментария
  • Как посчитать ФИО в колонках с неправильным порядком?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Пример реализации для MySQL 8+:
    WITH 
    cte1 AS ( SELECT id, col1 val FROM test UNION ALL 
              SELECT id, col2 FROM test UNION ALL
              SELECT id, col3 FROM test ),
    cte2 AS ( SELECT id, GROUP_CONCAT(val ORDER BY val) FIO
              FROM cte1 
              GROUP BY id )
    
    SELECT test.id, test.col1, test.col2, test.col3, GROUP_CONCAT(cte2_2.id) ids
    FROM test
    JOIN cte2 cte2_1 USING (id)
    JOIN cte2 cte2_2 USING (FIO)
    GROUP BY test.id, test.col1, test.col2, test.col3

    Вывод:

    id	col1		col2		col3		ids
    1	Иванов		Иван		Иванович	1,2
    2	Иван		Иванович	Иванов		1,2
    3	Петров		Сергей		Алексеевич	3,4,5
    4	Петров		Сергей		Алексеевич	3,4,5
    5	Сергей		Алексеевич	Петров		3,4,5
    DEMO

    Если нужна ещё и нормализация (т.е. строго в col1 сунуть фамилию, в col2 имя...) - наилучшим вариантом считаю загрузку справочников имён, отчеств и фамилий (вполне доступные справочники) и их использование для категорирования. 99% записей будут полностью обработаны по ним, а оставшийся десяток записей (где два или все три значения отсутствуют в справочниках) можно и вручную обработать, вернее, пополнить справочник, чтобы при втором запуске все 100% были распознаны и категорированы корректно.

    выполняться будет на MS SQL Server, версию не могу сказать.

    Для MS SQL вместо GROUP_CONCAT будет STRING_AGG(column) [WITHIN GROUP ( ORDER BY column)]. https://docs.microsoft.com/ru-ru/sql/t-sql/functio...
    Ответ написан
    3 комментария
  • Как получить количество записей перед определенной записью в mysql с сортировкой по полю varchar?

    @Akina
    Сетевой и системный админ, SQL-программист.
    мне надо сделать подсчет количества записей перед определенной записью.
    Но обязательно с сортировкой по полю varchar asc.

    SELECT COUNT(*)
    FROM table
    WHERE varchar_column <= @value_in_definite_row

    Или строгое неравенство, если саму "определённую запись" не учитывать.
    Ответ написан
    7 комментариев
  • Как вывести значение поля до выполнения UPDATE, вместе со значением после UPDATE?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Добавь в источник данных копию изменяемой таблицы, связанную по первичному ключу или иному уникальному полю/выражению, и оттуда возьми исходное значение.

    DEMO
    Ответ написан
    Комментировать
  • Обращение к записи БД требует некоторой обработки. Что лучше: обработать в скрипте, который обратился, или в хранимой процедуре в БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    что эффективнее: хранить в записи список id объектов, которые должны быть обработаны при обращении к этой записи, в виде строки (скрипт будет парсить строку и отрабатывать каждый id), либо сделать триггер и хранимую процедуру (MySQL), которая возьмёт эту работу на себя?

    Ни то ни другое.

    Если тебе нужна канава, и есть экскаватор, то взять из его ремнабора лопату и ей копать канаву - голимая дурь. Это что касается обработки в скрипте - сервере БД сделает то же на порядок быстрее и эффективнее.

    Но есть ещё косяк - в том, как хранятся данные. Упаковка набора данных в одну запись в виде CSV-списка - это тоже дурь в подавляющем большинстве случаев. Умные люди не зря придумали нормальные формы, которые позволяют обрабатывать данные максимально эффективным образом.

    Вот и займитесь - почитайте про нормализацию, нормализуйте схему БД. А потом обрабатывайте данные на сервере как надо. В большинстве случаев оказывается, что супер-пупер-сложная обработка сводится на самом деле к одному не сильно сложному запросу.

    Насчёт триггера - сильно сомнительно, что он нужен. Триггер - это реакция на изменение данных, тогда как, судя по описанию, сигналом на обработку будет явное действие оператора без изменения данных, типа нажатия кнопки в форме. По-моему, будет достаточно если не запроса, то хранимой процедуры.
    Ответ написан
    2 комментария