Подтвердить что ты не робот

Можно ли повторно использовать вычисленное поле в запросе SELECT?

Есть ли способ повторного использования вычисленного поля в инструкции mysql. Я получаю сообщение об ошибке "unknown column 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-программе.

4b9b3361

Ответ 1

Да, вы можете повторно использовать переменные. Вот как вы это делаете:

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

[Примечание: Это поведение undefined. Согласно документам MySQL:]

Как правило, вы никогда не должны присваивать значение переменной пользователя и читать значение в пределах одного и того же оператора. Вы можете получить ожидаемые результаты, но это не гарантируется.

Ответ 2

В моем тестировании MySQL 5.5 работает хорошо:

SELECT 
    s.f1 + s.f2 as total_sale, 
    s.f1 / (SELECT total_sale) as f1_percent
FROM sales s

Ответ 3

Только межплатформенные поддерживаемые средства - это использование производного таблицы/встроенного представления:

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

Ответ 4

Вы можете использовать подвыбор:

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;

Ответ 5

Вы можете использовать подзапросы, например:

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

Edit:
фиксированный декартова продукт, предполагая, что первичный ключ id.
Это должно быть эквивалентно решению OMG Ponies после оптимизации, но я думаю, что это станет труднее читать, если вам нужно больше подзапросов.

Ответ 6

Я тестировал следующее и, похоже, работает все время, может быть, есть причина для этого, потому что я предопределл переменную @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

Ответ 7

Я просмотрел различные ответы здесь и сделал несколько экспериментов.

В частности, я использую 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, которая ссылается на первую. По качеству я вообще не знаю, как это устроить двойное <<22 > .