Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дублирование стобцов с одинаковым именем, Дублировать или использовать много JOIN 
V
    Опции темы
fridkaratel
Дата 29.11.2012, 05:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 221
Регистрация: 22.10.2007
Где: Error connect to MySQL Da...

Репутация: нет
Всего: нет



А как быть в таком случае?

Код

client:
- ClientId    = ID клиента (AUTO_INCREMENT)
- Name        = Имя клиента
- ManagerId    = Пользователь, чей это клиент (кто его обслуживает)

client_booking_commodity
- BookingCommodityId    = ID для связывания между другими таблицами
- ClientId                = ID клиента, заказавшего товар
- Sku                    = Артикул товара
- BookingQty            = Заказанное количество
- ReserveQty            = Количество, которое зарезервировано со склада
- IssueQty                = Выданное количество


Менеджеру необходимо сформировать заявку на основной склад.
Для этого необходимо получить список долгов его клиентам: DebtQty = BookingQty - ReserveQty - IssueQty

Получается, если не дублировать данные в другой таблице, то выходит такой запрос:
Код

SELECT
    SUM(cbc.BookingQty - cbc.ReserveQty - cbc.IssueQty) AS DebtQty,        -- Считаем количество долгов
    cbc.Sku

FROM
    `client_booking_commodity` cbc        -- Заказанные клиентами товары

RIGHT JOIN
    `client` c            -- Чтобы выбрать только клиентов менеджера с ID=10
    ON
        c.ClientId = cbc.ClientId
        AND
        c.ManagerId = 10

WHERE
    cbc.BookingQty > cbc.ReserveQty + cbc.IssueQty        -- Если товар есть в долгах

GROUP BY
    cbc.Sku        -- Группируем по артикулу, чтобы получить общую заявку


Не медленный он будет?
Ведь, получается, чем больше клиенты заказывают, тем больше данных надо проверить...

С ходу я вижу, что тут надо добавить столбец Status = TINYINT(1) unsigned, который будет содержать 1, если нет долгов и 0, если есть...
Тогда не придётся просчитывать DebtQty...

Как вариант, не добавлять столбец Status, а сделать столбец DebtQty, в который будет записываться количество долга.
Но в этом случае, надо будет при изменении количества заказа (или резерва) изменять ещё и количество долга.

К тому же, меня смущает то, что мне надо делать LEFT JOIN на таблицу `client`, чтобы узнать, относится ли этот клиент к этому менеджеру.
А если менеджеров будет тысяч 5-10 и клиентов на каждого менеджера тоже тысяч по 5-10?

----------------------------------------------------------------

Попутно возник ещё вопрос...

1. Мне надо отобразить список долгов, сгруппированных по артикулу, чтобы оформить заявку на основной склад.
2. Но мне так же надо получить BookingCommodityId и DebtQty, чтобы выставить на резерв товары, которые есть на складе.

Получается такой запрос...
Постарался в SQL-комментариях расписать, что да как...

Код

SELECT
    cbc.BookingCommodityId,    -- Надо только в случае 2
    (cbc.BookingQty - cbc.IssueQty - cbc.ReserveQty) DebtQty,    -- Надо в случаях 1 и 2

    cc.Sku,        -- Надо только в случае 1
    cc.Title,    -- Надо только в случае 1
    cc.Price,    -- Надо только в случае 1
    cc.Pack        -- Надо только в случае 1

FROM
    `client_booking_commodity` cbc

RIGHT JOIN
    `client` c
    ON
        c.ClientId=cbc.ClientId
        AND
        c.ManagerId = 10

RIGHT JOIN                    -- RIGHT, чтобы отсеить товары, которые нельзя получить с основного склада - сняты с продажи
    `catalog_commodity` cc
    ON
        cc.Sku = cbc.Sku
        AND
        cc.ObsoleteDate = 0        -- Дата снятия товара с продажи

WHERE
    cbc.BookingQty > cbc.IssueQty + cbc.ReserveQty

GROUP BY cbc.Sku    -- Надо только в случае 1, т.к. в случае 2 мне надо получить BookingCommodityId, который я не получу при группировке


Имеет ли смысл делать два конкретных запроса?
Или можно обойтись одним, просто группируя в PHP-скрипте по артикулу?

Это сообщение отредактировал(а) fridkaratel - 29.11.2012, 05:52
PM   Вверх
Arantir
Дата 29.11.2012, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 1
Всего: 55



