MySQL выводит несколько строк, если QTY> 1 - PullRequest
2 голосов
/ 08 мая 2011

Есть ли способ вывести несколько строк таблицы, если определенное поле в таблице больше 1.

Вот мой пример:

Я создаю веб-сайт аукциона, где мыпродать билеты на лотерею.Билеты хранятся в таблице примерно так:

id, order_id, product_id, qty, price

Когда придет время распечатывать билеты, я хочу выгрузить все это в CSV.Пока что я делаю этот запрос (упрощенно, опуская INNER JOIN):

SELECT id, order_id, product_id, qty, price FROM order_details

И затем запускаю что-то вроде следующего цикла:

foreach($rows as $row) {
   for($i = 0; $i < $row['qty']; $i++) {
      $tickets[] = $row;
   }
}

, чтобыполучить отдельную запись для каждого кол-во (чтобы люди получали правильное количество записей ...).

Есть ли способ сделать это в самом SQL, чтобы каждая строка умножалась х раз, где хопределенное поле в таблице (qty в этом примере)?

Ответы [ 6 ]

2 голосов
/ 08 мая 2011

Чтобы расширить @ zdennis ' answer , вы можете сделать это в MySQL:

    SELECT order_details.*
      FROM order_details
INNER JOIN kilo
           ON kilo.i < order_details.qty;

где отношение "kilo" имеет целые числа 0 - 999, приспособление, адаптированное из сообщения xaprb :

CREATE TABLE deca (i integer not null);
INSERT INTO deca (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
CREATE VIEW kilo (i) AS
      SELECT iii.i * 100 + ii.i * 10 + i.i
        FROM deca iii
  CROSS JOIN deca ii
  CROSS JOIN deca i;
2 голосов
/ 08 мая 2011

Вы можете сделать это исключительно в MySQL, используя таблицу blackhole и триггер

Настройка таблиц
Сначала создайте таблицу черной дыры, в которую вы собираетесь вставить, и память (или временную таблицу), в которую черная дыра будет перенаправлена.

CREATE TABLE Blackhole1 LIKE order_details ENGINE = BLACKHOLE;

CREATE TABLE temp_order_results LIKE order_details ENGINE = MEMORY;

Настройка триггера
Теперь создайте триггер в таблице blackhole, который перенаправит вставку в таблицу памяти, дублируя строки с помощью qty > 1.

DELIMITER $$

CREATE TRIGGER ai_Blackhole1_each AFTER INSERT ON blackhole1 FOR EACH ROW
BEGIN
  DECLARE ACount INTEGER;
  SET ACount = new.qty;
  WHILE ACount > 1 DO BEGIN
    INSERT INTO temp_order_results 
    VALUES (new.id, new.order_id, new.product_id, 1, new.price)
    SET ACount = ACount - 1;
  END; END WHILE;
END $$

DELIMITER ;

Заявления для выполнения запроса
Теперь сделайте вставку .. выберите в черную дыру

INSERT INTO blackhole1 
  SELECT id, order_id, product_id, qty, price FROM order_details;

И выбор на temp_order_results.

SELECT id, order_id, product_id, qty, price FROM order_details;
1 голос
/ 08 мая 2011

На самом деле нет причин для производительности.В MySQL есть несколько сильных сторон: сортировка, индексация, поиск, хранение и т. Д. Вы также можете сделать это в PHP.

0 голосов
/ 08 января 2012

Я должен был сделать то же самое, чтобы избежать курсора. Мое решение для SQL Server и действительно простое, потому что в моем случае qty никогда не превышает 99, поэтому вот пример с использованием временных таблиц:

create table #t (
     id int
    ,qty int
)

insert into #t values (1,2)
insert into #t values (2,3)

create table #n (
     id int
)

insert into #n values (1)
insert into #n values (2)
insert into #n values (3)
insert into #n values (4)
insert into #n values (5)

select t.*
from #t t
inner join #n n on
    n.id <= t.qty

Вам просто нужно вставить в #n максимальное количество, которое вы ожидаете (в моем случае 99).

0 голосов
/ 08 мая 2011

В соответствующем ответе может использоваться двойное соединение по уровню. См. Этот вопрос для получения дополнительной информации: Как вернуть несколько одинаковых строк на основе поля количества в самой строке?

Хотя это не работает в MySQL, см .: Как мне создать генератор строк в MySQL?

Если вы используете MySQL, вам нужно быть довольным, делая это на PHP или делая что-то грубое (например, триггер, который опубликовал Йохан). Я бы проголосовал, чтобы просто сделать это на PHP, если бы это было так.

0 голосов
/ 08 мая 2011

Я думаю, что может быть возможным в Sql Server или Oracle с использованием рекурсивного общего табличного выражения (CTE), которое соединяет исходную таблицу с самим собой и включает Qty-1 в качестве выражения вместо Qty всписок выбора CTE.К сожалению, последнее, что я слышал, MySql еще не поддерживает CTE.

Другой вариант - создать простую таблицу последовательностей, которая просто включает числовой столбец и строки, которые начинаются с 1 и заканчиваются наибольшим числом, которое вы реально сможетев столбце Кол-во вашей исходной таблицы.Вы можете присоединить это к своей таблице заказов с помощью предложения WHERE, ограничив результаты цифр меньшим, чем поле Qty, и таким образом дублировать строки.Чтобы быстро построить таблицу последовательности, создайте таблицу цифр с записями от 0 до 9 и перекрестно соедините ее с собой один раз для каждой степени 10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...