Find max value in a group in FileMaker - filemaker

How to select only max values in a group in the following set
id productid price year
---------------------------
1 11 0,10 2015
2 11 0,12 2016
3 11 0,11 2017
4 22 0,08 2016
5 33 0,02 2016
6 33 0,01 2017
Expected result for each productid and max year would be
id productid price year
---------------------------
3 11 0,11 2017
4 22 0,08 2016
6 33 0,01 2017

This works for me.
ExecuteSQL (
"SELECT t.id, t.productid, t.price, t.\"year\"
FROM test t
WHERE \"year\" =
(SELECT MAX(\"year\") FROM test tt WHERE t.productid = tt.productid)"
; " " ; "")
Adapted from this answer:
https://stackoverflow.com/a/21310671/832407

A simple SQL query will give you a last year for every product record
ExecuteSQL (
"SELECT productid, MAX ( \"year\")
FROM myTable
GROUP By productid";
"";"" )
To get to the price for that year is going to be trickier, as FileMaker SQL does not fully support subqueries or temp tables.

Related

In Redshift SQL query for reducing years

i have data with fields as shown below
id
grade
grade_id
year
Diff
101
5
7
2022
9
105
k
2
2021
2
106
4
6
2020
5
110
pk
1
2022
1
i want to insert records for same id until we reaches grade = pk , Like shown below for every record in the table .
id
grade
grade_id
year
Diff
101
5
7
2022
9
101
4
6
2021
8
101
3
5
2020
7
101
2
4
2019
6
101
1
3
2018
5
101
k
2
2017
4
101
pk
1
2016
3
need help in sql code
create table amish.cte_test
(id int,
grade int,
year int,
diff int)
insert into amish.cte_test
values (101,5,2022,9)
with recursive temp1( id, grade, year, diff) as
(select id, grade , year , diff from amish.cte_test
union all
select id, grade-1, year-1,diff-1 from temp1
where grade-1 > -2)
select * from temp1

PostgresSQL: Fill values for null rows based on rows for which we do have values

I have the following table:
country year rank
1 Austria 2019 1
2 Austria 2018 NA
3 Austria 2017 NA
4 Austria 2016 NA
5 Spain 2019 2
6 Spain 2018 NA
7 Spain 2017 NA
8 Spain 2016 NA
9 Belgium 2019 3
10 Belgium 2018 NA
11 Belgium 2017 NA
12 Belgium 2016 NA
I want to fill in the NA values for 2018, 2017 and 2016 for each country with the value for 2019 (which we have).
I want the output table to look like this:
country year rank
1 Austria 2019 1
2 Austria 2018 1
3 Austria 2017 1
4 Austria 2016 1
5 Spain 2019 2
6 Spain 2018 2
7 Spain 2017 2
8 Spain 2016 2
9 Belgium 2019 3
10 Belgium 2018 3
11 Belgium 2017 3
12 Belgium 2016 3
I do not know where to get started with this question. I typically work with R but am now working on a platform which uses postgresSQL. I could do this in R but thought it would be worthwhile to figure out how it is done with postgres.
Any help with this would be greatly appreciated. Thank you.
Using an update to join to find the non NULL rank value for each country:
UPDATE yourTable AS t1
SET "rank" = t2.max_rank
FROM
(
SELECT country, MAX("rank") AS max_rank
FROM yourTable
GROUP BY country
) t2
WHERE t2.country = t1.country;
-- AND year IN (2016, 2017, 2018)
Add the commented out portion of the WHERE clause if you really only want to target certain years (your example seems to imply that you want to backfill all missing data).
If you just want to view your data in the format of the output, then use MAX as an analytic function:
SELECT country, year, MAX("rank") OVER (PARTITION BY country) AS "rank"
FROM yourTable
ORDER BY country, year DESC;
If you just want the output then
try this,
with cte as (
select distinct on (country) * from test
order by country, year desc
)
select
t1.id,t1.country,t1.year,t2.rank
from test t1 left join cte t2 on t1.country=t2.country
If you want to update your table then try this:
with cte as (
select distinct on (country) * from test
order by country, year desc
)
update test set rank=cte.rank from cte
where test.country=cte.country
DEMO

How to update one table from another table having more than 1 row with matching conditions? - in postgreSQL

I have table A with product_id,cost,year,quarter,... etc columns.
I have another table B with product_id,base_cost,current_year,p_year,p_quarter,p_order columns.
I want to write an update query to update A from B. My conditions are -
WHERE A.product_id=B.product_id
and A.year=B.current_year
and A.year=B.p_year and A.quarter>B.p_quarter
and A.cost=0;
But the problem is, with these conditions if i have more than one rows in B then i only want to update from the row of B which has the minimum of all quarters.
Example 1-
If A has one row as:
product_id cost year quarter
102 0 2019 1
102 0 2019 2
102 0 2019 3
102 0 2019 4
And B has two rows corresponding to the where clause:
product_id cost current_year p_year quarter
102 3.5 2019 2019 3
102 1.8 2019 2019 1
102 0.5 2019 2019 2
Then updated A should be:
product_id cost year quarter
102 0 2019 1
102 1.8 2019 2
102 1.8 2019 3
102 1.8 2019 4
This is a greatest-n-per-group problem which you need to apply to the table b in a sub-select:
UPDATE A
SET cost = B.base_cost
FROM (
select distinct on (product_id, current_year) product_id, current_year, cost
from b
order by product_id, current_year, quarter
) b
WHERE A.product_id = B.product_id
AND A.year = B.current_year
AND A.cost = 0

subtract two rows values using t-sql

i want to subtract values from of month 7 salary from month 8 salary
using t-sql can anyone help me i m new in tsql
ID Year Month Salary
1088 2017 8 -29766.250 0.000
1088 2015 7 -58.500 0.000
The simplest approach: use a subquery for each value (i.e. replace a and b in select a - b with subqueries):
select
(select salary from mytable where year = 2017 and month = 8) -
(select salary from mytable where year = 2015 and month = 7) as diff;

While loop to add data for pivot

Currently i have a requirement which needs a table to look like this:
Instrument Long Short 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 ....
Fixed 41 41 35 35 35 35 35 35 35 53 25 25
Index 16 16 22 22 22 32 12 12 12 12 12 12
Credits 29 29 41 16 16 16 16 16 16 16 16 16
Short term 12 12 5 5 5 5 5 5 5 5 5 17
My worktable looks like the following:
Instrument Long Short Annual Coupon Maturity Date Instrument ID
Fixed 10 10 10 01/01/2025 1
Index 5 5 10 10/05/2016 2
Credits 15 15 16 25/06/2020 3
Short term 12 12 5 31/10/2022 4
Fixed 13 13 15 31/03/2030 5
Fixed 18 18 10 31/01/2019 6
Credits 14 14 11 31/12/2013 7
Index 11 11 12 31/10/2040 8
..... etc
So basically the long and the short in the pivot should be the sum of each distinct instrument ID. And then for each year i need to take the sum of each Annual Coupon until the maturity date year where the long and the coupon rate are added together.
My thinking was that i had to create a while loop which would populate a table with a record for each year for each instrument until the maturity date, so that i could then pivot using an sql pivot some how. Does this seem feasible? Any other ideas on the best way of doing this, particularly i might need help on the while loop?
The following solution uses a numbers table to unfold ranges in your table, performs some special processing on some of the data columns in the unfolded set, and finally pivots the results:
WITH unfolded AS (
SELECT
t.Instrument,
Long = SUM(z.Long ) OVER (PARTITION BY Instrument),
Short = SUM(z.Short) OVER (PARTITION BY Instrument),
Year = y.Number,
YearValue = t.AnnualCoupon + z.Long + z.Short
FROM YourTable t
CROSS APPLY (SELECT YEAR(t.MaturityDate)) x (Year)
INNER JOIN numbers y ON y.Number BETWEEN YEAR(GETDATE()) AND x.Year
CROSS APPLY (
SELECT
Long = CASE y.Number WHEN x.Year THEN t.Long ELSE 0 END,
Short = CASE y.Number WHEN x.Year THEN t.Short ELSE 0 END
) z (Long, Short)
),
pivoted AS (
SELECT *
FROM unfolded
PIVOT (
SUM(YearValue) FOR Year IN ([2013], [2014], [2015], [2016], [2017], [2018], [2019], [2020],
[2021], [2022], [2023], [2024], [2025], [2026], [2027], [2028], [2029], [2030],
[2031], [2032], [2033], [2034], [2035], [2036], [2037], [2038], [2039], [2040])
) p
)
SELECT *
FROM pivoted
;
It returns results for a static range years. To use it for a dynamically calculated year range, you'll first need to prepare the list of years as a CSV string, something like this:
SET #columnlist = STUFF(
(
SELECT ', [' + CAST(Number) + ']'
FROM numbers
WHERE Number BETWEEN YEAR(GETDATE())
AND (SELECT YEAR(MAX(MaturityDate)) FROM YourTable)
ORDER BY Number
FOR XML PATH ('')
),
1, 2, ''
);
then put it into the dynamic SQL version of the query:
SET #sql = N'
WITH unfolded AS (
...
PIVOT (
SUM(YearValue) FOR Year IN (' + #columnlist + ')
) p
)
SELECT *
FROM pivoted;
';
and execute the result:
EXECUTE(#sql);
You can try this solution at SQL Fiddle.