[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как задать допустимое количество повторений?
minok94
Здравствуйте, форумчане! Есть запрос из БД, как сделать, чтобы при выводе значение одного из полей повторятось не больше 3 раз?



Спустя 15 минут, 52 секунды (21.04.2011 - 15:54) alex12060 написал(а):
Вас кинут в баню.
Это раз.
А во-вторых, я вопроса не понял.

Спустя 2 минуты, 18 секунд (21.04.2011 - 15:56) inpost написал(а):
ORDER BY по этому полю.
При каждом круге цикла заноси $i++ как счетчик, например если запись не повторилась, то $i = 1; если повторилась, то ++, если >3 , то continue до вівода.

Спустя 2 минуты (21.04.2011 - 15:58) minok94 написал(а):
Есть таблица с автомобилями, как сделать чтобы в поле "марка" выводильсь не больше 3 повторений, например:

bmw
audi
bmw
....
....
bmw

Спустя 2 минуты, 17 секунд (21.04.2011 - 16:00) minok94 написал(а):
inpost
А можно это сделать в теле запроса? Или только срадствами PHP?

Спустя 10 минут, 42 секунды (21.04.2011 - 16:11) sergeiss написал(а):
Элементарно в БД делается. Надо использовать limit.

Спустя 3 минуты, 54 секунды (21.04.2011 - 16:15) minok94 написал(а):
sergeiss
Можете дать пример?

Спустя 1 час, 56 минут, 42 секунды (21.04.2011 - 18:12) alex12060 написал(а):

SELECT `auto`
FROM `autos`
WHERE `aname` = 'bmw'
LIMIT 0, 3

Спустя 3 часа, 46 минут, 48 секунд (21.04.2011 - 21:59) sergeiss написал(а):
Цитата (sergeiss @ 21.04.2011 - 17:11)
Элементарно в БД делается.

Наверное, я погорячился немного.... Не так и элементарно. Хотя, я думаю, можно сделать smile.gif Подумаю как.

Спустя 51 минута, 28 секунд (21.04.2011 - 22:50) Snus написал(а):
minok94
А вариант с массивом не устроит?

Спустя 5 минут, 15 секунд (21.04.2011 - 22:55) Snus написал(а):
$query = 'SELECT `mark` FROM `auto` ORDER BY `mark`';
$sql = mysql_query($query) or die(mysql_error());
$arr = array();
while ( $row = mysql_fetch_assoc($sql) )
if(count($arr[$row['mark']]) < 3)
$arr[$row['mark']][] = $row['mark'];

print_r($arr);

Спустя 4 минуты, 14 секунд (21.04.2011 - 23:00) Invis1ble написал(а):
Итересно было бы увидеть чисто SQL-решение

Спустя 11 часов, 55 минут, 42 секунды (22.04.2011 - 10:55) sergeiss написал(а):
Цитата (Invis1ble @ 22.04.2011 - 00:00)

Интересно было бы увидеть чисто SQL-решение

Хотите - получите...

Алгоритм простой: делаем функцию в SQL, которая выполняет нужные действия :) Там получается цикл в цикле, но так как это происходит полностью внутри БД и делаются только необходимые действия, то скорость выполнения достаточно большая.

Далее приведено решение для Postgre. Кому надо - переводите в MySQL.

Таблица:
CREATE TABLE auto
(
id serial NOT NULL,
name_ character varying(30),
info character varying(30)
)


функция (каменты внутри):
CREATE OR REPLACE FUNCTION get_auto(n_limits integer)
RETURNS SETOF auto AS
$BODY$
declare
one_name varchar(30);
r record;
begin
<<all_names>> /* цикл по всем уникальным именам машин */
FOR one_name in
select distinct
name_ from auto order by name_ LOOP
<<one_name>> /* выборка не более заданного количества строк по каждому типу авто */
FOR r in
select
* from
(select a2.id, a2.name_, a2.info from auto a2 where a2.name_=one_name order by random() limit n_limits) ini_select
order by id
LOOP
return next r; /* полученный результат записывается в результирующую таблицу */
END LOOP one_name;
END LOOP all_names;

RETURN;
END
$BODY$
LANGUAGE 'plpgsql' VOLATILE


получить результат (этот запрос вызывается изнутри ПХП и его результат можно использовать для вывода данных):
select * from get_auto( 3 )


Получаемые данные сортируются сначала в алфавитном порядке по именам машин, а внутри них - по возрастанию id. Этот алгоритм задан внутри функции, но его можно и изменить.

У меня получилось в одном из запусков
<pre class="sh_sourceCode" rel="code">id;name_;info
6;"audi";"info audi 33"
9;"audi";"info audi 65"
10;"audi";"info audi 874"
2;"bmw";"info2"
3;"bmw";"info10"
4;"bmw";"info35"
</pre>

Обращаю внимание, что ПРИ КАЖДОМ ЗАПУСКЕ (!) набор возвращаемых строк будет меняться для каждого типа авто. Если, конечно, для определенного авто будет строк больше, чем указанный лимит.

Цитата (sergeiss @ 21.04.2011 - 17:11)
Элементарно в БД делается. Надо использовать limit

Цитата (sergeiss @ 21.04.2011 - 22:59)
Наверное, я погорячился немного.... Не так и элементарно.

И все-таки элементарно! ;) Я был прав.

Спустя 1 день, 9 часов, 55 минут, 14 секунд (23.04.2011 - 20:50) sergeiss написал(а):
Чё-та я так и не понял... Прочитали ли мой ответ, помог ли он хоть как-то? И ТС, и Invis1ble молчат smile.gif

Спустя 1 час, 2 минуты, 3 секунды (23.04.2011 - 21:53) Invis1ble написал(а):
sergeiss
а я не пробовал еще, если честно, времени нету к сожалению... Надо еще этот код в диалект мускула перевести )
Ну я попозжа обязательно пошаманю, спасибо за твой пример.

Спустя 4 дня, 6 часов, 16 минут, 10 секунд (28.04.2011 - 04:09) olgatcpip написал(а):
sergeiss, я только не поняла запись <<all_names>>
это типа.. виртуальной/временной таблицы?

Спустя 5 часов, 15 минут (28.04.2011 - 09:24) Snus написал(а):
sergeiss
А сколько по времени выполняется запрос при условии, что записей в БД более 300 тыс?

Спустя 3 часа, 16 минут, 37 секунд (28.04.2011 - 12:40) sergeiss написал(а):
Цитата (olgatcpip @ 28.04.2011 - 05:09)
sergeiss, я только не поняла запись <<all_names>>
это типа.. виртуальной/временной таблицы?

Нет, это метка цикла. Там же идет потом END LOOP all_names;, т.е. конец цикла с этой меткой.

Цитата (Snus @ 28.04.2011 - 10:24)
А сколько по времени выполняется запрос при условии, что записей в БД более 300 тыс?

А я откуда знаю? smile.gif Наверное, не меньше, чем просто выбрать 300 килозаписей wink.gif Т.е. достаточно долго, т.к. эти килозаписи надо будет записать во временную таблицу.

Другой вопрос - а зачем для 300К записей эту функцию запускать?

Спустя 4 дня, 5 часов, 43 минуты, 17 секунд (2.05.2011 - 18:24) minok94 написал(а):
Извините, некоторое время небыло возможности выйти в и-нет, спасибо всем!
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.