Здраствуйте. Делаю чат. Проектирую таблицу с сообщениями. В комнате выводится сообщения из БД. поля в таблице: id сообщения, id комнаты, дата и время, id пользователя который отправил сообщение, id пользователя кому отправлено сообщение, private - приватность сообщения (0 - видят все, 1 видит только тот пользователь, которому отправлено которому отправлено сообщение и тому пользователю, который отправил) Запрос примерно таков: ВЫБРАТЬ все поля ИЗ таблицы message ГДЕ с пометкой '1' в private поле не является id тому пользователю, которому отправлено данное сообщение И с пометкой '1' в private поле не является id того пользователя, который отправил данное сообщение СОРТИРОВКА ПО id сообщения С ЛИМИТОМ 200 сообщений ЛИМИТ нужен для того, чтобы для каждого пользователя выборка из БД была 200 сообщений не зависимо приватное сообщение или нет. Это для постраничной навигации: 10 страниц по 20 сообщений на странице. ВОПРОС!!! как сделать такой запрос? ГДЕ с пометкой '1' в private поля не является id тому пользователю, которому отправлено данное сообщение И с пометкой '1' в private поля не является id того пользователя, который отправил данное сообщение ПРИМЕЧАНИЕ: Можно было бы выбрать все сообщения в количестве 200 штук, не зависимо от является ли отправитель автор приватного сообщения и является ли получатель приватного сообщения, и уже при выводе сообщений проверять является ли данное приватное сообщение того пользователя, который отправил или тому пользователю, которому отправлено, если да, то выводить это сообщение, if($private == 1 && $id_отп-ля == $id_поль-ля || $id_получ-ля == $id_поль-ля) выводим сообщение else continie; но тут есть проблема: Допустим будет 5 приватных сообщений. Из БД выводится 200 сообщений независимо от приватности и, если такой метод отображения использовать, то другие пользователи увидят на 5 сообщений, а именно 195. Следовательно, на первой странице они увидят не 20 сообщений, а на 5 меньше, то есть 15.
Код (Text): WHERE `id_user` NOT IN(123,234) AND `privat` !=1 Где 123,234 - это поля id пользователя который отправил сообщение и id пользователя кому отправлено сообщение?
@Funch, нужно проектировать таблицы в соответствии с выполняемыми запросами, а не усложнять запросы из-за неподходящим образом спроектированных таблиц. Например, ЛС можно отображать в приватных чатах, а в сообщениях вместо флага приватности хранить идентификатор (приватного) чата (значение 0, например, указывает на публичный чат).
Выбрать всё, кроме 123 и 234 в колонке in, при этом не равное 345 в колонке out, и при этом не равное 1 в колонке privat. Это не решение конкретно вашей задачи. А пример постановки условий. Так как задача неконкретна и описана непродуманно. Вместо AND можно использовать OR.
Код (Text): CREATE TABLE `test_table` ( `id` int UNSIGNED NOT NULL, `id_who` int NOT NULL, `id_to_whom` int NOT NULL, `private` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0', `message` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; это таблица PHP: $mysqli = mysqli_connect('localhost', 'root', 'root', 'test') or die(mysqli_error()); // * в качестве теста $id_user = 3; $sql = "SELECT * FROM `test_table` WHERE (`id_who` = '$id_user' AND private = '0') OR (`id_who` = '$id_user' AND private = '1') OR (`id_who` != '$id_user' AND private = '0') OR (`id_to_whom` = '$id_user' AND private = '1') LIMIT 5"; echo $sql; $result = mysqli_query($mysqli, $sql); for($i = 0; mysqli_num_rows($result) > $i; $i++){ $row[] = mysqli_fetch_assoc($result); } print_r ($row); а вот запрос, который работает, все отрабатывает, но какой-то он громоздкий
Не совсем. Нет данных. >а вот запрос, который работает, все отрабатывает, но какой-то он громоздкий Работает быстро?
PHP: $start = microtime(); // * в качестве теста $id_user = 3; $sql = "SELECT * FROM `test_table` WHERE (`id_who` = '$id_user' AND private = '0') OR (`id_who` = '$id_user' AND private = '1') OR (`id_who` != '$id_user' AND private = '0') OR (`id_to_whom` = '$id_user' AND private = '1') LIMIT 5"; $total_time = microtime()- $start; echo $total_time; // 9.0000000000368E-6 0.0000090000 - это самое большое значение . вот данные , которые хранятся в таблицею они тестовые
а для чего? можно узнать поподробней или дайте ресурс, где с этим можно ознакомиться и почему сравнение в поле private убрать? PHP: $sql = "SELECT * FROM `test_table` WHERE private = '0' OR (`id_who` = '$id_user' AND private = '1') OR (`id_to_whom` = '$id_user' AND private = '1') LIMIT 5" и вот несколько строк кода сократил в запросе!
Оно здесь бессмысленно. http://www.mysql.ru/docs/man/ENUM.html https://www.google.com/search?q=mysql+составной+индекс
PHP: $sql = "SELECT * FROM `test_table` WHERE private = '0' OR (`id_who` = '$id_user' OR `id_to_whom` = '$id_user') LIMIT 200"; Тогда уж вообще так.
Не уверен. Можно обратиться к структуре таблицы. Например, если у вас нет обращений к конкретному челу в публичных сообщениях, то вам поле private не нужно. Т.е. обращение к конкретному будет признаком приватности. Иначе – ко всем.