Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / MySQL Новый топик    Ответить
 Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
Все привет, помогите пожалуйста с запросом:

Суть такова:
Есть бургер и всякие дополнения к нему, и у бургера и у самих дополнений есть цена.
Вот так это выглядит:

lines
idnamesum
1burger1


ingredients
idline_idnamesumtype
11onion20
21garlic30
31tomato41
41carrot51
51pepper62


Вопрос:
Нужно сделать отчет в котором покажет сколько действительно стоит бургер без использования UNION ALL

Но есть хитрость одна:
дополнения с типом 0 должны войти в стоимость самого бургера, а все остальные как отдельные строки

report
namesumtype
burger60
burger|tomato41
burger|carrot51
burger|pepper62


Я тут накидал запрос нерабочий, он не учитывает стоимость самого бургера, как туда добавить еще бургер без union, голову ломаю.
Можно было бы продублировать строку, но как.
Вообщем буду признателен за любую помощь.


SELECT l.id, i.type, SUM(i.sum)
FROM _lines l
LEFT JOIN _ingr i ON i.line_id = l.id
GROUP BY l.id,
	case when i.`type` = 0 then i.`type` ELSE i.id END;



Исходные данные:
+

-- --------------------------------------------------------
-- Host:                         127.0.0.1
-- Server version:               5.7.25-log - MySQL Community Server (GPL)
-- Server OS:                    Win64
-- HeidiSQL Version:             10.2.0.5599
-- --------------------------------------------------------

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

-- Dumping structure for table _ingr
CREATE TABLE IF NOT EXISTS `_ingr` (
  `id` int(11) NOT NULL,
  `line_id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '',
  `sum` int(11) NOT NULL,
  `type` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK___lines` (`line_id`),
  CONSTRAINT `FK___lines` FOREIGN KEY (`line_id`) REFERENCES `_lines` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- Dumping data for table _ingr: ~0 rows (approximately)
/*!40000 ALTER TABLE `_ingr` DISABLE KEYS */;
INSERT INTO `_ingr` (`id`, `line_id`, `name`, `sum`, `type`) VALUES
	(1, 1, 'onion', 2, 0),
	(2, 1, 'garlic', 3, 0),
	(3, 1, 'carrot', 4, 1),
	(4, 1, 'tomato', 5, 1),
	(5, 1, 'pepper', 6, 2);
/*!40000 ALTER TABLE `_ingr` ENABLE KEYS */;

-- Dumping structure for table _lines
CREATE TABLE IF NOT EXISTS `_lines` (
  `id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '',
  `sum` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- Dumping data for table _lines: ~1 rows (approximately)
/*!40000 ALTER TABLE `_lines` DISABLE KEYS */;
INSERT INTO `_lines` (`id`, `name`, `sum`) VALUES
	(1, 'burger', 1);
/*!40000 ALTER TABLE `_lines` ENABLE KEYS */;

/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

11 фев 20, 16:03    [22077701]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
Тут скорей всего проблема в хранении данных:
эти ингредиенты с типом 0 должны быть в таблице lines с указанием родителя ParentId и тогда было бы все проще
11 фев 20, 16:54    [22077742]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20026
GROUP BY (_ingr.type>0) * _ingr.id
11 фев 20, 16:59    [22077748]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
entrypoint
Member

Откуда:
Сообщений: 227
maratoss,

maratoss

Нужно сделать отчет в котором покажет сколько действительно стоит бургер без использования UNION ALL


почему именно без UNION ALL ?
11 фев 20, 17:34    [22077801]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
entrypoint,

С union all на реальных данных почему-то долго работает
если взять одну и ту же таблицу, объединить и попробовать поискать по первичному ключу то занимает это несколько секунд
в таблицы где-то ~100к строк


SELECT d.id FROM (
	SELECT lns1.id FROM orderlines lns1
	UNION all
	SELECT lns2.id FROM orderlines lns2
) d
WHERE d.id = '02207950-5f81-4b5c-bc46-08dbf029b566'


К сообщению приложен файл. Размер - 26Kb
11 фев 20, 19:56    [22077857]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
Akina
GROUP BY (_ingr.type>0) * _ingr.id


Не совсем так работает, не учитывает стоимость самого бургера
burger: 1 + onion: 2 + garlic: 3 = должно получиться 6
этот запрос возвращает 5 для type = 0.

SELECT l.id, i.type, SUM(i.sum)
FROM _lines l
LEFT JOIN _ingr i ON i.line_id = l.id
GROUP BY (i.type>0) * i.id;
11 фев 20, 20:04    [22077859]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20026
SELECT CONCAT(_lines.name, 
               CASE WHEN type 
                    THEN CONCAT('|', 
                                ANY_VALUE(ingr.name)) 
                    ELSE '' 
                    END) name, 
       SUM(ingr.`sum`) `sum`, 
       ANY_VALUE(ingr.type) type
FROM _lines
JOIN ( SELECT id, line_id, name, `sum`, type
       FROM _ingr
       UNION ALL
       SELECT 0, id, name, `sum`, 0
       FROM _lines ) ingr ON _lines.id = ingr.line_id
GROUP BY _lines.name, (ingr.type > 0) * ingr.id, ingr.type;

fiddle.
11 фев 20, 20:14    [22077862]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20026
Ну и, как просили, вариант без UNION ALL:

SELECT CASE WHEN ANY_VALUE(I.type) = 0
            THEN L.name
            ELSE CONCAT(L.name, '|', ANY_VALUE(I.name))
            END name,
       CASE WHEN ANY_VALUE(I.type) = 0
            THEN SUM(I.`sum`) + ANY_VALUE(L.`sum`)
            ELSE ANY_VALUE(I.`sum`)
            END `sum`,
       ANY_VALUE(I.type) type
FROM _lines L
JOIN _ingr I ON L.id = I.line_id
GROUP BY L.name, (I.type > 0) * I.id;

fiddle.
11 фев 20, 20:45    [22077879]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
Akina,

Идеалити! Спасибо, то что нужно.
В мой запрос получается нужно было добавить только вот это, но я чет тупанул :)
, case when i.type = 0 then SUM(i.sum) + l.sum ELSE SUM(i.sum) END s


Всем спасибооо!
12 фев 20, 10:02    [22078019]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20026
Я всё же настоятельно рекомендую использовать ANY_VALUE(), чтобы всё не обсыпалось при случайном или плановом включении ONLY_FULL_GROUP_BY.
12 фев 20, 12:16    [22078133]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
maratoss
Member

Откуда: от верблюда
Сообщений: 137
Akina,

Хорошее замечание, благодарю, учту
12 фев 20, 13:09    [22078213]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34587
maratoss

Вопрос:
Нужно сделать отчет в котором покажет сколько действительно стоит бургер без использования UNION ALL



Я на SQL.ru уже хожу, только чтобы поржать...
Тут не только ответить ни на что нельзя, а и даже что-то понять, настолько невменяемые запросы.
12 фев 20, 16:41    [22078542]     Ответить | Цитировать Сообщить модератору
 Re: Как продублировать строку в запросе  [new]
Андрей B.
Member

Откуда: Оренбург
Сообщений: 1
А мне очень даже интересно.
Не стандартно мыслят товарищи...
15 фев 20, 15:47    [22080509]     Ответить | Цитировать Сообщить модератору
Все форумы / MySQL Ответить