Проблем със SQL заявка

Здравейте, програмиста, който ми пише един сайт има проблем със SQL зявка, а откакто го познавам досега не е имал проблеми, така че в случая е нещо сериозно :) ако можете да помогнете, много ще се радвам

Здравейте

имам следната таблица

Код:
mysql> describe messages;
+-----------+---------------------+------+-----+-------------------+------------
| Field        | Type                      | Null | Key | Default     | Extra
+-----------+---------------------+------+-----+-------------------+------------
| id            | int(10) unsigned    | NO   | PRI | NULL     | auto_increm
| user_id    | int(10) unsigned    | NO   |  | NULL     |
| target_id | int(10) unsigned    | NO   |  | NULL     |
| text        | text                        | NO   |  | NULL     |
| status     | tinyint(3) unsigned | NO   |  | NULL     |
| hide        | tinyint(3) unsigned | NO   |  | NULL     |
| ts           | timestamp               | NO   |  | CURRENT_TIMESTAMP |
| ip            | int(11)                    | NO   |  | NULL     |
+-----------+---------------------+------+-----+-------------------+------------

става въпрос за лични съобщения между потребителите в 1 уебсайт.

Опитвам се да измисля заявка, която да изведе по 1 ред за всеки потребител, с който Х си е писал (да кажем че ИД-то на този потребител е 2), в който да е последното съобщение с въпросния човек, ИД-то му (вече мога да си напиша join, с който да извадя потр.име и т.н.), датата на съответното съобщение и ИП-то

Уловката е, че съобщението трябва да е последното писано с този човек, независимо дали е изпратено или получено от гледна точка на потребителя. Примерно Гошо пише на Пешо, след това Пешо му отговаря. В кутиите и на двмата трябва да излиза второто съобщение, само името на кореспондента да е различно. Вече при кликване на името се отваря цялата дискусия между двмата потребители, но това отдавна съм го написал вече...

В общи линии - като фейсбук, но без отделни разговори, а всички съобщения с дадения потребител формират 1 разговор.

Ето докъде стигнах до момента....

Код:
(select `id`, `user_id`, `target_id`, `text`, `status`, `ts`, `ip` from messages where user_id in ((select user_id from messages where target_id = 2) union (select target_id from messages where user_id = 2)) and target_id = 2) union (select `id`, `target_id`, `user_id`, `text`, `status`, `ts`, `ip` from messages where target_id in ((select user_id from messages where target_id = 2) union (select target_id from messages where user_id = 2)) and user_id = 2)
Код:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select target_id from messages where user_id = 2))) union (select `id`, `' at line 1

Благодаря ви предварително :)
 
От: Проблем със SQL заявка

Не разбрах какво в този скрипт трябва да изважда последното съобщение с даден потребител. Бих се опитал да свържа тази таблица (примерно по user_id) с друга от базата данни, за да мога да намеся последните съобщения. Не знам защо използваш толкова много union в една таблица без дата за това, което се опитваш да постигнеш.
Грешката в синтакса е друг проблем. Аз работя с Oracle база данни и също често ми се налага да чета за определен тип номера на грешки в Интернет.
 
От: Проблем със SQL заявка

Доколкото разбрах искаш да изведеш последното съобщение на всеки потребител независимо дали той го е писал или друг потребител го е писал до него? Ако полето id e auto_increment, полето user_id е полето на потребителя написал съобщението, а target_id e полето ДО когото е съобщението тази заявка трябва да изкара последното съобщение на потребител с ID=2 независимо кой го е писал:

$user_id = 2;
$query = mysql_query("SELECT * FROM messages WHERE user_id='$user_id' OR target_id='$user_id' ORDER BY id DESC LIMIT 1");

EDIT: хубаво е да записваш и часа и датата на съобщението както ти е казал harkon
 
Последно редактирано:
От: От: Проблем със SQL заявка

EDIT: хубаво е да записваш и часа и датата на съобщението както ти е казал harkon
Не съм казал, че е хубаво да ги записва. Едно query може да бъде пренаписано по няколко начина и да вади верните резултати. Ако базата съдържа таблица с дата и час, заявката и съответно външния вид на справката ще са по-прегледни. "LIMIT 1" не отговаря на целта на справката, защото резултатните редове трябва да са повече от 1.
 
От: От: Проблем със SQL заявка

Не съм казал, че е хубаво да ги записва. Едно query може да бъде пренаписано по няколко начина и да вади верните резултати. Ако базата съдържа таблица с дата и час, заявката и съответно външния вид на справката ще са по-прегледни. "LIMIT 1" не отговаря на целта на справката, защото резултатните редове трябва да са повече от 1.

harkon чети малко по-добре - "...в който да е последното съобщение с въпросния човек..."
 
От: От: От: Проблем със SQL заявка

harkon чети малко по-добре - "...в който да е последното съобщение с въпросния човек..."
"Опитвам се да измисля заявка, която да изведе по 1 ред за всеки потребител, с който Х си е писал (да кажем че ИД-то на този потребител е 2), в който да е последното съобщение с въпросния човек"
Кой трябва да чете по-добре? Колко могат да се потребителите, с които x си е писал?
 
От: От: Проблем със SQL заявка

X може да си е писал с N потребителя ... и?
В такъв случай заявката трябва да изведе N на брой редове, във всеки от които да бъде последното съобщение от потребителя, с който X си е писал.
(N+1) ред -> последно съобщение с потребител Y
(N+2) ред -> последно съобщение с потребител Z
Ако иска входящи и изходящи съобщения, както е в случая, редовете стават 2N.
Ако полето ts съдържа дата и час, може да се ползва. Бих използвал maximum date, за да отделя само последните съобщения от/към даден потребител.
 
Ето това е заявката (ако правилно съм разбрал какво искаш):

SET @user_id = 1;

SELECT
t1.*
FROM
messages t1
LEFT JOIN
messages t2 ON ((t1.user_id = t2.user_id AND t1.target_id = t2.target_id) OR
(t1.user_id = t2.target_id AND t1.target_id = t2.user_id)) AND t1.id < t2.id
WHERE
(t1.user_id = @user_id OR t1.target_id = @user_id)
AND
t2.id IS NULL;

В mysql с MAX май няма как да стане само с една заявка. Иначе има разни варианти с temp таблица и подобни.
 

Горе