| Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум на Исходниках.RU > Базы данных: SQL > Как работают вычисления в SQL? |
| Автор: Majestio 26.12.23, 17:15 |
| Конечно можно. Для этого тебе нужно сделать соединение таблицы с самой себя. Условие соединения - что номера заказов совпадают, и у первой таблицы в поле статуса заказа "создан", и у второй "завершен". В этом запросе в блоке SELECT указываешь первым полем - номер заказа (первой или присоединяемой таблицы - без разницы, т.к. они равны), вторым полем используешь функцию с постфикcом AS days. Этим самым ты переназовешь второй столбец. Функцию ищи в документации, которая рассчитывает разницу в днях. Если я не ошибаюсь - в MySQL это DATEDIFF. В PostgreSQL используй что-то типа: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> (timestamp2::date - timestamp1::date) AS days Добавлено Цитата rownong@yandex.ru @ Вопрос аналогичный, где будет выведен результат? Будет создана абстрактная (временная) таблица в которой будут выведены - Номер заказа - Количество дней между прошло между статусам "Создан" и "Завершен". ?? Будет создан результат, который будет выведен в интерфейс phpMyAdmin, и никуда не будет записан. Если нужно его куда-то сохранить - копируй из интерфейса копипастой. Или создай заранее нужную таблицу в БД и в нее произведи запись результата запроса. |
| Автор: Akina 26.12.23, 19:49 |
| В запросе, который описывает задание серверу, указывается, какие поля нужно вернуть, и с помощью каких выражений следует получать для них значения. Можно вывести поле исходной таблицы без изменения, можно его при выводе переименовать, можно на основе нескольких полей написать вычисляющее выражение и дать ему имя... Например, запрос может выглядеть так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT table1.name1, table2.name2 AS name3, table1.name4 * table2.name5 AS name6 FROM ... Соответственно после связывания исходных таблиц в соответствии в секцией FROM, фильтрации в соответствии со WHERE и сортировкой в соответствии с ORDER BY будет возвращён набор записей. Он будет состоять из трёх полей с именами name1, name3 и name6, первые два будут содержать неизменённые значения указанных полей исходных таблиц, третье - произведение указанных полей. |
| Автор: rownong@yandex.ru 29.12.23, 01:15 |
| Цитата В запросе, который описывает задание серверу, указывается, какие поля нужно вернуть, и с помощью каких выражений следует получать для них значения. Можно вывести поле исходной таблицы без изменения, можно его при выводе переименовать, можно на основе нескольких полей написать вычисляющее выражение и дать ему имя... Получается когда делаем SQL запрос, чтобы соединить 2 таблицы можем в результате скрывать (не выводить) определённые столбцы? Вернее, выводить только нужны столбцы из обоих таблиц Добавлено Если есть например 10 менеджеров по продажам, мы можем в результате SQL запроса вывести не 10 строка с суммой продажи каждого менеджера за месяц, а 1 строк с суммой продаж всех менеджеров за месяц? |
| Автор: Majestio 29.12.23, 04:04 |
| Цитата rownong@yandex.ru @ Получается когда делаем SQL запрос, чтобы соединить 2 таблицы можем в результате скрывать (не выводить) определённые столбцы? Вернее, выводить только нужны столбцы из обоих таблиц Да. Цитата rownong@yandex.ru @ Если есть например 10 менеджеров по продажам, мы можем в результате SQL запроса вывести не 10 строка с суммой продажи каждого менеджера за месяц, а 1 строк с суммой продаж всех менеджеров за месяц? Можем. Есть несколько вариантов. Первый - используй фильтрацию запросов оператором WHERE чтобы получить одну нужную строку, либо пробуй использовать оператор LIMIT с аргументом 1. Во втором случае скорее всего нужно будет прибегнуть заранее к сортировке строк результата, ибо лимит только "обрежет" остальные строки из результата. А без предварительной сортировки это будет недетерминированный результат. Хотя, суммируя все продажи, мы реально должны получить одну строку без всяких телодвижений типа WHERE и LIMIT. |
| Автор: Akina 29.12.23, 07:05 |
| Цитата rownong@yandex.ru @ Получается когда делаем SQL запрос, чтобы соединить 2 таблицы можем в результате скрывать (не выводить) определённые столбцы? Вернее, выводить только нужны столбцы из обоих таблиц Выводить нужно (не можно, а именно нужно) только то, что реально требуется. Если нужны только результаты вычисления каких-то выражений - в выходном наборе должны быть только они. SELECT * в рабочей версии приложения пишут исключительно идиоты (да, вот настолько безальтернативно) - даже если действительно нужны все поля, следует их перечислять по одному. Или идти учить матчасть по нормализации данных. Цитата rownong@yandex.ru @ Если есть например 10 менеджеров по продажам, мы можем в результате SQL запроса вывести не 10 строка с суммой продажи каждого менеджера за месяц, а 1 строк с суммой продаж всех менеджеров за месяц? Продажа отдельного менеджера и продажа всех менеджеров - это разные уровни группировки. Поэтому сама фраза не имеет смысла - нужно ведь либо то, либо другое. А если вдруг надо всё это одновременно (программист не умеет заставить клиентскую часть выводить итоги), то есть GROUP BY WITH ROLLUP/CUBE. Нереляционно, но если по другому не умеешь - пусть его. Это ж потом не SQL-серверу трахаться, а клиентской части, её не жалко. |
| Автор: Majestio 29.12.23, 08:17 |
| Цитата Akina @ SELECT * в рабочей версии приложения пишут исключительно идиоты (да, вот настолько безальтернативно) - даже если действительно нужны все поля, следует их перечислять по одному Согласен полностью. Но только с учетом именно рабочей версии. В процессе написания скрипта и его отладки SELECT * вполне допустимо использовать, иногда это немного экономит время. ИМХО. |
| Автор: MIF 29.12.23, 13:50 |
| SELECT * можно писать в рабочем коде. Вот MS SQL пример: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> IF EXISTS(SELECT * … Есть еще по крайней мере один случай, когда нельзя перечислять поля, а надо писать SELECT * в рабочем коде. |
| Автор: Majestio 29.12.23, 17:21 |
| Хм...Это с какого такого перепугу? |
| Автор: Akina 30.12.23, 09:16 |
| Вас спасает только то, что MS SQL достаточно умный. И знает, что в EXISTS сами значения полей не нужны, и лезть за ними в тело таблицы не требуется. Но вот формально - такой код требует метнуться за значениями полей, а потому SELECT {const} разумнее и логичнее. Цитата MIF @ Есть еще по крайней мере один случай, когда нельзя перечислять поля, а надо писать SELECT * в рабочем коде. Хотелось бы конкретики. Я пока о таких случаях не слышал - за исключением ситуации, когда необходимость грести всё подряд определяется или отставанием клиента, или мультиверсионностью БД. |
| Автор: Akina 02.01.24, 18:36 |
| Цитата rownong@yandex.ru @ 1. При SQL запросе, когда создаем абстрактные (не существующие) поле (столбцы) можно ли кроме присвоения им имен, также добавлять комментарии, на время просмотра SQL запроса? Нет. Цитата rownong@yandex.ru @ 2. Какой оператор нужно использовать, чтобы использовать фильтр типа "содержит"? Показанные примеры не относятся к типу "содержит". Это типичный случай "равно" (использован синтаксис MySQL): <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> WHERE log->>"$.jp_purchase_id" = '395948' |
| Автор: rownong@yandex.ru 05.01.24, 22:38 |
| Цитата Akina @ Цитата rownong@yandex.ru @ 1. При SQL запросе, когда создаем абстрактные (не существующие) поле (столбцы) можно ли кроме присвоения им имен, также добавлять комментарии, на время просмотра SQL запроса? Нет. Цитата rownong@yandex.ru @ 2. Какой оператор нужно использовать, чтобы использовать фильтр типа "содержит"? Показанные примеры не относятся к типу "содержит". Это типичный случай "равно" (использован синтаксис MySQL): <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> WHERE log->>"$.jp_purchase_id" = '395948' Спасибо! |
| Автор: rownong@yandex.ru 05.01.24, 22:38 |
| Подскажите, правильно понимаю, что результатом SQL запроса могут быть: 1. Реальная таблица из БД. 2. Абстрактная таблица (с несуществующими столбцами, но которые создаем в момент запроса) 3. Число (например результат расчетов). Т.е. просто одно число (без таблиц и столбцов), которое получаем в результате. ?? |
| Автор: Majestio 05.01.24, 23:08 |
| Цитата rownong@yandex.ru @ Подскажите, правильно понимаю, что результатом SQL запроса могут быть: 1. Реальная таблица из БД. 2. Абстрактная таблица (с несуществующими столбцами, но которые создаем в момент запроса) 3. Число (например результат расчетов). Т.е. просто одно число (без таблиц и столбцов), которое получаем в результате. Не совсем правильно. Результатом SQL запроса не может быть ни реальная таблица из БД, ни абстрактная таблица, и ни число. Ибо результатом SQL запроса может быть только сам результат SQL запроса Другое дело, что может содержать этот результат. А он может содержать: 1. Значения всех или отдельных полей (столбцов) реальной таблицы или таблиц из БД 2. Значения полей (столбцов), получаемых в результате вычислений, обращений к VIEW или хранимым процедурам 3. Значения полей (столбцов), заданных константой Последний вариант, скажем так, сильно менее распространён. Как правило используется в подзапросах. Ибо в финальном запросе указывать поле, содержащее константу, по факту - бессмысленно. |
| Автор: Majestio 05.01.24, 23:29 |
| Он скорее всего некорректно задал вопрос Возможно речь шла о формировании "комментария" (по факту обычного поля), а-ля:<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT name AS Name, cnt AS Cnt , CASE WHEN cnt > 100500 THEN 'дофига' ELSE 'так себе' END AS Comment; Хотя - это только мои догадки. |
| Автор: macomics 06.01.24, 00:44 |
| Цитата Majestio @ Он скорее всего некорректно задал вопрос Возможно речь шла о формировании "комментария" (по факту обычного поля), а-ля:<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT name AS Name, cnt AS Cnt , CASE WHEN cnt > 100500 THEN 'дофига' ELSE 'так себе' END AS Comment; Хотя - это только мои догадки. Нет. Он спрашивал о комментариях. Они могут быть добавлены к полям таблицы при создании. <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> CREATE TABLE IF NOT EXISTS `BIO` (`id` INT PRIMARY KEY COMMENT 'Main key', `name` VARCHAR(64) COMMENT 'Имя', `sername` VARCHAR(64) COMMENT 'Фамилия', `male` INT(1) COMMENT 'Пол мужской?') Вот об этих комментариях он спрашивал https://dev.mysql.com/doc/refman/8.0/en/create-table.html |
| Автор: Majestio 06.01.24, 06:54 |
| Цитата macomics @ А, понятно |
| Автор: Akina 06.01.24, 08:25 |
| Цитата rownong@yandex.ru @ Подскажите, правильно понимаю, что результатом SQL запроса могут быть: 1. Реальная таблица из БД. 2. Абстрактная таблица (с несуществующими столбцами, но которые создаем в момент запроса) 3. Число (например результат расчетов). Т.е. просто одно число (без таблиц и столбцов), которое получаем в результате. ?? Совершенно неправильно. Есть запросы, которые возвращают набор данных. Т.е. которые возвращают результат выборки/расчёта. Даже если результатом является единственная запись с единственным полем (то, что тебе кажется "просто числом"). Даже если результатом является пустой, не содержащий ни одной записи, набор. И есть запросы, которые НЕ возвращают набор данных. Это запросы, которые модифицируют данные (если диалект не поддерживает RETURNING или если он не использован), а также запросы, которые работают с метаданными. Такие запросы возвращают статус выполненного запроса и, возможно, дополнительную информацию по его выполнению (например, запрос на обновление возвращает как общее количество записей, соответствующих условиям отбора, так и количество фактически обновлённых записей, т.е. в которых новое значение отличается от старого). Кроме того, выполнение абсолютно любого запроса может привести к ошибке - в этом случае возвращается код ошибки и дополнительная информация по ней. |
| Автор: Majestio 06.01.24, 12:12 |
| Цитата Akina @ Совершенно неправильно. Есть запросы, которые возвращают набор данных. Т.е. которые возвращают результат выборки/расчёта. Даже если результатом является единственная запись с единственным полем (то, что тебе кажется "просто числом"). Даже если результатом является пустой, не содержащий ни одной записи, набор. И есть запросы, которые НЕ возвращают набор данных. Это запросы, которые модифицируют данные (если диалект не поддерживает RETURNING или если он не использован), а также запросы, которые работают с метаданными. Такие запросы возвращают статус выполненного запроса и, возможно, дополнительную информацию по его выполнению (например, запрос на обновление возвращает как общее количество записей, соответствующих условиям отбора, так и количество фактически обновлённых записей, т.е. в которых новое значение отличается от старого). Кроме того, выполнение абсолютно любого запроса может привести к ошибке - в этом случае возвращается код ошибки и дополнительная информация по ней. Не согласен, потому как речь шла именно о запросах по получению данных. Другие запросы, модифицирующие прикладные данные, системную информацию - об этом не шла речь. Равно как и о запросах с ошибкой. |
| Автор: rownong@yandex.ru 06.01.24, 20:57 |
| Цитата rownong@yandex.ru @ 3. Число (например результат расчетов). Т.е. просто одно число (без таблиц и столбцов), которое получаем в результате. ?? По этому вопросу в итоге непонял, результат SQL моежет быть только 1 число - результат вычислений? |
| Автор: macomics 06.01.24, 21:23 |
| Цитата rownong@yandex.ru @ По этому вопросу в итоге непонял, результат SQL моежет быть только 1 число - результат вычислений? Даже одно число можно представить в виде одной строки с одним столбцом. Результатом запроса будут именно подобные значения (строки и столбцы). Столбцы перечисляются в запросе, а строки формируются по результатам отбора из базы данных. При этом результатом запроса может быть одно значение, но для его размещения будет сформировано одно поле и выбрана одна строка. Так надеюсь понятнее. |
| Автор: Akina 06.01.24, 22:18 |
| Цитата rownong@yandex.ru @ По этому вопросу в итоге непонял, результат SQL моежет быть только 1 число - результат вычислений? Нет. Как уже выше сказано, это будет набор записей. Сам набор будет состоять из одной записи, а структура набора (и соответственно этой одной записи) будет состоять из одного поля. Как итог - весь набор записей будет содержать ровно 1 запись * 1 поле = 1 значение. Но набор записей содержит ещё кучу метаданных - количество полей (одно), имя этого одного поля, тип его данных, количество записей (одна)... Соответственно обратиться к этому набору как к скалярному значению - нельзя. Хорошо, если при обращении будет выполнено неявное приведение к скалярному типу - то есть удалена метаинформация об имени поля и типе его данных и пр... но надеяться на это неразумно, да и вероятность существования в синтаксисе такого неявного приведения весьма мала. Например, тот же MySQL вроде бы делает это с лёгкостью - ага, как бы не так! для того, чтобы он преобразовал, надо выражение-запрос обернуть скобками, иначе syntax error. |
| Автор: Akina 15.01.24, 19:32 |
| Цитата rownong@yandex.ru @ Подскажите в SQL запросе возможно построить абстрактную (виртуальную) таблицу Нет. Применительно к SQL такого понятия как "абстрактная (виртуальная) таблица" - не существует. Используйте корректную технически грамотную терминологию. |
| Автор: rownong@yandex.ru 15.01.24, 21:01 |
| Цитата rownong@yandex.ru @ А что по поводу этого вопроса? Такое решение реально сделать? |
| Автор: Majestio 16.01.24, 13:35 |
| Абстрактных (виртуальных) таблиц в SQL не существует, но есть VIEW (представления), которые реализуют твои потребности по данному вопросу. Материала по этому в сети полно. Навскидку, почитай вот эту статью. Статья более-менее норм, имхо. |
| Автор: rownong@yandex.ru 19.01.24, 13:39 |
| Еще подскажите, создавая временные (виртуальные) поля (столбцы) в результате SQL запроса, можно им имена давать не на латинице, а на кириллице и с пробелами? |
| Автор: macomics 19.01.24, 14:07 |
| <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> Что мешает попробовать? Это на MSSQL - работает.SELECT id as 'идентификатор', name as 'имя', sername as 'фамилия', extname as 'отчество', birthday as 'дата рождения' FROM BIOData; https://sqliteonline.com/ Для тренировки и уменьшения количества вопросов |
| Автор: rownong@yandex.ru 19.01.24, 14:21 |
| Цитата macomics @ <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> Что мешает попробовать? Это на MSSQL - работает.SELECT id as 'идентификатор', name as 'имя', sername as 'фамилия', extname as 'отчество', birthday as 'дата рождения' FROM BIOData; https://sqliteonline.com/ Для тренировки и уменьшения количества вопросов Отлично! Спасибо! |
| Автор: rownong@yandex.ru 19.01.24, 16:18 |
| Попробовал просто на кириллице одинарные слова или несколько через нижнее подчеркивание, все ок. А вот когда через пробел слова, даже в кавычках вся фраза, то заглючивает SQL запрос. |
| Автор: rownong@yandex.ru 20.01.24, 07:34 |
| Подскажите, если есть столбце с полем артикул и в каждой строке перед артикулом приставка "1-" (например 1-23442242), то как вырезать эту приставку "1-" SQL-ем чтобы далее производить вычисления чистым артикулом? |
| Автор: Akina 20.01.24, 16:50 |
| Зависит от СУБД и даже точной версии - везде свои встроенные строковые функции. |
| Автор: rownong@yandex.ru 20.01.24, 19:23 |
| MySQL |
| Автор: macomics 20.01.24, 19:57 |
| https://dev.mysql.com/doc/refman/8.0/en/str...function_substr |