Can you send a full result set to an SQL function? - postgresql

I am working in Postgres and I need to send in a full result set with many rows and column into a stored procedure or a function. Is this possible? If so, where can I see resources for syntax?
OK this is how I have it set up without being able to send in a result set, it forces me to break out comparison logic and put it in two different spots, however my goal is to keep the actual finding the promotion logic in one place, which I have done here. This may change one day, the comparison logic is less likely to change, it is pretty standard.
Promotion Line Item Logic
-There will be triggers set on INSERT for the promo_objects, promo_buy_objects, and promo_get_objects tables, there will be an UPDATE trigger on the promo table.
-The trigger for the xrefs will call a stored procedure called set_best_product_promos that will decide which promotion is best for that object and it will then save to a new table:
promo_best_product_promos
promo_id,
object_id,
expiration_date
-The trigger for promo will call update_best_product_promos and will send in the promo_id and if active = true it will update the expiration date for that promo else it will delete all entries for that promo
The new table has been added to the promo.sql script, however the triggers and function can not be added until the function is written.
A script will run at midnight every night to delete the entries that have expired.
PSEUDO FOR cart code (application code)
Run the union query just as we are now shown_object_promotions (this gets all available promotions for the item)
Loop through results
if buy_quantity > 0
IF the quantity of the buy item in the cart is greater than or = the buy_quantity (I think c.active_items is the items in the cart)
IF get_quantity > 0
If the get item is in the cart AND it is the item sent into this function (I think c.active_items is the items in the cart)
run the get_best_product_promos function
run comparison logic
else
run the get_best_product_promos function
run comparison logic
EDIT: So I guess I could dump this cart logic as a stored procedure as well, and then make one for the comparison logic, and boom its all in stored procedures and portable and generic?
PSEUDO FOR set_best_product_promos:
-You will send in the object_id and promo_id
-You will declare all of your variables
-Go ahead an query the end date of the promo
-You will then query the promo_best_product_promos table to see if an entry exists for this product
IF exists:
RUN YOUR UNION QUERY accept this time you will have to explicitly say all the fields you want and what variables to select them into
Then loop through your query
LOOP
run get_best_product_promos
run comparison logic
END LOOP
Now take those variables you set in the crazy logic and update promo_best_product_promos
ELSE:
insert the object_id, promo_id, and end date (expiration_date) into the promo_best_product_promos table
PSEUDO FOR get_best_product_promos:
If no buy and no get quantities
If discount type = percent
calculate value of the promotion for this item to compare later
calculate the new price for the product and update the estimated unit price
If discount type = dollar
calculate value of the promotion for this item to compare later
calculate the new price for the product and update the estimated unit price
If discount type = price
calculate value of the promotion for this item to compare later
calculate the new price for the product and update the estimated unit price
If discount amount = Free
do nothing
pass
If buy quantity but no get quantity
If discount type = percent
calculate value of the promotion for this item to compare later
If discount type = dollar
calculate value of the promotion for this item to compare later
If discount type = price
calculate value of the promotion for this item to compare later
If discount amount = Free
do nothing
pass
Else (assumes there is both buy and get)
IF the quantity of the buy item in the cart is >= the buy_quantity (I think c.active_items is the items in the cart)
If discount type = percent
calculate value of the promotion for this item to compare later
If discount type = dollar
calculate value of the promotion for this item to compare later
If discount type = price
calculate value of the promotion for this item to compare later
If discount amount = Free
#Use a different var here like in select_cart_promotion - they will always get this promotion
calculate the value of the promotion for these items
do something here to ensure the get product is in the cart

Take a look at cursors.

Postgres user defined functions can be written in many languages
On the formats of input and output parameters for PL/pgSQL you can check the documentation here
Are you sure that you need to pass this to a function? I believe you could structure your functions to avoid this, functions can return tables and get get tables inside of them. If this table of yours is a query/table/view then you can use SQL inside the function to get to it (passing only parameters of other data type); if this table is the result of another function you can call the function to get to the table. What's your scenario?

Related

Tableau KPI prev value depending on variable

am trying to get Previous Sum(of someField) based on a variable value which is an Id.
This is not a table, Im doing a KPI
On Qlik you would do something like:
SUM({<Id={"$(=Max(vVariable),-1))"}>} someField)
But I can not achieve it on Tableau, off course is due to my lack of knowledge, unfortunatelly time is tinking at work and wanted to see if anyone has any input!
Thanks
Assuming you may use a sample input like the Superstore (using sales as metric), this could be what you're looking for:
In red you can see your "variable" which allows you to select a value and in blue you'll find the unique row for the previous value (Order ID sorted).
The first thing you need to to do is creating a parameter based on all the Order ID values:
Then things start to get a bit complicated if you're not familiar with LOD (Level of details) and the order of execution in Tableau, especially for filters.
Assuming that you can get some information on your own (otherwise, feel free to ask), the first thing you nee to to do is to "pre-calculate" the equivalent of a table having a rowe for each Order ID, in which you also have the previous Order ID value.
You can achive this combining Fixed (LOD) and Lookup function, creating this Calculated Field "Lookup Order ID":
LOOKUP( max({ FIXED [Order ID] : MAX([Order ID])}),1)
This is actually just a calculated field that you want to "fix" because you need the filter to act after you have made that previous calculus, and then you shift your data by 1 row backward.
Once you've done that, you just nee to create another calculated field in order to test your parametric value, and it could be something like this "check param":
[Lookup Order ID] = [Order ID param]
Moving this calculated field in the filter section and selecting just "true" values, you'll get that unique rows like in the initial image, showing the previous value (blue) related to the one you select in the parameter drop-down menu (red).

