Можно ли повторно использовать вычисляемое поле в запросе SELECT?
Есть ли способ повторно использовать вычисляемое поле в операторе mysql. Я получаю ошибку "неизвестный столбец total_sale" для:
SELECT
s.f1 + s.f2 as total_sale,
s.f1 / total_sale as f1_percent
FROM sales s
или я должен повторить вычисление, которое сделало бы для очень длинного оператора SQL, если бы я добавил все вычисления, которые мне нужны.
SELECT
s.f1 + s.f2 as total_sale,
s.f1 / (s.f1 + s.f2) as f1_percent
FROM sales s
Конечно, я могу сделать все расчеты в моей программе PHP.
7 ответов
Да, вы можете повторно использовать переменные. Вот как вы это делаете:
SELECT
@total_sale := s.f1 + s.f2 as total_sale,
s.f1 / @total_sale as f1_percent
FROM sales s
Подробнее об этом читайте здесь: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html
[Примечание: это поведение не определено. Согласно документации MySQL:]
Как правило, вы никогда не должны присваивать значение пользовательской переменной и читать значение в том же выражении. Вы можете получить ожидаемые результаты, но это не гарантировано.
Следующее, похоже, хорошо работает в моем тестировании на MySQL 5.5:
SELECT
s.f1 + s.f2 as total_sale,
s.f1 / (SELECT total_sale) as f1_percent
FROM sales s
Только кроссплатформенные средства поддерживаются с помощью производного табличного / встроенного представления:
SELECT x.total_sale,
x.f1 / x.total_sale as f1_percent
FROM (SELECT s.f1,
s.f1 + s.f2 as total_sale,
FROM sales s) x
Вы можете использовать дополнительный выбор:
select tbl1.total_sale,
tbl1.f1/tbl1.total_sale as f1_percent
from (select s.f1+s.f2 AS total_sale,
s.f1
from sales s) as tbl1;
Вы можете использовать подзапросы, например так:
SELECT
h.total_sale,
s.f1 / h.total_sale AS f1_percent
FROM sales s,
(SELECT id, f1 + f2 AS total_sale FROM sales) h
WHERE
s.id = h.id
Редактировать:
фиксированное декартово произведение, предполагая, что первичный ключ id
,
Это должно быть эквивалентно решению OMG Ponies после оптимизации, но я думаю, что будет труднее читать, если вам нужно больше подзапросов.
Я посмотрел на различные ответы здесь и сделал несколько экспериментов.
В частности, я использую MariaDB 10.1.
Для "простой" вещи вы можете сделать то, что Роберт Д. предложил в своем комментарии:
SELECT Price_Per_SqFt, (Price_Per_SqFt/2) AS col1, (SELECT col1 + 1) AS col2 FROM Items
Если вы используете какую-либо агрегатную функцию с внутренним объединением, вы не можете использовать это, но вы можете объединить этот подход с подходом внутреннего объединения следующим образом (NB VAT = "налог с продаж"... и NB в валюте финансовых данных поля обычно имеют 4 знака после запятой, я думаю, что это историческое...)
SELECT
invoices.invoiceNo, invoices.clientID, invoices.Date, invoices.Paid,
invoicesWithSubtotal.Subtotal,
ROUND( CAST( Subtotal * invoices.VATRate AS DECIMAL( 10, 4 )), 2 ) AS VAT,
(SELECT VAT + Subtotal) AS Total
FROM invoices
INNER JOIN
( SELECT Sum( invoiceitems.Charge ) AS Subtotal, invoices.InvoiceNo FROM invoices
INNER JOIN invoiceitems ON invoices.InvoiceNo = invoiceitems.InvoiceNo
GROUP BY invoices.InvoiceNo ) invoicesWithSubtotal
ON invoices.InvoiceNo = invoicesWithSubtotal.InvoiceNo
Я хотел использовать выше, чтобы создать View
перечислить счета с их промежуточными итогами, НДС и итоговыми данными... оказалось, что MariaDB (и почти наверняка MySQL) не допускает вложение в FROM
пункт. Однако это легко решить, сделав первый View
который перечисляет InvoiceNo
а также Subtotal
и затем сделать второй View
который ссылается на первый. Что касается производительности, я понятия не имею об этомView
расположение.
Я тестировал следующее, и оно, кажется, работает все время, возможно, есть причина для этого, потому что я предопределил переменную @total_sales как значение, а не строку, и не переопределил ее тип во время выбора заявление??
Если я сделаю следующее
set @total_sales = 0;
SELECT
@total_sale := s.f1 + s.f2 as total_sale,
s.f1 / @total_sale as f1_percent
FROM sales s