Задавайте вопросы, мы ответим
Вы не зашли.
Не знаю как толком описать вопрос.
Есть таблица с полями:
id, b, c, d
записи выглядят например так:
id=1, b=1, c=1, d=acb
id=2, b=1, c=2, d=acbxyz
id=3, b=2, c=1, d=acb
id=4, b=2, c=2, d=acbxyz
id=5, b=3, c=1, d=acb
Тут какая ситуация: Сейчас мы видим 5 записей данных. Но на самом деле важны только три (b=1, b=2, b=3), две попарно, и одна сама по себе. Различаются по признаку c=1 или c=2, то есть короткая запись данных с=1 или длинная с=2.
Я бы мог делать выборку всех данных, и потом на php прогонять массив и глядеть что у записи с признаком 1 (b=1) есть два варианта c=1 или c=2, значит берем данные из колонки d=acbxyz - типа длинная запись предпочтительнее короткой. Но такой метод это ресурсы системы и зачем их занимать если можно правильно составить запрос к базе и сразу получить данные только те что нужно откидывая лишние которые не предпочтительны.
Помогите составить запрос чтоб возвращалась строка при наличии c=2 - только запись с ней, а если ее нет то запись со значением c=1.
Спасибо за подсказки.
Отредактированно батарейка (29.11.2010 00:46:05)
Неактивен
Я тут подумал что мне скажут про GROUP BY `b`, но в таком случае что именно вернется c=1 или c=2 останется? Как то не очень вариант думаю.
Неактивен
батарейка написал:
Я тут подумал что мне скажут про GROUP BY `b`,
Не угадали
Неактивен
Очень круто и по делу. Просто приятное посещение ресурса вышло. А то везде любят в Гугль посылать. Благодарю вас!
Неактивен
vasya написал:
батарейка написал:
Я тут подумал что мне скажут про GROUP BY `b`,
Не угадали
select t.* from
(select * from `таблица` order by b, c desc) t,
(select @i:=0,@p:=0) x
where if(@p=b,@i:=@i+1,(@i:=0) or (@p:=b)) and @i<1;
Пояснения в теме http://sqlinfo.ru/forum/viewtopic.php?id=1742
Я прошу меня простить, сел разбирать - уууу.
Если можно - что такое (select t.* from) "t", эта таже таблица что и (from `таблица`), или это одна из этих переменных @p или @i немного запутался, подставляю свои значения и ничего
Неактивен
(select * from `таблица` order by b, c desc) t,
Это отсортированная исходная таблица
В запросе вам нужно лишь заменить `таблица` на имя вашей таблицы, никаких других значений там подставлять не надо.
Неактивен
Решил показать саму таблицу, а то ничего не понятно вероятно вам. Извиняюсь за хлопоты.
Итак, есть таблица с данными:
Поле "fieldcol", и есть тот самый признак хранения поля короткой записи и полной. Вообще эта вся таблица как бы сводная по другим таблицам и полям, так работает система.
Итак, Поле "fieldcol" - какое поле хранится, кратко или полно. Поле "fieldrow", это идентификатор поля, тут мы видим везде 1 - что значит все три поля относятся к одной записи с айди 1, но на языках "lang", 2 или 3 или там бывает вообще сколько угодно.
Итого, нужно из этих трех строк взять только одну, чтоб поле "lang" например было 2, как текущий язык на странице, получается уже выбираются 2 поля с айди 3 и 5, и уже среди них нужно откинуть запись с значением "short" так как есть "full" запись что более приоритетна.
Спасибо сердечное за помощь.
Неактивен
Я увидел ваш ответ и спешу сказать что я поля a, b, c, d написал чтоб упросить тут вопрос, а потом под них подставить нужно свои имена полей и короче я запутался.
Неактивен
Попробовал так:
Неактивен
Ну, с вашим последним ответом я тоже запутался
"Итого, нужно из этих трех строк взять только одну, чтоб поле "lang" например было 2, " - вот этот момент совершенно непонятен. Каким образом, вы определяете какой язык оставить? Это фиксированная константа? А если у записи нет языка №2, а есть 3,5,8, какой выбрать?
Неактивен
батарейка написал:
Попробовал так:
select t.* from
(select * from `u_passengers_alerts_languages_data` order by fieldcol, fieldrow desc) t,
(select @i:=0,@p:=0) x
where if(@p=fieldcol,@i:=@i+1,(@i:=0) or (@p:=fieldcol)) and @i<1
Но ничего не находит
Ну, fieldcol это аналог признака с, т.е. длинная или короткая запись.
А вот что будет выступать аналогом признака b (в свете наличия различных языков у fieldrow и необходимости выбрать среди них один) неясно. См предыдущий ответ.
Неактивен
Спасибо за ваш ответ, Архат.
Такой подход с языком придумал я как-то. Когда потребовалось делать сайты на разных языках. В админке которую я пишу пользователи заполняют форму. Но у формы нет одного фиксированного поля например для оглавления статьи, а этих полей может быть и миллион, в зависимости от того столько языков на сайте присутствуют.
от того визуально у него форма выглядит просто:
Тут мы даже видим те самые "кратко" (short) и полно (full) это таблица так называемых у меня "текстовых переменных". После все это сыплется в базу, от куда при случае возьмутся данные (на самом деле все) но функционал системы сравнит какие есть записи, например на сайте установлен русский язык, и подгрузятся только русские сообщения, или на английском, или если есть русского возьмется по приоритету далее, английский или французский.
Потому выбирая сейчас я получаю ненужные записи, одновременно и short и full, хотя full предпочтительнее чем short.
Короче я видно вас запутал. Извиняюсь что в предыдущих записях записал про выборку еще и по языку, совсем забыл что мне нужно все данные, на случай если какого то языка нет в данный момент (но это уже работа php).
Если можно давайте про язык забудем, как будто этой колонки нет вообще, как и колонки arraname она сейчас не играет роли.
Неактивен
Перечитал все, подставил правильно как вы писали. Уже лучше:
Неактивен
батарейка написал:
Перечитал все, подставил правильно как вы писали. Уже лучше:
select t.* from
(select * from `u_passengers_alerts_languages_data` order by fieldrow, fieldcol desc) t,
(select @i:=0,@p:=0) x
where if(@p=fieldrow,@i:=@i+1,(@i:=0) or (@p:=fieldrow)) and @i<1
Нашло одну строку с айди 3.
Буду копать далее.
В исходной постановке задачи признак с был числовым и отсортированный по убыванию на первом месте ставил строки соответствующие длинной строки. В нынешнем варианте сортировка по убыванию для fieldcol на первом месте поставит строку short.
Правильно ли я понимаю, что вам нужно для каждого fieldrow все строчки, имеющие fieldcol=full?
Просто это отличается от исходной задачи, где требовалась одна строчка на каждый fieldrow.
Неактивен
Немного не ловко вам уже писать. Наверное много требуется терпения все это выслушивать. Сейчас вот проанализировав все пришел к следующему заключению. Если конечно у вас будет желание то конечно ваша помощь не была бы лишней мне, но если уже утомил - то пусть будет как есть.
Попробую описать еще раз максимально понятно. Для этого я внес еще записи и предоставляю картинку.
Итак:
Мы видим в таблице 7 записей. Если смотреть по колонке "fieldrow" то мы увидим всего 2 записи, под номерами 1 и 2, Данные с номером fieldrow=1 всего три, из них Short (Короткое значение) 2 записи и 1 запись с тегом full (полная запись с форматированием). Но и 2 записи Short разные, так как написаны для языка 3 и 2. Итого, для записи fieldrow=1 существуют 2 записи для двух языков, short и full для языка 2, и только short для языка 3.
Тоже самое для fieldrow=2. Там 4 записи попарно short и full для языка 2, и short и full для языка 3.
Зачада. Так как одной записи fieldrow=1 и одному языку (lang) = 2 мы получаем одновременно и short и full, то так как запись fieldcol=full имеет приоритет выше чем short то вернуть ее, а short откинуть. Так же получается что по fieldrow=1 и одному языку (lang) = 3 мы получаем запись только short и возвращаем ее так как нет fieldcol=full.
Также и по второй группе и так далее. Например по fieldrow=2 у нас 4 записи, по short и full для каждого языка, для 2, и 3. Потому смысл вернуть только с значениями full имеет смысл.
Думаю что сейчас объяснил всю суть проблемы. Но не замарачивайтесь если нет желания.
За все с благодарностью.
Отредактированно батарейка (30.11.2010 23:02:39)
Неактивен
Понятно. Требуется выбрать по одной записи для каждой группы, но группа характеризуется не одним параметром fieldrow, а комбинацией (fieldrow,lang).
Соответственно ответ тот же, что и раньше, только условие на обнуление счетчика не при изменении fieldrow, а комбинации (fieldrow,lang).
Неактивен
Это очень круто! Спасибо, работает. Да у вас лучший форум!
Спасибо!
Неактивен