Postgresql – Database VIEW with a dynamically changing filter

postgresqlview

I am trying to create a view based on a specific case. Following is my table:

Table Name: Calls

CustomerName | CallID | Timestamp | Quality | PacketLoss | Jitter

The goal is to create a view that can do the following:

  1. SELECT * FROM [VIEW NAME] WHERE TIMESTAMP BETWEEN {Start Time} AND {End Time}
  2. At this point the database need to go through the table and find top 5 CustomerNames with the most amount of rows where the Quality was marked as "Bad".
  3. The database will use the return as a filter and send me back all the rows that had one of the CustomerName's listed in top 5.

I tried this:

CREATE VIEW "Calls_View" 
AS (
SELECT * 
FROM "Calls" 
WHERE "CustomerName" IN (SELECT "CustomerName" 
                         FROM "Calls" 
                         WHERE "Quality"='Bad' 
                         GROUP BY "CustomerName" 
                         ORDER BY COUNT(*) DESC LIMIT 5) 
  AND "Quality"='Bad');

Is my logic correct?

Best Answer

You can't do what you want with a view. You have to use a function. Note that I didn't retain all your double quoting of identifiers, so you will have to put them back if you insist.

CREATE OR REPLACE FUNCTION public.calls_view(timestamp with time zone, timestamp with time zone)
 RETURNS SETOF calls
 LANGUAGE sql
AS $function$
SELECT *
FROM Calls
WHERE CustomerName IN (SELECT CustomerName
                         FROM Calls
                         WHERE Quality='Bad' and timestamp between $1 and $2
                         GROUP BY CustomerName
                         ORDER BY COUNT(*) DESC LIMIT 5)
  AND Quality='Bad' and timestamp between $1 and $2 
$function$

You can use it kind of like a view, but you must supply your parameters in parentheses, not a WHERE clause:

select * from calls_view(now() - interval '1 day', now());