Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Выборка одной и той же строки несколько раз

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: как сделать одним запросом
Slavenin
Отправлено: 19 Мая, 2011 - 20:27:09
Post Id



Посетитель


Покинул форум
Сообщений всего: 285
Дата рег-ции: Май 2010  
Откуда: Тверь


Помог: 4 раз(а)




Всем доброго времени суток!

Возникла такая необходимость, есть n строк в бд в которых содержится информация о некоторых вещах и их количестве. Необходимо выбрать каждую строку столько раз, сколько содержится в количестве. Т.е. есть строки

id | название | количество
1 | вещь1 | 4
2 | вещь2 | 3

необходимо строку 1 выбрать четыре раза, а строку 2 - три раза, одним запросом, причем количество строк может быть разным в зависимости от условия. Нужно реализовать это на чистом sql без использования php или javascript.
Нужно это чтобы выводилось типа вещь1 1 из 4, вещь1 2 из 4 и тд.
Подскажите направление в котором думать, уже сломал весь мозг себе.

(Отредактировано автором: 19 Мая, 2011 - 20:27:38)

 
 Top
DeepVarvar Супермодератор
Отправлено: 19 Мая, 2011 - 20:38:44
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Slavenin пишет:
на чистом sql без использования php или javascript

Покажите как вы на javascript ЭТО делаете!!!

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t.*,COUNT(t.*) cnt1,tt.*,COUNT(tt.*) cnt2 FROM t LEFT JOIN t tt WHERE t.id = 1 AND tt.id = 2

Не проверял... Ниндзя

(Отредактировано автором: 19 Мая, 2011 - 20:39:50)

 
 Top
Slavenin
Отправлено: 19 Мая, 2011 - 20:46:48
Post Id



Посетитель


Покинул форум
Сообщений всего: 285
Дата рег-ции: Май 2010  
Откуда: Тверь


Помог: 4 раз(а)




[quote=DeepVarvar]
Slavenin пишет:
на чистом sql без использования php или javascript

Покажите как вы на javascript ЭТО делаете!!!

я имею в виду, что выборку строк можно сделать запросом, а обработчик написать в виде цикла на php либо ajax запросом и циклом уже на java

неа, не получается таким запросом
пишет ошибку

Цитата:
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 '*) cnt1,tt.*,COUNT(tt.*) cnt2 FROM t_items as t LEFT JOIN t tt WHERE t.i_code = ' at line 1


запрос:

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t.*,COUNT(t.*) cnt1,tt.*,COUNT(tt.*) cnt2 FROM t_items AS t LEFT JOIN t tt WHERE t.i_code = 'item1'

(Отредактировано автором: 19 Мая, 2011 - 21:07:40)

 
 Top
DeepVarvar Супермодератор
Отправлено: 19 Мая, 2011 - 21:10:19
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Дайте реальные имена таблицы и полей
 
 Top
Slavenin
Отправлено: 19 Мая, 2011 - 21:17:17
Post Id



Посетитель


Покинул форум
Сообщений всего: 285
Дата рег-ции: Май 2010  
Откуда: Тверь


Помог: 4 раз(а)




таблица t_items
поле имени i_code
поле количества i_count
 
 Top
DeepVarvar Супермодератор
Отправлено: 19 Мая, 2011 - 21:32:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t_items.id,t_items.i_code,t_items.i_count,t_items2.id id2,t_items2.i_code i_code2,t_items2.i_count i_count2 FROM t_items LEFT JOIN t_items t_items2 ON (t_items2.id = (t_items.id+1)) WHERE t_items.id = 1
 
 Top
Slavenin
Отправлено: 19 Мая, 2011 - 21:52:00
Post Id



Посетитель


Покинул форум
Сообщений всего: 285
Дата рег-ции: Май 2010  
Откуда: Тверь


Помог: 4 раз(а)




поля id в таблице нет, ключом является поле i_code(varchar). Выбрать нужно именно несколько копий одной строки , а не присоединить копию слева

(Отредактировано автором: 19 Мая, 2011 - 21:52:21)

 
 Top
DeepVarvar Супермодератор
Отправлено: 19 Мая, 2011 - 21:58:08
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Тогда мне кажется что задача несколько маразматична - множить результат для вывода...
 
 Top
Slavenin
Отправлено: 19 Мая, 2011 - 22:02:51
Post Id



Посетитель


Покинул форум
Сообщений всего: 285
Дата рег-ции: Май 2010  
Откуда: Тверь


Помог: 4 раз(а)




есть такая волшебная программа зовется bartender печатает она этикетки, настройка функции сериализации в ней не позволяет сделать вывод этикеток в нужном формате, зато она умеет работать с базой. поэтому для реализации задачи, необходимо именно размножить вывод нужное количество раз
 
 Top
