Простите, ещё одна задача.
3) Provide a list of the order types, ordered by the absolute difference between the average price and the median price. I.e the last order type X has the biggest difference when comparing the average price of X against the median price of X.
Suppose we have schema:
Order_Type (
id primary key (int),
name (varchar)
)
Order (
id primary key (int),
order_type_id foreign key to order_type (int),
price (double)
)
We have lots of orders for each order type. Suppose we have around a dozen order types and around 100k orders.
Order_Type
id primary key (int) || name (varchar)
Order
id primary key (int) || order_type_id foreign key to order_type (int) || price (double)
Ответ(?):
/*Создаём вспомогательную таблицу Order_type_with_abs_diff_AP_MP для хранения абсолютной разности между средней ценой (СЦ) и медианной ценой (МЦ) заказов по каждому типу.*/
CREATE TABLE Order_type_with_abs_diff_AP_MP (
id INT NOT NULL PRIMARY KEY,
/*Для следующей колонки abs_diff определяем возможность значения NULL, если, к примеру, заказов данного типа ещё не было.*/
abs_diff DOUBLE NULL);
/*Определяем минимальный id типа заказа*/
DECLARE @min_oreder_type_id INT;
SELECT @min_oreder_type_id=MIN(id) FROM Order_Type;
/*Определяем максимальный id типа заказа*/
DECLARE @max_oreder_type_id INT;
SELECT @max_oreder_type_id=MAX(id) FROM Order_Type;
/*Определяем переменную для хранения вычисленной абсолютной разницы между СЦ и МЦ для конкретного типа заказа.*/
DECLARE @abs_diff_v DOUBLE;
DECLARE @i INT;
/*Присваиваем вспомогательной переменной @i минимальное id типа заказа.*/
SET @i=@min_oreder_type_id;
/*Запускаем цикл выборки по всем типам заказа (по их id в переменной @i), в котором вычисляем абсолютную разность между СЦ и МЦ по каждому типу заказа и добавляем эту разность в созданную таблицу Order_type_with_abs_diff_AP_MP.*/
WHILE @i<=@max_oreder_type_id
BEGIN
SELECT
@abs_diff_v=ABS(AVG(price)-(MAX(price)+MIN(price))/2)
FROM ORDER
WHERE ORDER.order_type_id =@i;
INSERT INTO Order_type_with_abs_diff_AP_MP (id, abs_diff)
VALUES (@i, @abs_diff_v);
SET @i=@i+1;
END;
/*Отображаем на экран id типа заказа, название типа и его абсолютную разность, выбираем только те типы, для которых абсолютная разность не NULL, т.е. заказы такого типа были, и сортируем их в порядке возрастания абсолютной разности.*/
SELECT Order_Type.id, name, abs_diff
FROM Order_Type, Order_type_with_abs_diff_AP_MP
WHERE Order_Type.id=Order_type_with_abs_diff_AP_MP.id
AND Order_type_with_abs_diff_AP_MP.abs_diff IS NOT NULL
ORDER BY abs_diff;
/*Можно ли уже в следующей команде удалить вспомогательную таблицу?
DROP TABLE Order_type_with_abs_diff_AP_MP;
*/
Ещё пара вопросов. Команда
SELECT CONCAT(‘The USER ’, CONVERT(VARCHAR, Users.id), ‘ ‘, name,
‘ made an ORDER ’, CONVERT(VARCHAR, Orders.id), ‘ at ’,
CONVERT(VARCHAR, created_at))
для пустой выборки отобразит что-то на экран?
Можно ли так писать:
SELECT Order_Type.id, name, abs_diff
FROM Order_Type, Order_type_with_abs_diff_AP_MP
WHERE Order_Type.id=Order_type_with_abs_diff_AP_MP.id
если в двух разных таблицах первые столбцы названы одинаково?
Значения переменных SQL, наверняка(?), распознает в команде:
INSERT INTO Order_type_with_abs_diff_AP_MP (id, abs_diff)
VALUES (@i, @abs_diff_v);
Буду очень признателен, если вы пробежитесь глазами по синтаксису команд.