Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Фильтрация выборки / 19 сообщений из 19, страница 1 из 1
18.01.2016, 10:19:06
    #39149369
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Привет всем, есть таблица с товарами, есть 2 прайс листа - один для нормальных товаров, другой для уцененных. В зависимости, побит ли жизнью товар или нет нужно выбирать цену (или прайс?). А если цены нет то как отфильтровать записи?
Приведу пример своего запроса (не работает):

SELECT *
FROM product
LEFT JOIN price normal_price on product.article=normal_price.article and normal_price.id_pricelist=1
LEFT JOIN price markdown_price on product.article=markdown_price.article and markdown_price.id_pricelist=2
GROUP BY product.id
HAVING IF(product.broken=1 OR product.damaged=1, markdown_price.low_value, normal_price.low_value) > 0

Помогите плиз написать верный запрос... и можно ли вообще без HAVING обойтись?
...
Рейтинг: 0 / 0
18.01.2016, 10:31:59
    #39149380
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Нафига вообще группировка? неужели в прайсе есть дубли по товару? Если да - какой смысл получать рандом? причём даже без гарантии, что из одной записи...
А вообще - начните с чёткого формулирования задачи. Тот поток сознания, что выше, на задачу не тянет даже приблизительно.
...
Рейтинг: 0 / 0
18.01.2016, 10:51:59
    #39149396
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

Задача: вывод списка товаров, цена выводится в зависимости от состояния товара. Если товар с повреждениями то цену брать из прайс листа 2. Если у битого товара не выставлена цена в прайсе №2 не выводить товар в списке.
...
Рейтинг: 0 / 0
18.01.2016, 11:03:13
    #39149400
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
polkiloЗадача: вывод списка товаров, цена выводится в зависимости от состояния товара. Если товар с повреждениями то цену брать из прайс листа 2. Если у битого товара не выставлена цена в прайсе №2 не выводить товар в списке.
Мля...
Как определить, что товар "с повреждениями"? на потолок поглядеть?
Структуры исходных данных с пояснениями - в студию (лишнее для задачи - поскипать).
...
Рейтинг: 0 / 0
18.01.2016, 11:19:39
    #39149414
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

За "повреждения" отвечают поля product.broken и product.damaged.
Вот таблица товаров:

CREATE TABLE ecs_20151118.esys_product (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
article char(20) NOT NULL COMMENT 'Артикул',
id_group int(11) UNSIGNED DEFAULT NULL COMMENT 'Группа',
name varchar(255) NOT NULL COMMENT 'Полное название',
description text NOT NULL COMMENT 'Описание',
broken tinyint(4) NOT NULL COMMENT 'С трещиной',
damaged tinyint(4) NOT NULL COMMENT 'Повреждения',
PRIMARY KEY (id),
INDEX article (article)
)
ENGINE = INNODB
AUTO_INCREMENT = 1
CHARACTER SET utf8
COLLATE utf8_general_ci
COMMENT = 'Товары';
...
Рейтинг: 0 / 0
18.01.2016, 11:24:08
    #39149423
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Таблица цен:

CREATE TABLE ecs_20151118.esys_price (
article char(20) NOT NULL COMMENT 'Артикул товара',
id_pricelist int(11) UNSIGNED NOT NULL COMMENT 'Прайс лист',
value decimal(10, 2) UNSIGNED NOT NULL COMMENT 'Цена',
PRIMARY KEY (article_product, id_pricelist)
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci
COMMENT = 'Цены';
...
Рейтинг: 0 / 0
18.01.2016, 11:31:09
    #39149429
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
polkiloПривет всем, есть таблица с товарами, есть 2 прайс листа - один для нормальных товаров, другой для уцененных. В зависимости, побит ли жизнью товар или нет нужно выбирать цену (или прайс?). А если цены нет то как отфильтровать записи?
Приведу пример своего запроса (не работает):

SELECT *
FROM product
LEFT JOIN price normal_price on product.article=normal_price.article and normal_price.id_pricelist=1
LEFT JOIN price markdown_price on product.article=markdown_price.article and markdown_price.id_pricelist=2
GROUP BY product.id
HAVING IF(product.broken=1 OR product.damaged=1, markdown_price.low_value, normal_price.low_value) > 0

Помогите плиз написать верный запрос... и можно ли вообще без HAVING обойтись?


нужно обходиться без group by и having
...
Рейтинг: 0 / 0
18.01.2016, 11:33:10
    #39149432
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
MasterZiv,


два left join плюс case-выражение для цены.

никаких group by не нужно.
...
Рейтинг: 0 / 0
18.01.2016, 11:37:03
    #39149439
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
С кейсами написал запрос, но как убрать GROUP BY и HAVING?

SELECT
products.*,
CASE WHEN (products.article_markdown is NOT NULL OR products.badpack>0 OR products.surplus>0 OR products.damaged>0 OR products.repaired>0 OR products.used>0)
THEN (SELECT low_value FROM esys_price WHERE article_product=products.article AND id_pricelist=16)
ELSE (SELECT low_value FROM esys_price WHERE article_product=products.article AND id_pricelist=90)
END AS price
FROM esys_product products
GROUP BY products.id
HAVING price>0
ORDER BY price
...
Рейтинг: 0 / 0
18.01.2016, 11:44:00
    #39149448
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Попробовал вот так:

SELECT
product.*,
CASE WHEN (product.broken>0 OR product.damaged>0)
THEN (SELECT value FROM price WHERE article=product.article AND id_pricelist=2)
ELSE (SELECT value FROM price WHERE article=product.article AND id_pricelist=1)
END AS price
FROM product
WHERE price>0

Выдает ошибку:
4 Unknown column 'price' in 'where clause' SQL9.sql 6 16

Where не понимает алиасов, как быть, растолкуйте пожалуйста...
...
Рейтинг: 0 / 0
18.01.2016, 12:33:03
    #39149502
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Связывание надо производить с учётом поля "повреждения". Т.е. типа
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
FROM product 
LEFT JOIN price
ON product.id=price.id 
AND (
        (product.broken=1 AND price.id_pricelist=2)
     OR (product.damaged=1 AND price.id_pricelist=2)
     OR (product.broken=0 AND product.damaged=0 AND price.id_pricelist=1)
    )


Ну а цену выводить, используя COALESCE, если не устраивает NULL для отсутствующих.
...
Рейтинг: 0 / 0
18.01.2016, 12:48:13
    #39149532
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

Огромное Вам спасибо!!! Вы гений ;) Благодаря Вам наконец то дошло, как работает JOIN! Здоровья Вам и удачи =)
...
Рейтинг: 0 / 0
21.01.2016, 12:32:05
    #39152180
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

