How can I define a view that has two calculated fields, for instance...
('TableName'.'BlueSquares' + 'TableName'.'RedSquares') AS TotalSquares, ('TableName'.'BlueCirles' + 'TableName'.'RedCircles') AS TotalCircles
... and create a third calculated field that's based on the first two calculated fields, as in...
('ViewName'.'TotalSquares' + 'ViewName'.'TotalCircles') AS TotalShapes
...?
When I reference the first two calculated fields by name, I get a message that the fields are unknown.
Thanks!
Since subqueries are not allowed in views, you will need to simulate them by creating multiple views.
For example, this query will solve your issue if directly executed:
SELECT
TotalCircles + TotalSquares AS TotalShapes
FROM
(SELECT
BlueCirles + RedCircles AS TotalCircles,
BlueSquares + RedSquares AS TotalSquares
FROM
(SELECT
2 AS BlueCirles,
3 AS RedCircles,
4 AS BlueSquares,
5 AS RedSquares
) AS shapes
) as totals;
According to the MySQL documentation views have the restriction on not being able to contain subqueries in the FROM clause. To work around this limitation and turn this query into a view, break it up into 3 views (one for each subquery) with the last giving the desired combination of fields:
CREATE VIEW shapes AS
SELECT
2 AS BlueCirles,
3 AS RedCircles,
4 AS BlueSquares,
5 AS RedSquares;
CREATE VIEW totals AS
SELECT
BlueCirles + RedCircles AS TotalCircles,
BlueSquares + RedSquares AS TotalSquares
FROM
shapes;
CREATE VIEW result AS
SELECT
TotalCircles + TotalSquares AS TotalShapes
FROM
totals;
SELECT * FROM result;
...create a third calculated field that's based on the first two calculated fields...
As you've found, you can't reference computed columns in the same SELECT. Your options are to:
Duplicate the logic
MySQL doesn't support subqueries in views for some odd reason:
CREATE OR REPLACE VIEW your_view AS
SELECT t.BlueSquares + t.RedSquares AS TotalSquares,
t.BlueCirles + t.RedCircles AS TotalCircles,
t.BlueSquares + t.RedSquares + t.BlueCirles + t.RedCircles AS TotalShapes
FROM TABLE t
Layer the Views
Least recommended option...
CREATE OR REPLACE VIEW initial_view AS
SELECT t.BlueSquares + t.RedSquares AS TotalSquares,
t.BlueCirles + t.RedCircles AS TotalCircles,
FROM TABLE
CREATE OR REPLACE VIEW layered_view AS
SELECT iv.TotalSquares + iv.TotalCircles AS TotalShapes
FROM initial_view iv
Unfortunately, what you're trying to do isn't actually possible the way you're doing it. Generally, MySQL views can be viewed as a scripted SELECT. The results of a view aren't stored on the database separate from their source, but are rather calculated when you refer to the view.
Most of the time, MySQL uses the MERGE algorithm when you SELECT from a view. This means it merges the definition of your view and the SELECT statement referring to the view it to create a final SELECT it actually runs. As such, you can't really have a VIEW refer to itself.
Your options here are to (1) define a second view which refers to the first view in order to create your sum, or (2) write out the sum longhand like this:
('TableName'.'BlueSquares' + 'TableName'.'RedSquares' + 'TableName'.'BlueCirles' + 'TableName'.'RedCircles') AS TotalShapes