Помогите с запросом
У нас уже 12 ночи но не могу успокоиться пока не получится
есть таблица(пример)
Код:
my-----you
13-------1
13-------1
13-------1
4-------1
4-------1
1-------13
1-------13
13-------2
13-------2
13-------2
13-------1
13-------1
13-------1
4-------1
4-------1
1-------13
1-------13
13-------2
13-------2
13-------2
Делаю запрос
Код:
select * from tab where my= 13 OR you=13 GROUP BY my
выдаёт 3 строки(группы)
то есть строки таблицы 1-3 и 6-7 помещает в разные группы
а мне нужно чтобы все строки в которых число 13 встречается в любом столбце были в одной группе
тоесть чтобы запрос выдал 2 строки(группы)
думаю понятно объяснил
туплю что то
заранее спасибо
надеюсь поможите..
Что значит в одной группе? Как, по-вашему, должен выглядеть результат?
Чтобы было понятнее, напиши такой запрос:
Код:
SELECT table1.my,
table1.you
FROM table1
GROUP BY table1.my
HAVING table1.my = 13 OR table1.you = 13
table1.you
FROM table1
GROUP BY table1.my
HAVING table1.my = 13 OR table1.you = 13
Группировка фактически даёт то, что ты по одному полю можешь указать DISTINCT, только тут получается по DISTINCT по двум критериям.
таблицу не точно нарисовал
у меня выдаёт 3строки
а если табл вот так вглядит
Код:
13-------1
13-------1
13-------1
4-------1
4-------1
1-------13
1-------13
2-------13
2-------13
2-------13
13-------1
13-------1
4-------1
4-------1
1-------13
1-------13
2-------13
2-------13
2-------13
тоесть группирует строки
так
1-3
6-7
8-10
а мне надо чтобы строки
1-3 и 6-7 попадали в одну строку результата
мне бы хотелось чтобы результат 2 строки был для обоих вариантов таблицы
задачка не так проста как кажется
такого не бывает, это мистика. не может попасть в один ряд результат, где my=13 AND my=1.
мне нужно сгруппировать строки уникальные
только по значению
а не по расположению
не важно
1----13
или
13----1
эти строки должны быть в одной группе
Код:
SELECT t1.my, t1.you, t2.my, t2.you
FROM table1 t1
INNER JOIN table1 t2 ON t1.my = t2.you
GROUP BY t1.my
FROM table1 t1
INNER JOIN table1 t2 ON t1.my = t2.you
GROUP BY t1.my
UPD. Даже вот так:
Код:
SELECT t1.my, t1.you, t2.my, t2.you
FROM table1 t1
INNER JOIN table1 t2 ON t1.my = t2.you
WHERE t1.my=13
GROUP BY t1.my
FROM table1 t1
INNER JOIN table1 t2 ON t1.my = t2.you
WHERE t1.my=13
GROUP BY t1.my
может тут не группировать нужно
а что то другое главное
что бы
1----13
и
13----1
были в одной строке результата
ну вон чуть выше всё в одном ряду
нужно таблицу t2 создать
с такими же полями
нет, t1 и t2 - это алиасы для одной и той же таблицы table1. Ну ты попробуй этот запрос - сразу всё поймёшь.
вернул одну строку
Извращенцы. Автору я бы порекомендовал объяснить задачу на более высоком уровне, что за данные он хочет получить, потому что на низком уровне получается какая-то ахинея и извращения.
есть таблица переписки
столбцы
nu - индекс автоинкремент
n_pa - номер автора сообщения
n_to - номер адресата
tx - текст сообщения
new_s - прочитано или нет(0 или 1)
data - дата сообщения
nu-----n_pa-----n_to-----tx-----data
например пользователь с номером 13 написал сообщение пользователю 1
получаем
n_pa-----n_to
13--------1
в ответ пользователь 1 написал ответ пользователю 13
n_pa-----n_to
1--------13
ну и так далее
потом наверное многие видели делаю как переписка в однокласниках
из таблицы нужно выбрать уникальные диалоги
тоесть все записи
n_pa-----n_to
13--------1
.....
1--------13
это один диалог
а например
n_pa-----n_to
13--------5
.....
5--------13
другой и так далее нужно чтобы результат возвращал все уникальные диалоги причём поля new_s могут иметь разные значения 0 или 1
не знаю как понятней
правда, есть ещё вариант. насколько я понял, тебя последовательность мессаг в переписке определяется только временем? (кстати, date - зарезервированное слово и поле нельзя так называть) Если бы у тебя у мессаги был идентификатор её предка, то можно было бы все "узлы" рекурсивно пробежать. У тебя всё в одну колонку. Значит нужно выбрать во вложенном запросе идентификаторы рядов, отсортировав их по времени и авторам, и тогда тебе вернутся сообщения с этими идентификаторами, отсортированные как надо.
FROM
table1
WHERE
id IN (SELECT id FROM table1 WHERE my=13 OR you=13 ORDER BY date ASC)
И не надо никаких группировок. И всё это в цикл завернуть, если хостёр позволяет stored procedures )))))
но не суть сортировать хотел не по дате а по количеству новых
new_s=1 значит непрочитанное
остальные сотртировать по id(nu)
сердцем чую запрос написать можно
а может сначала выбрать
(SELECT id FROM table1 WHERE my=13 ORDER BY nu desc)
(SELECT id FROM table1 WHERE you=13 ORDER BY nu desc)
а потом их как то объдинить
Вобщем, введи ещё одно поле answer_by, в который будешь писать идентификатор сообщения, на которое ответ случился. Соответственно, у самого первого сообщения будет answer_by=0. Вот тебе и первые сообщения в переписках. А дальше циклами, циклами по всей ёлке.
Цитата: vadim_k
а может сначала выбрать
(SELECT id FROM table1 WHERE my=13 ORDER BY nu desc)
(SELECT id FROM table1 WHERE you=13 ORDER BY nu desc)
а потом их как то объдинить
(SELECT id FROM table1 WHERE my=13 ORDER BY nu desc)
(SELECT id FROM table1 WHERE you=13 ORDER BY nu desc)
а потом их как то объдинить
Эти два запроса можно объединить, вставив между ними UNION. и скобки убрать.
UPD. и сортируй не по id, а по времени. Идентификатор с автоинкрементом может подвести.
Какая субд у вас?
[quote=mfender]
не парся с запросом. он тебе никогда не вернёт того что ты хочешь.
[/quote]
Вообще-то можно и одним запросом.
А циклы - это плохо. Где есть возможность - надо стараться обходиться без них.
MySql 5.0, PHP
Я тоже чувствую одним можно
рою книги
А идея такая. В подзапросе значения полей меняете местами (при помощи case), если одно больше другого, при этом, если значения поменялись устанавливаете признак что они были поменяны, потом запросом из подзапроса выбираете только уникальные (при помощи оконной функции или группировки). Потом в том же запросе смотрите на прзнак, если значения полей менялись местами - меняете их обратно.
Могу привести пример такого решения, но только на mssql, если он вам поможет...
конечно лучше на пример посмотреть а то я не особо силён в Sql
Код:
(SELECT DISTINCT n_pa as first, n_to as second from tab
WHERE my=13)
UNION
(SELECT DISTINCT n_to as first, n_pa as second from tab
WHERE you=13)
WHERE my=13)
UNION
(SELECT DISTINCT n_to as first, n_pa as second from tab
WHERE you=13)
попробовал количество строк вроде правильно выдаёт
осталось только доработать что бы количество сообщений
подсчитывать
раньше делал так
COUNT(if(n_to = 13 and new_s = 0,1,NULL)) AS mi_mess_new
куда теперь это пристроить
SELECT t1.*,
if(t1.n_pa > t1.n_to,t1.n_pa,t1.n_to) AS first,
if(t1.n_pa > t1.n_to,t1.n_to,t1.n_pa) AS second,
FROM messeges AS t1
where t1.n_to=13 OR t1.n_pa=13 GROUP BY first,second
только единственный минус, у вас в запросе. Если допустим была только одна запись у которой t1.n_pa < t1.n_to, то вы поменяв там поля местами получите ту запись которой фактически не было в исходных данных.
Т.е. например было 1, 3 и 3, 1. Вы поменяли стало 3,1 и 3, 1 берете одну из них. Тут все ок. А если была только одна запись например 1, 6. То в итоговой выборке у вас будет запись 6, 1 - а такой записи фактически не существует.
По этому я предложил решить эту проблему через подзапрос. Т.е. ввести признак в подзапросе и если смена фактически была - то меняем обратно во внешенм запросе.
Хотя если для вашей задачи это не важно, то можно и не париться.