Оптимизация SQL query

Оптимизация SQL query


Нашел интересную задачу из ЕГЭ по работе с базами данных через sqlite3

Я, недолго думая, написал вот такую query, которая выдала правильный ответ 30%

SELECT SUM(products_moving.quantity * products_moving.cost) * 100 / (
    SELECT SUM(products_moving.quantity * products_moving.cost) FROM products_moving
    JOIN shops ON products_moving.shop_id = shops.id
    WHERE products_moving.op_type = 'Продажа'
        AND shops.region = 'Октябрьский'
) FROM products_moving
JOIN products ON products_moving.article = products.article
JOIN shops ON products_moving.shop_id = shops.id
WHERE products_moving.op_type = 'Продажа'
    AND shops.region = 'Октябрьский'
    AND products.type = 'Молоко'

Но это далеко не самое красивое решение, ведь я, по идее, целых два раза ищу в базе данных все продажи в Октябрьском регионе. Мне стало очень интересно, можно ли как-то более красиво и изящно расписать эту query?

Первое что мне приходит на ум - это сначала найти все продажи в Октябрьском регионе, сохранить куда-то их, посчитать их сумму в рублях, сохранить эту сумму куда-то, потом уже из сохранённого ранее набора всех продаж в Октябрьском районе посчитать только все те, у которых была категория "Молоко", найти уже их сумму в рублях и посчитать процент

т.е. сделать что-то типа такого, но в SQL:

sales_in_region = filter(
    lambda row: row["op_type"] == 'Продажа' and row["region"] == 'Октябрьский',
    all_rows
)

sales_in_region_sum = sum(map(
    lambda row: row["quantity"] * row["cost"],
    sales_in_region
))

sales_in_region_milk = filter(
    lambda row: row["type"] == 'Молоко',
    sales_in_region
)

sales_in_region_milk_sum = sum(map(
    lambda row: row["quantity"] * row["cost"],
    sales_in_region_milk
))

print(sales_in_region_milk_sum // sales_in_region_sum * 100)

В рамках ЕГЭ конечно этот запрос оптимизировать нет никакого смысла, т.к. более одного раза я его не выполню и можно не париться, даже если он с десяток секунд занимает, но хочется знать, есть ли возможность как-то красиво обрабатывать такие кейсы?





Я придумал решение, которое уже заметно быстрее выполняется

SELECT 
    SUM(CASE WHEN products.type = 'Молоко' THEN products_moving.quantity * products_moving.cost END) 
    * 100 /  SUM(products_moving.quantity * products_moving.cost)
FROM products_moving
JOIN products ON products_moving.article = products.article
JOIN shops ON products_moving.shop_id = shops.id
WHERE products_moving.op_type = 'Продажа'
    AND shops.region = 'Октябрьский'

идея в том, чтобы с помощью оператора CASE фильтровать нужные строки внутри SUM






Report Page