// 1. Подготовка запроса (используем ? вместо переменной)
$sql = "SELECT ord.id, ord.kp_id, ord.status_deal, ord.deal_update, me.chat, me.uid_inbox, me.text_post, me.attach_post, me.from_send,
me.account_id_send, me.email_group_id, me.account_create, me.date_create as mess_create, me.date_update as mess_update, me.id as meido,
im.inbox_from, im.status_kp, im.date_create as status_create, im.date_update as status_update, im.inbox_udate as date_inbox, im.inbox_from as email_org,
im.id as id_inbox, im.subject as text_subject, me.subject_post, ord.type_payment, ord.date_up_notis, ord.sum_order, ord.bill_amount, ord.kp_num_out,
ord.bill_num, ord.delivery_days, ord.discount_percentage, ord.cost_markup, org.firs_last_name
FROM orders ord
LEFT JOIN message me ON ord.id = me.order_id
LEFT JOIN inbox_mail im ON im.uid = me.uid_inbox
LEFT JOIN organization org ON me.from_send = org.email_org
WHERE ord.id = ?
GROUP BY me.id
ORDER BY me.date_create DESC";
$stmt = $mysqli->prepare($sql);
// 2. Привязка параметров (i - integer, s - string)
$stmt->bind_param("i", $order_id_one);
// 3. Выполнение
$stmt->execute();
// 4. Получение результата
$Result = $stmt->get_result();
// Если ваша функция ResultSet ожидает массив данных:
$DEAL_ONE = [];
while ($row = $Result->fetch_assoc()) {
$DEAL_ONE[] = $row;
}
- Безопасность: В MySQLi крайне не рекомендуется вставлять переменную
$order_id_oneнапрямую в строку запроса. Используетсяprepare()иbind_param(). - Метод получения: Вместо прямого
$SQLite3->query()мы сначала подготавливаем запрос, а затем извлекаем результат черезget_result(). - Группировка: В MySQL (в зависимости от настроек
sql_mode) GROUP BY может потребовать перечисления всех полей в блоке SELECT, если они не агрегированы. Однако, еслиme.idявляется первичным ключом, этот запрос в MySQL будет работать корректно.
query), то в MySQLi это будет выглядеть так: // Прямой запрос через mysqli (аналог $SQLite3->query)
$Result = $mysqli->query("SELECT ord.id, ord.kp_id, ord.status_deal, ord.deal_update, me.chat, me.uid_inbox, me.text_post, me.attach_post, me.from_send,
me.account_id_send, me.email_group_id, me.account_create, me.date_create as mess_create, me.date_update as mess_update, me.id as meido,
im.inbox_from, im.status_kp, im.date_create as status_create, im.date_update as status_update, im.inbox_udate as date_inbox, im.inbox_from as email_org,
im.id as id_inbox, im.subject as text_subject, me.subject_post, ord.type_payment, ord.date_up_notis, ord.sum_order, ord.bill_amount, ord.kp_num_out,
ord.bill_num, ord.delivery_days, ord.discount_percentage, ord.cost_markup, org.firs_last_name
FROM orders ord
LEFT JOIN message me ON ord.id = me.order_id
LEFT JOIN inbox_mail im ON im.uid = me.uid_inbox
LEFT JOIN organization org ON me.from_send = org.email_org
WHERE ord.id='" . $mysqli->real_escape_string($order_id_one) . "'
GROUP BY me.id
ORDER BY me.date_create DESC");
// Получение данных (в зависимости от того, как работает ваша функция ResultSet)
// Если ResultSet принимает объект mysqli_result:
$DEAL_ONE = ResultSet($Result);
- Экранирование данных: В SQLite3 часто пренебрегают безопасностью, но в MySQLi при прямой вставке переменной обязательно используйте
$mysqli->real_escape_string(). Это защитит базу от взлома через SQL-инъекции. - Объект подключения: Вместо объекта
$SQLite3теперь используется объект$mysqli(или переменная, в которой у вас хранится соединение с БД). - Обработка результата:
- Если ваша функция
ResultSet()самописная, убедитесь, что внутри она используетmysqli_fetch_assoc($Result)вместо функций sqlite. - Если вы хотите получить массив вручную без сторонних функций:php
$DEAL_ONE = $Result->fetch_all(MYSQLI_ASSOC);Используйте код с осторожностью.
- Если ваша функция
В MySQL поведение
GROUP BY строже, чем в SQLite. Если запрос выдаст ошибку "Expression #1 of SELECT list is not in GROUP BY clause...", вам нужно будет либо добавить все поля из SELECT в GROUP BY, либо (что проще) убрать GROUP BY me.id, если в этом нет острой необходимости для фильтрации дублей. GROUP BY me.id), выбирая при этом десятки других колонок. - В MySQL (режим
ONLY_FULL_GROUP_BY): Если вы используетеGROUP BY, то все колонки, перечисленные вSELECT, должны либо присутствовать вGROUP BY, либо быть обернуты в агрегатные функции (например,MAX(),MIN(),ANY_VALUE()). - Решение: Если вы уверены, что
me.idуникален для этих данных, можно обернуть «лишние» поля в функциюANY_VALUE(field_name)или добавить их вGROUP BY.
- Регистрозависимость: В MySQL сравнение строк (например,
org.email_org) зависит от кодировки (collation). Обычно оно регистронезависимое (_ci), но если база настроена как_bin, запрос может перестать находить данные, которые SQLite находил. - Кавычки: SQLite позволяет использовать двойные кавычки для строк, MySQL требует для строк только одинарные
', а для имен таблиц и полей — обратные кавычки (backticks)`.
- SQLite:
WHERE ord.id='$order_id_one'(часто работало «как есть»). - MySQLi: Обязательно используйте
$mysqli->real_escape_string($order_id_one)или подготовленные выражения (?), иначе ваш код будет уязвим для SQL-инъекций.
LEFT JOIN (который поддерживают оба движка), помните, что MySQL поддерживает и RIGHT JOIN, и FULL JOIN (через UNION), что дает больше гибкости при обратной миграции. sql_mode в MySQL или добавьте все поля из SELECT в GROUP BY. GROUP BY, то все поля, которые вы перечислили в SELECT, должны быть указаны в GROUP BY. Вы говорите: "Сгруппируй по ID сообщения, а из остальных колонок (дата, текст, сумма) просто возьми какое-нибудь первое попавшееся значение". База данных соглашалась и работала.
ONLY_FULL_GROUP_BY):MySQL скажет: "Вы группируете по
me.id, но просите меня вывести ord.sum_order. А что если для одного me.id в базе данных есть две разные суммы? Какую именно мне показать? Я не буду гадать и выдам ошибку". ... GROUP BY me.id, ord.id, ord.kp_id, ord.status_deal, me.chat ... (и так далее все 30 полей)
ANY_VALUE(). Она говорит базе: "Возьми любое значение, мне не важно". SELECT ANY_VALUE(ord.id), ANY_VALUE(ord.kp_id), me.id ... GROUP BY me.id
GROUP BY используют просто чтобы убрать дубликаты. В MySQL для этого лучше использовать SELECT DISTINCT: SELECT DISTINCT ord.id, ord.kp_id ... (без GROUP BY в конце)
В MySQL нельзя просто выбрать «яблоко, грушу и цену» и сгруппировать только по «яблоку». Либо группируй по всему, либо используй функции (MAX, SUM, ANY_VALUE) для остальных полей.
me.id), является Primary Key (первичным ключом) или уникальным индексом (UNIQUE NOT NULL), то MySQL разрешает выбирать другие поля из этой же таблицы, даже если их нет в GROUP BY. id соответствует строго одна строка, поэтому никакой двусмысленности в данных не возникнет. - Для таблицы
message(me): Еслиme.id— это Primary Key, то все поляme.chat,me.text_postи т.д. будут выбираться без ошибок. - Для других таблиц (
orders,inbox_mail): Если между сообщениями и заказами связь «многие к одному» (много сообщений на один заказ), то поля изord(например,ord.status_deal) также будут выбираться корректно, так как они однозначно определены для этого сообщения.
Если
me.id — это AUTO_INCREMENT PRIMARY KEY, ваш запрос в MySQL, скорее всего, заработает без правок текста SQL, несмотря на строгий режим ONLY_FULL_GROUP_BY. 1055 (Expression #N of SELECT list is not in GROUP BY clause...), это будет означать, что MySQL не смог подтвердить уникальность для какой-то из колонок. В этом случае просто добавьте эту колонку в GROUP BY или оберните её в ANY_VALUE(название_поля). id, вы почти наверняка столкнетесь с ошибкой или логической проблемой в MySQL. me.from_send (email отправителя) не является уникальным. Один и тот же человек может отправить 10 разных сообщений. GROUP BY me.from_send, MySQL объединяет все строки с одинаковым email в одну. Но в этих строках могут быть разные ord.id или разные ord.status_deal. - MySQL (в строгом режиме) выдаст ошибку: «Я не знаю, какой именно
ord.idпоказать для этого отправителя, их там десять разных». - SQLite просто выдал бы вам первую попавшуюся строку.
SELECT me.from_send, ord.status_deal, ord.id
FROM orders ord
LEFT JOIN message me ON ord.id = me.order_id
WHERE ord.kp_id='$kpcr_n'
-- Группировка удалена, вы увидите каждую переписку
SELECT DISTINCT me.from_send, ord.status_deal, ord.id
FROM orders ord
LEFT JOIN message me ON ord.id = me.order_id
WHERE ord.kp_id='$kpcr_n'
GROUP BY, используйте функцию ANY_VALUE() для полей, которые не входят в группировку. Это заставит MySQL вести себя как SQLite (взять любое значение): SELECT me.from_send, ANY_VALUE(ord.status_deal), ANY_VALUE(ord.id)
FROM orders ord
LEFT JOIN message me ON ord.id = me.order_id
WHERE ord.kp_id='$kpcr_n'
GROUP BY me.from_send
ONLY_FULL_GROUP_BY включен по умолчанию. Поэтому ваш старый запрос из SQLite SELECT * ... GROUP BY non_unique_field в 99% случаев вызовет фатальную ошибку при выполнении в PHP. Всегда используйте либо DISTINCT, либо агрегатные функции (MAX, MIN, ANY_VALUE). Turn on your Visual Search History?
Google uses its visual recognition technologies to process the images you use to search, like when you search with Google Lens. If you turn on your Visual Search History, Google will save these images from eligible Google services to your Web & App Activity when you’re signed in to your Google Account. You can learn more about this setting and which Google services save images to it at g.co/Search/VisualSearchHistory.
How visual search history is used
Your Visual Search History may be used to improve your experience on Google services, like letting you revisit your past visual searches. It may be used to develop and improve Google’s visual recognition and search technologies, as well as the Google services that use them.
When visual search history is off
If you turn this setting off, any previous Visual Search History may still be kept and used to improve Google’s visual recognition and search technologies, unless you delete it from your Web & App Activity.
Visual Search History doesn’t affect images saved by other settings, like Gemini Apps Activity.
How to manage your Visual Search History
You can view, delete, or manage your Visual Search History at activity.google.com. To download your Visual Search History, visit takeout.google.com. Images will be deleted in accordance with your Web & App Activity auto-delete settings, although some types of images may be deleted sooner.
Google uses and saves data in accordance with Google Privacy Policy.