DeepVarvar Супермодератор
Отправлено: 19 Мая, 2011 - 22:20:59
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




А вот теперь интересно Улыбка
Так тем же джойном, только убрать +1 в запросе..
И далее сколько раз надо, столько и джойнить..
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t_items.i_code,t_items.i_count
  2. t_items2.i_code i_code2,t_items2.i_count i_count2,
  3. t_items3.i_code i_code3,t_items3.i_count i_count3,
  4. t_items4.i_code i_code4,t_items4.i_count i_count4
  5. FROM t_items
  6. LEFT JOIN t_items t_items2 ON (t_items2.i_code = t_items.i_code)
  7. LEFT JOIN t_items t_items3 ON (t_items3.i_code = t_items.i_code)
  8. LEFT JOIN t_items t_items4 ON (t_items4.i_code = t_items.i_code)
  9. WHERE t_items.i_code = 'чему_оно_там_равно'

Наверное есть какое-то более лаконичное решение..

(Отредактировано автором: 19 Мая, 2011 - 22:30:15)

 
 Top
EuGen Администратор
Отправлено: 20 Мая, 2011 - 11:19:13
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Лаконичнее - вряд ли.
Ваше плохо тем, что если надо на чистом SQL, то мы не знаем, сколько заранее раз надо выполнять JOIN. Плюс к тому если повторять надо раз 500, JOIN уже не кажется таким уж отличным решением.
В качестве "классического" SQL-решения мне тоже не удалось найти ничего.
Однако можно использовать SQL-процедуры, которые по сути повторят ту же работу, что была бы проделана в скрипте. Вот то, что сделал я:
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. DROP PROCEDURE IF EXISTS dorepeat;
  3.  
  4. delimiter //
  5.  
  6. CREATE PROCEDURE dorepeat()
  7. BEGIN
  8.    SET @i=0;
  9.    SET @c=(SELECT COUNT(*) FROM `repeats`);
  10.    SET @s='';
  11.    REPEAT      
  12.       PREPARE repsel FROM 'SELECT num INTO @r FROM repeats LIMIT ?,1';
  13.       EXECUTE repsel USING @i;
  14.       PREPARE repsel FROM 'SELECT id INTO @id FROM repeats LIMIT ?,1';
  15.       EXECUTE repsel USING @i;
  16.       SET @j=0;
  17.       REPEAT
  18.          SET @s=CONCAT(@s, 'SELECT ',@id,' UNION ALL ');
  19.          SET @j=@j+1;
  20.       UNTIL @j>@r-1 END REPEAT;
  21.       SET @i=@i+1;    
  22.    UNTIL @i>@c-1 END REPEAT;
  23.    SET @s=SUBSTRING(@s, 1, LENGTH(@s)-10);  
  24.    PREPARE mainsel FROM @s;
  25.    EXECUTE mainsel;
  26.    DEALLOCATE PREPARE mainsel;
  27. END
  28. //
  29. delimiter ;
  30.  

Таблица:
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `repeats` (
  3.  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  4.  `num` int(11) UNSIGNED NOT NULL,
  5.  PRIMARY KEY  (`id`)
  6. ) ENGINE=InnoDB;
  7.  

После определения нужно вызывать процедуру так:


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
EuGen Администратор
Отправлено: 20 Мая, 2011 - 13:59:39
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Придумал как сделать на "чистом" SQL:
Если создать дополнительную таблицу такого вида:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE `natural` (
  2.  `id` int(11) UNSIGNED NOT NULL,
  3.  PRIMARY KEY  (`id`)
  4. ) ENGINE=InnoDB

И заполнить её значениями целых положительных чисел подряд (в моем примере я заполнил ее от 1 до 10)
То выбрать строки можно так:
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT repeats.* FROM `natural` LEFT JOIN repeats ON `natural`.id<=repeats.num WHERE repeats.id IS NOT NULL
  3.  

Таблица repeats та же.
Стоит отметить, что таблица naturals должна быть заполнена до значения, которое больше максимального числа повторений из таблицы repeats.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Sylver
Отправлено: 02 Февраля, 2016 - 09:51:19
Post Id


Новичок


Покинул форум
Сообщений всего: 1
Дата рег-ции: Февр. 2016  


Помог: 0 раз(а)




Тоже озаботился повторением этикеток в Bartender, придумал вот такое решение для размножения этикеток, позволяет вставить на этикетку поле заполняемое для каждой новой записи из БД.


CODE (SQL):
скопировать код в буфер обмена
  1. SELECT
  2.         (SELECT 'одна запись' FROM dual) AS str
  3. FROM dual
  4. connect BY rownum <= 'сколько надо повторить'
  5.  

(Отредактировано автором: 02 Февраля, 2016 - 09:52:12)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB