Generated columns using aggregate functions

后端 未结 2 1694
遥遥无期
遥遥无期 2021-01-22 11:47

The starting point

Suppose I have a table devTest that looks like this:

+----+------+  
| id | j    |  
+----+------+  
|  1 |    5 |  
|          


        
相关标签:
2条回答
  • 2021-01-22 12:32

    This error makes sense because any change in your table (say you add a j with value 0) would update your average, and this in turn would change all your generated columns. So this would be quite a bit of work for the query engine.

    Another solution would be to define a view instead:

    CREATE VIEW j_dev (id, j, j_dev) AS 
    SELECT id, j, 
           (j - avg(j)) / std(j) as j_dev
    FROM devTest
    

    (not sure about the create view syntax, correct me if I'm wrong)

    0 讨论(0)
  • 2021-01-22 12:44

    In standard SQL you'd do:

    select id, j, (j - avg(j) over ()) / std(j) over () as jdev
    from devtest;
    

    But MySQL doesn't support analytic window functions such as AVG OVER. So in MySQL, you must select the aggregation values separately:

    select d.id, d.j, (d.j - agg.javg) / agg.jstd as jdev
    from devtest d
    cross join (select avg(j) as javg, std(j) as jstd from devtest) agg;
    

    Then create a view as Benjamin Crouzier suggests in his answer:

    CREATE VIEW v_devtest AS
      select d.id, d.j, (d.j - agg.javg) / agg.jstd as jdev
      from devtest d
      cross join (select avg(j) as javg, std(j) as jstd from devtest) agg;
    

    A computed column can only calculate its value from other values in the same record. So what you are trying to do cannot be done with a calculated column.

    0 讨论(0)
提交回复
热议问题