Count at the end of a month in Tableau

I want to find the number of customers per subscription plan at the end of the acquisition month.
As you can see in the workbook, customers can change their subscription plan on any date, but I only want to find the subscription plan at the end of the acquisition month.
I created a field, called EOM Acquisition, but need to find the desired output below for any given month of acquisition. (in sample dataset only October).
How can I do that? Thanks in advance!
Please proceed like this. Create a new calculated field say calculation1 as follows-
IF [Date] = [EOM Acquisition] then [Subscription Plan] END
drag this field instead of subs plan in view and filter out null values, you'll get what you want
Another way add a calc field as follows
IF [Date] = [EOM Acquisition] then 1 ELSE 0 END
And thereafter add sum on this field as measure alongwith EOM and subscription fields.

how to use datediff properly tableau

basically i have the same problem with this and use this solution too https://community.tableau.com/s/question/0D54T00000C6aS6/datediff-in-lod
so i want to count time diff between transaction for each transaction and for each users, basically my problem is just like this
same with that, ON interaction id = user id in my real data, so i want to know time different between date transaction for each users.
based on that, i made this on calculation DATEDIFF('day',LOOKUP(MIN([Created At]),-1), MIN([Created At]))
and here's the results
what makes me confuse is, why the first transaction of users always have time difference, instead it must be nothing because there's no time difference if you do first transaction, so how to make it not appear?
Create a table calc field for First
FIRST()=0
Edit the table calc so it resets ever new user id.
Now filter for False. You can remove it from Rows, I just kept it there for demo. Your calculation will still work.

SSRS Grouping Summary - with Max not working

This is the data that comes back from the database
Data Sample for one season (the report returns values for two):
What you can see is groupings, by Season, Theater then Performance number and lastly we have the revenue and ticket columns.
The SSRS Report Has three levels of groupings. Pkg (another ID that groups the below), venue -- the venue column and perf_desc -- the description column linked tot he perf_no.
Looks like this --
What I need to do is take the revenue column (a unique value) for each Performance and return it in a separate column -- so i use this formula.
sum(Max(Fields!perf_tix.Value, "perf_desc"))
This works great, gives me the total unique value for each performance -- and sums them up by the pkg level.
The catch is when i need to pull the data out by season.
I created a separate column looks like this
it's yellow because it's invisible and is referenced elsewhere. But the expression is if the Season value = to the Parameter (passed season value) -- then basically pull the sum of each of the tix values and sum them up. This also works great on the lower line - the line where the grouping exists for pkg -- light blue in my case.
=iif(Fields!season.Value = Parameters!season.Value, Sum(Max(Fields!perf_tix.Value, "perf_desc")), 0)
However, the line above -- the parent/header line its giving me the sum of the two seasons values. Basically adding it all up. This is not what I want and also why is it doing this. The season value is not equal to the passed parameter for the second season value so why is it adding it to the grouped value.
How do I fix this??
Since your aggregate function is inside your IIF function, only the first record in your dataset is being evaluated. If the first one matches the parameter, all records would be included.
This might work:
=IIF(Fields!season.Value = Parameters!season.Value, Sum(Max(Fields!perf_tix.Value, "perf_desc")), 0)
It might be better if your report was also grouping on the Venue, otherwise you count may include all values.

Perform analysis on last three values of a FileMaker dataset

My end goal is to have a box change color when the last 3 records input into a field (based on the time of input) in FileMaker achieve a certain criteria (ex. variance < 2). I would like to know how to make this happen, or how a calculation/script can be written to only look at the last 3 records.
There are several ways you could approach this. A simple one would be to use a script to:
Show all records in the given table;
Unsort them (assuming they were entered in chronological order; otherwise sort them by creation timestamp);
Omit all records except the last three;
Get the value of a summary field defined as Standard Deviation of your value field;
Set a global variable/field to the square of the returned value.
Then use the global variable/field to conditionally format your "box".
If you don't want to use a script, you will have to define a relationship in order to get the last three values in the table, regardless of the current found set and/or sort order. Or you may use the ExecuteSQL() function for this.