Невозможно создать псевдоним для простого оператора CASE

#mysql #aliasing

#mysql

Вопрос:

Привет всем, я новичок в MySQL server и пытаюсь выполнить задание для класса. Кажется, я не могу найти решение. Любая помощь очень ценится. Вот мой код, а вот инструкция об ошибке. Заранее благодарю вас.

Оператор ОШИБКИ:

ОШИБКА 1054 (42S22) в строке 1: неизвестный столбец ‘Total_Number_Forced_Outage_Events’ в ‘списке полей’


 SELECT 
 
SUM(CASE 

WHEN Reason = 'Forced' THEN 1 ELSE 0 END) AS Total_Number_Forced_Outage_Event,

Count(*)AS Total_Number_Outage_Events,

Total_Number_Forced_Outage_Events / Total_Number_Outage_Events AS Forced_Outage_Percentage,

YEAR(Start_Time) AS Year

FROM AEMR 

WHERE Status = 'Approved' 

GROUP BY Year 

ORDER BY Year 

;
 

Комментарии:

1. Псевдоним столбца не может быть использован в выражении другого столбца. Либо используйте само выражение, либо используйте подзапрос.

2. Total_Number_Forced_Outage_Event != Total_Number_Forced_Outage_Events — У одного есть s в конце.

3. Ах, как я это пропустил! … Спасибо, Андреас!

Ответ №1:

Как прокомментировал @Akina выше, вы не можете ссылаться на псевдоним в том же запросе, где он определен.

Однако вы можете определить псевдоним в подзапросе и использовать его во внешнем запросе:

 SELECT t.*,
  Total_Number_Forced_Outage_Events / Total_Number_Outage_Events
    AS Forced_Outage_Percentage
FROM (
    SELECT 
      SUM(CASE WHEN Reason = 'Forced' THEN 1 ELSE 0 END)
        AS Total_Number_Forced_Outage_Events,
      COUNT(*) AS Total_Number_Outage_Events,
      YEAR(Start_Time) AS Year
    FROM AEMR 
    WHERE Status = 'Approved' 
    GROUP BY Year 
) AS t
ORDER BY Year;
 

t в этом примере приведен псевдоним таблицы для подзапроса.

Исключение: MySQL позволяет использовать псевдоним, определенный в том же запросе в GROUP BY предложениях , HAVING , и ORDER BY .

Также прочитайте документацию об псевдонимах столбцов в https://dev.mysql.com/doc/refman/8.0/en/select.html и https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html

Комментарии:

1. Спасибо, Билл. Очень признателен . и будет сделано!

Ответ №2:

CASE WHEN Reason = 'Forced' THEN 1 ELSE 0 END точно так же, как Reason = 'Forced' , поскольку MySQL (и MariaDB) используют 1 и 0 в качестве логических значений.

Таким образом, вы можете просто использовать SUM(Reason = 'Forced') для получения Total_Number_Forced_Outage_Events.

Кроме того, COUNT(Reason = 'Forced') даст вам Total_Number_Outage_Events, поскольку будут учитываться как единицы, так и нули (это не особенно полезно в вашем случае, но объясняет, почему следующее предложение верно).

Наконец, AVG(Reason = 'Forced') даст вам Forced_Outage_Percentage (поскольку AVG(x) по сути SUM(x) / COUNT(x) ).

Итак, один из способов написать ваш запрос:

 SELECT 
  SUM(Reason = 'Forced') AS Total_Number_Forced_Outage_Event,
  COUNT(Reason = 'Forced') AS Total_Number_Outage_Events,
  AVG(Reason = 'Forced') AS Forced_Outage_Percentage,
  YEAR(Start_Time) AS Year
FROM AEMR 
WHERE Status = 'Approved' 
GROUP BY Year 
ORDER BY Year 
;
 

который, я считаю, достаточно лаконичен.

Обратите внимание, что запись COUNT(Reason = 'Forced') вместо COUNT(*) может быть более эффективной, поскольку оптимизатор, вероятно, увидит это SUM(x) COUNT(x) и AVG(x) будет использоваться в той же области и выполнять три вычисления одновременно.