Search code examples
sqlsqlitelivecode

Is it possible to programmatically edit a SQLite CREATE VIEW statement?


I have a view that contains a number of nested views as shown below.

Main View:

CREATE VIEW `qryAttackRate` AS 
Select qryFoodInCases.fldCaseID,qryFoodInCases.fldFood,
AteAndGotSick,TotalAte,AteAttackRate,
NotAteAndGotSick,TotalNotAte,NotAteAttackRate,
ROUND(AteAttackRate/CAST(NotAteAttackRate AS FLOAT),2) RelativeRisk 
FROM qryFoodInCases
LEFT JOIN qryNotAteAttackRate QA
ON qryFoodInCases.fldFood=QA.fldFood
LEFT JOIN qryAteAttackRate QN
ON qryFoodInCases.fldFood=QN.fldFood
GROUP BY qryFoodInCases.fldFood
ORDER BY  RelativeRisk Desc

These are 2 of the sub views. There are a few more:

CREATE VIEW `qryAteAttackRate` 
AS SELECT qryFoodInCases.fldCaseID,qryFoodInCases.fldFood,
COALESCE(qryAteAndGotSick.AteAndGotSick,0) AteAndGotSick,
qryFoodInCases.fldFoodFrequency TotalAte,
 100*COALESCE(qryAteAndGotSick.AteAndGotSick,0)/
qryFoodInCases.fldFoodFrequency AteAttackRate
FROM qryFoodInCases
LEFT JOIN qryAteAndGotSick 
ON qryFoodInCases.fldFood=qryAteAndGotSick.fldFood
GROUP BY qryFoodInCases.fldFood


CREATE VIEW `qryFoodInCases` 
AS SELECT tblCases.fldCaseID,fldfood,
COUNT(tblFoodHistory.fldFoodID) AS fldFoodFrequency 
FROM tblFood 
INNER JOIN tblFoodHistory 
ON tblFoodHistory.fldFoodID=tblFood.fldFoodID)
INNER JOIN tblMealHistory 
ON tblFoodHistory.fldMealID=tblMealHistory.fldMealHistoryID)
INNER JOIN tblInterviews 
ON tblInterviews.fldInterviewID=tblMealHistory.fldInterviewID)
INNER JOIN tblCases 
ON tblCases.fldCaseID=tblInterviews.fldCaseID
GROUP BY tblCases.fldCaseID,tblFood.fldFood

I want to query the main view for each fldCaseID. Problem is, the WHERE condition when querying the main view does not apply to the subviews.

Other than creating a long complex SQL statement, is there a way to programmatically insert a WHERE condition into the sub views?

To illustrate the problem see the output of select * from qryAttackRate where fldcaseid=1 before and after adding a second case without making any change to data related to the first case Before

+-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+
    | fldCaseID |  fldFood   | AteAndGotSick | TotalAte | AteAttackRate | NotAteAndGotSick | TotalNotAte | NotAteAttackRate | RelativeRisk |
    +-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+
    |         1 | Beans      |             4 |        4 |           100 |                1 |           3 |               33 | 3.03         |
    |         1 | Cabagge    |             2 |        3 |            66 |                3 |           4 |               75 | 0.88         |
    |         1 | fried fish |             2 |        3 |            66 |                3 |           4 |               75 | 0.88         |
    |         1 | Banana     |             1 |        2 |            50 |                4 |           5 |               80 | 0.62         |
    |         1 | Pork       |             2 |        4 |            50 |                3 |           3 |              100 | 0.5          |
    |         1 | Chicken    |             1 |        3 |            33 |                4 |           4 |              100 | 0.33         |
    |         1 | Potatoes   |             0 |        2 |             0 |                5 |           5 |              100 | 0            |
    |         1 | Rice       |             0 |        2 |             0 |                5 |           5 |              100 | 0            |
    +-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+

After

+-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+
| fldCaseID |  fldFood   | AteAndGotSick | TotalAte | AteAttackRate | NotAteAndGotSick | TotalNotAte | NotAteAttackRate | RelativeRisk |
+-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+
|         1 | Cabagge    |             2 |        3 |            66 |                4 |           7 |               57 | 1.16         |
|         1 | fried fish |             2 |        3 |            66 |                4 |           7 |               57 | 1.16         |
|         1 | Pork       |             2 |        4 |            50 |                4 |           6 |               66 | 0.76         |
|         1 | Potatoes   |             0 |        2 |             0 |                6 |           8 |               75 | 0            |
+-----------+------------+---------------+----------+---------------+------------------+-------------+------------------+--------------+

Solution

  • A view always computes a fixed result set before any processing in the outer query is applied. (The database actually tries to optimize away unneeded processing in the view, but it will always behave as if the view were materialized in advance.)

    It is not possible to change a view (with parameters, or with any other mechanism).

    If your subqueries must change dynamically, you cannot use views. You must write them as subqueries, or (in SQLite 3.8.3 or later) as common table expressions.