Цитата(fridkaratel @  29.11.2012,  04:46 Найти цитируемый пост)
Не медленный он будет?

Если вы не будете пробовать получить все пару сотен тысяч записей сразу, то разницы с JOIN и без него вы не заметите.
В базах данных логарифмические алгоритмы посика. Видели график логарифма? Вот, увеличиваете количество на очень-очень много, а время увеличивается на чуть-чуть. И сортировка тоже логарифмическая. Невозможно сделать логарифмической только выборку. Так как N штук меньше чем за N действий не выберешь.

У вас на пинг между серверами времени больше будет тратится, чем у БД на обработку запросов. Посмотрите на этот форум: [ Время генерации скрипта: 0.3409 ]. А страница появляется далеко не моментально из-за пинга и загрузки информации.

Если вас беспокоит, придется ли менеджеру ждать несколько секунд после нажатия на кнопочку - БД тут точно будет ни при чем.
Если вас беспокоит, не упадет ли БД от множества неэффективных запросов - даже средний домашний компьютер вытянул бы 1тыс. INSERT'ов в секунду, в SELECT'ов и того больше.
Посчитайте: если 15000 менеджеров будут каждые 15 минут оформлять заказ и выполнять при этом по 10 запросов, то это выйдет в среднем 160 запросов в секунду. Если не считать утрированности этой ситуации, то это вообще очень мало.


Цитата(fridkaratel @  28.11.2012,  00:16 Найти цитируемый пост)
Я думал так сделать, но в таком случае получается, что четыре столбца будут дублировать значения: IssueDate, UserIdFrom, UserIdTo и Comment. 

Далеко не все должно иметь вид лога =) Можно изменять и уже имеющиеся записи. Впрочем да, если надо к каждому изменению комментарий, то надо отдельную таблицу для этого.

Цитата(fridkaratel @  29.11.2012,  04:46 Найти цитируемый пост)
Имеет ли смысл делать два конкретных запроса?

Вот и спрашиваю, почему вы все в один запрос пытаетесь вместить...
Посмотрите на это форум: [ Использовано запросов: 35 ]223 гостей, 15 пользователей. И сервер же не падает.

Я не буду отрицать того факта, что оптимизированные скрипты и запросы и т.д. т.п. - это очень хорошо. Но, думаю, у вас в данный момент недостаточно опыта, чтобы взять так вот с сделать все совершенным. Сделайте для начала просто хорошо. Так чтобы все просто работало. А если уж там будет тормозить - попробуете оптимизировать.

Это сообщение отредактировал(а) Arantir - 29.11.2012, 08:26


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
fridkaratel
Дата 29.11.2012, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 221
Регистрация: 22.10.2007
Где: Error connect to MySQL Da...

Репутация: нет
Всего: нет



@Arantir, спасибо за развёрнутый ответ ;)

Буду делать smile
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Общие вопросы по базам данных"
LSD
Zloxa

Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:

  • вопросам по СУБД для которых нет отдельных подфорумов
  • вопросам которые затрагивают несколько разных СУБД (например проблема выбора)
  • инструменты для работы с СУБД
  • вопросы проектирования БД
  • теоретически вопросы о СУБД

Данный форум не предназначен для:

  • вопросов о поиске разлиных БД (если не понимаете чем БД отличается от СУБД то: а) вам не сюда; б) Google в помощь)
  • обсуждения проблем с доступом к СУБД из различных ЯП (для этого есть соответсвующие форумы по каждому ЯП)
  • обсуждения проблем с написание SQL запросов, для этого есть форум Составление SQL-запросов
  • просьб о написании курсовой, реферата и т.п., для этого есть Центр помощи или фриланс биржа
  • объявлений о найме специалистов, для этого есть раздел Объявления о найме специалистов

Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение. ;)


Полезные советы:

При написании сообщения постарайтесь дать теме максимально понятное название. В теме максимально подробно опишите проблему. Если применимо укажите: название базы данных и версии (MySQL 4.1, MS SQL Server 2000 и т.п.); используемых язык программирования; способа доступа (ADO, BDE и т.д.); сообщения об ошибках.

Для вставки кода используйте теги [code=sql] [/code].

Литературу по базам данных можно поискать здесь.

Действия модераторов можно обсудить здесь.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | СУБД, общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0705 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.