А так можно?
Я думал будет быстро работать а на деле тормоза, подскажите, пожалуйста, может для таблицы Price создать какие-нить ключи?

FROM product
LEFT JOIN price
ON product.id=price.id
AND (
((product.broken=1 OR product.damaged=1) AND price.id_pricelist=2)
OR (product.broken=0 AND product.damaged=0 AND price.id_pricelist=1)
)
...
Рейтинг: 0 / 0
21.01.2016, 12:40:00
    #39152186
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
polkiloЯ думал будет быстро работать а на деле тормоза
Ясен пень - индексы-то побоку...
Лучше, конечно, переписать на UNION, чтобы избавиться от OR. Один подзапрос - один набор фильтров.
...
Рейтинг: 0 / 0
21.01.2016, 12:59:51
    #39152208
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

То есть никаким индексами это дело не ускорить?

Вот у меня была мысль про UNION, как то так:

(
-- нормальные товары
SELECT *
FROM product
JOIN price ON product.id=price.product_id and price.id_pricelist=1
WHERE product.broken=0 and product.damaged=0 and price.value>0
)
UNION
(
-- покалеченные товары
SELECT *
FROM product
JOIN price ON product.id=price.product_id and price.id_pricelist=2
WHERE (product.broken=1 or product.damaged=1) and price.value>0
)
LIMIT 30
...
Рейтинг: 0 / 0
21.01.2016, 13:02:26
    #39152210
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
polkiloкак то так:
Нет, не так. Во втором подзапросе OR. Поделите его на два. И замените звёзды на конкретный список полей.

PS. Используйте тег SRC для кода запросов.
...
Рейтинг: 0 / 0
21.01.2016, 13:17:21
    #39152221
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

Так?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
(
-- нормальные товары
SELECT product.name, price.value
FROM product 
JOIN price ON product.id=price.product_id and price.id_pricelist=1
WHERE product.broken=0 and product.damaged=0 and price.value>0
) 
UNION
(
-- треснутые товары
SELECT product.name, price.value
FROM product 
JOIN price ON product.id=price.product_id and price.id_pricelist=2
WHERE product.broken=1 and price.value>0
)
UNION
(
-- товары со значительными повреждениями
SELECT product.name, price.value
FROM product 
JOIN price ON product.id=price.product_id and price.id_pricelist=2
WHERE product.damaged=1 and price.value>0
)
LIMIT 30



Получается, что если в товаре 5 полей, содержащих информацию по типу повреждения, то будет дополнительно 5 union'ов.
Может я неправильно спроектировал базу? Подскажите, пожалуйста...
...
Рейтинг: 0 / 0
21.01.2016, 15:05:56
    #39152329
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
polkiloТак?
Наверное, всё-таки UNION ALL. Или может быть broken=1 и damaged=1 одновременно?

polkiloПолучается, что если в товаре 5 полей, содержащих информацию по типу повреждения, то будет дополнительно 5 union'ов.
Может я неправильно спроектировал базу?
Ну в общем денормализация налицо.
...
Рейтинг: 0 / 0
22.01.2016, 14:12:18
    #39153037
polkilo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация выборки
Akina,

Может тогда сделать таблицу с перечислением уценки? например такую:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE TABLE product_markdown (
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  id_product int(11) UNSIGNED NOT NULL,
  broken tinyint(4) NOT NULL COMMENT 'Разбит',
  damaged tinyint(4) NOT NULL COMMENT 'Повреждения',
  PRIMARY KEY (id),
  UNIQUE INDEX uk_art (product_id),
)
ENGINE = INNODB
COMMENT = 'Причины уценки товара';



а в таблице товаров создать поле с внешним ключом к этой таблице (product.id_markdown => product_markdown.id_product)

Тогда можно будет написать запрос к товарам с ценой:

Код: sql
1.
2.
3.
4.
5.
6.
FROM product 
LEFT JOIN price
ON product.id=price.id AND (
    (product.id_markdown IS NULL AND price.id_pricelist=1)
     OR (product.id_markdown=>1 AND price.id_pricelist=2)
    )



Но опять же в итоге выборка будет по условию OR... что же делать?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Фильтрация выборки / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]