looking for parameter help with filemaker "list" function - filemaker

I'm trying to get the following equation to return the results comma separated on a single line. Right now it leaves out the commas and puts each result on a separate line. I've tried with and without the paragraph symbol.
List (If ( ${1} = "Spare" and panelSize ≥ 1 ; "1" ; "" ) ;
If ( ${2} = "Spare" and panelSize ≥ 2 ; "2" ; "" ) ;
If ( ${3} = "Spare" and panelSize ≥ 3 ; "3" ; "" ) ;
If ( ${4} = "Spare" and panelSize ≥ 4 ; "4" ; "" ) ;
If ( ${5} = "Spare" and panelSize ≥ 5 ; "5" ; "" ) ;
If ( ${6} = "Spare" and panelSize ≥ 6 ; "6" ; "" ) ;
If ( ${7} = "Spare" and panelSize ≥ 7 ; "7" ; "" ) ;
If ( ${8} = "Spare" and panelSize ≥ 8 ; "8" ; "" ) ;
If ( ${9} = "Spare" and panelSize ≥ 9 ; "9" ; "" ) ;
If ( ${10} = "Spare" and panelSize ≥ 10 ; "10" ; "" ) ;
If ( ${11} = "Spare" and panelSize ≥ 11 ; "11" ; "" ) ;
If ( ${12} = "Spare" and panelSize ≥ 12 ; "12" ; "" ) ;
If ( ${13} = "Spare" and panelSize ≥ 13 ; "13" ; "" ) ;
If ( ${14} = "Spare" and panelSize ≥ 14 ; "14" ; "" ) ;
If ( ${15} = "Spare" and panelSize ≥ 15 ; "15" ; "" ) ;
If ( ${16} = "Spare" and panelSize ≥ 16 ; "16" ; "" ) ;
If ( ${17} = "Spare" and panelSize ≥ 17 ; "17" ; "" ) ;
If ( ${18} = "Spare" and panelSize ≥ 18 ; "18" ; "" ) ;
If ( ${19} = "Spare" and panelSize ≥ 19 ; "19" ; "" ) ;
If ( ${20} = "Spare" and panelSize ≥ 20 ; "20" ; "" ) ;
If ( ${21} = "Spare" and panelSize ≥ 21 ; "21" ; "" ) ;
If ( ${22} = "Spare" and panelSize ≥ 22 ; "22" ; "" ) ;
If ( ${23} = "Spare" and panelSize ≥ 23 ; "23" ; "" ) ;
If ( ${24} = "Spare" and panelSize ≥ 24 ; "24" ; "" ) ;
If ( ${25} = "Spare" and panelSize ≥ 25 ; "25" ; "" ) ;
If ( ${26} = "Spare" and panelSize ≥ 26 ; "26" ; "" ) ;
If ( ${27} = "Spare" and panelSize ≥ 27 ; "27" ; "" ) ;
If ( ${28} = "Spare" and panelSize ≥ 28 ; "28" ; "" ) ;
If ( ${29} = "Spare" and panelSize ≥ 29 ; "29" ; "" ) ;
If ( ${30} = "Spare" and panelSize ≥ 30 ; "30" ; "" ) ;
If ( ${31} = "Spare" and panelSize ≥ 31 ; "31" ; "" ) ;
If ( ${32} = "Spare" and panelSize ≥ 32 ; "32" ; "" ) ;
If ( ${33} = "Spare" and panelSize ≥ 33 ; "33" ; "" ) ;
If ( ${34} = "Spare" and panelSize ≥ 34 ; "34" ; "" ) ;
If ( ${35} = "Spare" and panelSize ≥ 35 ; "35" ; "" ) ;
If ( ${36} = "Spare" and panelSize ≥ 36 ; "36" ; "" ) ;
If ( ${37} = "Spare" and panelSize ≥ 37 ; "37" ; "" ) ;
If ( ${38} = "Spare" and panelSize ≥ 38 ; "38" ; "" ) ;
If ( ${39} = "Spare" and panelSize ≥ 39 ; "39" ; "" ) ;
If ( ${40} = "Spare" and panelSize ≥ 40 ; "40" ; "" ) ;
If ( ${41} = "Spare" and panelSize ≥ 40 ; "41" ; "" ) ;
If ( ${42} = "Spare" and panelSize ≥ 42 ; "42" ; "" ) ; ¶ ; ", " )
The result returns each entry on it's own line with no comma. I tried it with and without the ¶.

Your list function puts them all into a list, and also puts the pilcrow ( ¶ ) and the ", " in the list as well. The other suggestion to use Substitute was close but not quite. Leave the List there, but add a Substitute to the start.
Substitute ( List ( allyourvalueshere ) ; ¶ ; ", " )
This takes your list and changes all the returns to commas.

Try adding the "substitute" function before the "list" function.

Related

Calculate Max and min dates

i'm trying to calculate the max ( and min )  of a date.
My situation is the following.
I've create a date table like this:
Date =
ADDCOLUMNS (
CALENDAR (DATE(2008;1;1); DATE(2020;12;31));
"DateAsInteger"; FORMAT ( [Date]; "YYYYMMDD" );
"Year"; YEAR ( [Date] );
"Monthnumber"; FORMAT ( [Date]; "MM" );"Daynumber"; FORMAT ( [Date]; "DD" );
"YearMonthnumber"; FORMAT ( [Date]; "YYYY/MM" );
"YearMonthShort"; FORMAT ( [Date]; "YYYY/mmm" );
"MonthNameShort"; FORMAT ( [Date]; "mmm" );
"MonthNameLong"; FORMAT ( [Date]; "mmmm" );
"DayOfWeekNumber"; WEEKDAY ( [Date] );
"DayOfWeek"; FORMAT ( [Date]; "dddd" );
"DayOfWeekShort"; FORMAT ( [Date]; "ddd" );
"Quarter"; "Q" & FORMAT ( [Date]; "Q" );
"YearQuarter"; FORMAT ( [Date]; "YYYY" ) & "/Q" & FORMAT ( [Date]; "Q" );
"WeekNum"; WEEKNUM ( [Date] )
)
I have a table  "Table 1" like  this :
ID ForeignKey Date
1 A 01/01/2005
2 A 05/04/2008
3 A 31/12/2019
4 B 15/3/2017
5 B 16/05/2018
6 B 15/04/2019
7 C 05/06/2006
8 C 04/12/2015
9 C 15/04/2019
 And another table "Table 2" like this
 
ID2 Price
A 100
B 500
C 650
The "Date" table  is related to "Table1" by date and Table 1 is related to  "Table 2" by Table1.ForeignKey = Table2.ID2.
In my report i have a date slicer which is set for example to filter dates between Jan 1 2008 and June 30 2018.
My goal is  to calculate the max and min date for each one of table 2 in the selected period like this: 
ID2 Price MinDate MaxDate
A 100 05/04/2008 05/04/2008
B 500 15/3/2017 16/05/2018
C 650 04/12/2015 04/12/2015
All i am able to achieve by doing somethig like this 
MaxDate= CALCULATE ( LASTDATE ( Table1[Date] ); FILTER (
ALLSELECTED('Date') ;
'Date'[Date] <= Max('Date'[Date])
))
is the max and min dates in  the whole calendar (01/01/2008 - 12/31/2020) , which is not what i'm trying to do .
How can I do this?
Thanks in advance.
With the relationships you describe, simply use measures:
MinDate = CALCULATE ( MIN ( 'Table 1'[Date] ) )
and
MaxDate = CALCULATE ( MAX ( 'Table 1'[Date] ) )
And set your slicer on 'Date'[Date]
See https://pwrbi.com/so_55373837/ for example PBIX file

how to get this year opening from last year closing with condition?

I have table of data as below needs to use t-sql to generate
Year | Id | Entitle | Use | Max
-----------------------------------
2016 | 0001 | 15 | 5 | 20
2017 | 0001 | 15 | 2 | 20
2018 | 0001 | 15 | 4 | 20
I need to get opening and closing for each year, this year opening will be last year (opening + Entitle - Use), but it cannot exceed Max, if exceed Max then "Max" will be the opening.
this is the result I expected
year | Id | Opening | Entitle | Use | Max | Closing
-----------------------------------------------------
2016 | 0001 | 0 | 15 | 5 | 20 | 10
2017 | 0001 | 10 | 15 | 2 | 20 | 23
2018 | 0001 | 20 | 15 | 4 | 20 | 31
Here's another option, a recursive CTE will get you there.
DECLARE #TestData TABLE
(
[Year] INT
, [Id] NVARCHAR(10)
, [Entitle] INT
, [Use] INT
, [Max] INT
);
INSERT INTO #TestData (
[Year]
, [Id]
, [Entitle]
, [Use]
, [Max]
)
VALUES ( 2016, '0001', 15, 5, 20 )
, ( 2017, '0001', 15, 2, 20 )
, ( 2018, '0001', 15, 4, 20 );
INSERT INTO #TestData (
[Year]
, [Id]
, [Entitle]
, [Use]
, [Max]
)
VALUES ( 2015, '0002', 20, 7, 20 )
, ( 2016, '0002', 20, 7, 20 )
, ( 2017, '0002', 20, 4, 20 )
, ( 2018, '0002', 20, 13, 20 );
WITH [cte]
AS ( SELECT [a].[Year]
, [a].[Id]
, 0 AS [Opening]
, [a].[Entitle]
, [a].[Use]
, [a].[Entitle] - [a].[Use] AS [Closing]
FROM #TestData [a]
--Cross apply here to get our first record, earliest year for each Id for our anchor
CROSS APPLY (
SELECT [aa].[Id]
, MIN([aa].[Year]) AS [Year]
FROM #TestData [aa]
WHERE [aa].[Id] = [a].[Id]
GROUP BY [aa].[Id]
) [aaa]
WHERE [a].[Year] = [aaa].[Year]
AND [a].[Id] = [aaa].[Id]
UNION ALL
SELECT [c].[Year]
, [c].[Id]
, CASE WHEN [b].[Closing] > [c].[Max] THEN [c].[Max]
ELSE [b].[Closing]
END
, [c].[Entitle]
, [c].[Use]
, CASE WHEN [b].[Closing] > [c].[Max] THEN [c].[Max]
ELSE [b].[Closing]
END + [c].[Entitle] - [c].[Use] AS [Closing]
FROM [cte] [b]
INNER JOIN #TestData [c]
ON [c].[Id] = [b].[Id]
AND [c].[Year] = [b].[Year] + 1 )
SELECT *
FROM [cte]
ORDER BY [cte].[Id]
, [cte].[Year];
Simple SQL will not be enough here. You need to go trough each row and calculate the closing and opening values based on the previous year.
The idea would be to loop trough each row. Store the results. Add the results into a temp table.
I have made you the code here. Please note that I have used SSMS to implement it.
DECLARE #TempTable table (_ID varchar(255),Year int,Opening int, Entitle int,Used int,Max int, Closing int)
DECLARE #idColumn INT
DECLARE #ID varchar(255)
DECLARE #entitle INT
DECLARE #used INT
DECLARE #max INT
DECLARE #opening INT
DECLARE #closing INT
DECLARE #year INT
SELECT #idColumn = min( Id ) FROM MyTable
WHILE #idColumn is not null
BEGIN
SET #year = (SELECT Year FROM MyTable WHERE Id = #idColumn)
SET #ID = (SELECT [_ID] FROM MyTable WHERE Id = #idColumn)
IF #idColumn = 1
BEGIN
SET #entitle = (SELECT Entitle FROM MyTable WHERE Id = #idColumn);
SET #used = (SELECT Used FROM MyTable WHERE Id = #idColumn);
SET #opening = 0;
SET #closing = #opening + #entitle - #used;
SET #max = (SELECT Max FROM MyTable WHERE Id = #idColumn);
END
ELSE
BEGIN
SET #opening = #opening + #entitle - #used;
IF #opening > #max
BEGIN
SET #opening = #max;
END
SET #entitle = (SELECT Entitle FROM MyTable WHERE Id = #idColumn);
SET #used = (SELECT Used FROM MyTable WHERE Id = #idColumn);
SET #max = (SELECT Max FROM MyTable WHERE Id = #idColumn);
SET #closing = #opening + #entitle - #used;
END
INSERT INTO #TempTable (_ID , Year , Opening , Entitle , Used ,Max , Closing )
VALUES (#ID, #year, #opening, #entitle, #used, #max, #closing);
SELECT #idColumn = min( Id ) FROM MyTable WHERE Id > #idColumn
END
SELECT * FROM #TempTable

Finding chronological age on Filemaker to be used in equation

I'm trying to calculate a chronological age based on a person's birth date (DOB) and the date of evaluation (DOE). I need the answer to be expressed as a numerical number that can be put in an equation. For example if a person's DOB is 12/26/07 and the DOE is 10/13/15 the chronological age will be 7.75, NOT 7;9 (7 years, 9 months). The decimal place needs to be a function out of 12, not simply representing the age in months. I have accurately calculated this but every time the chronological age is configured to be an even age (9 years 0 months) the calculation shows up as 90, I really need this "90" to be a "9.0" is there anything I can do to configure this into my calculation? The current calculation that is working for every other age is:
Year ( GetAsNumber ( DOE )) - Year ( DOB ) - If ( GetAsNumber ( DOE ) < Date ( Month ( DOB ) ; Day ( DOB ) ; Year ( GetAsNumber ( DOE ) ) ); 1 ; 0 ) & ( Mod ( Month ( GetAsNumber ( DOE ) ) - Month ( DOB ) + 12 - If ( Day ( GetAsNumber ( DOE ) ) < Day ( DOB ) ; 1 ; 0 ) ; 12 ) / 12)
Thank you!
Your Calculation is ok, but you are concatenating the 2 parts rather than adding them. That's why you get a "90" instead of a "9"
Also, if you want it to be "9.0", the calculation result must be numeric; and in layout mode set the format to decimal with a fixed number of decimals.
Round (
Year ( GetAsNumber ( DOE )) - Year ( DOB ) -
If (
GetAsNumber ( DOE ) < Date ( Month ( DOB ) ; Day ( DOB ) ; Year ( GetAsNumber ( DOE )));
1 ;
0)
+
( Mod (
Month ( GetAsNumber ( DOE ) ) - Month ( DOB ) + 12 -
If (
Day ( GetAsNumber ( DOE ) ) < Day ( DOB );
1;
0)
; 12 )
/ 12)
; 2 )
I would suggest a simpler approach:
Let (
elapsedMonths = 12 * ( Year ( DOE ) - Year ( DOB ) ) + Month ( DOE ) - Month ( DOB ) - ( Day ( DOE ) < Day ( DOB ) )
;
Div ( elapsedMonths ; 12 ) + Mod ( elapsedMonths ; 12 ) / 12
)
Note that this counts only fully elapsed months.

sql window function to detect change in column values

I'd like to detect changes in column values in this (example) db
WITH events(id, row,event) AS (
VALUES
(1,1, 0 )
,(1,2, 0 )
,(1,3, 1 )
,(1,4, 0 )
,(1,5, 1 )
,(2,1, 0 )
,(2,2, 1 )
,(3,1, 0 )
,(3,2, 0 )
)
select * from events
What I am looking for is code for a new column 'code' which switches to 1 AFTER
de event column shows a 1. Within the same id the code stays 1.
For this example this new column wil look like this
WITH events2(id, row,event, code) AS (
VALUES
(1,1, 0, 0 )
,(1,2, 0, 0 )
,(1,3, 1, 0 )
,(1,4, 0, 1 ) -- notice the switch here
,(1,5, 1, 1 ) --
,(2,1, 0, 0 )
,(2,2, 1, 0 )
,(3,1, 0, 0 )
,(3,2, 0, 0 )
)
select * from events2
I have a hunch that the answer will be related to the answer on this question : PostgreSQL window function: partition by comparison
Somehow I cannot figure this out myself..
Peter
COALESCE over a scalar subquery:
WITH events(id, zrow, zevent) AS (
VALUES
(1,1, 0 ) ,(1,2, 0 ) ,(1,3, 1 ) ,(1,4, 0 ) ,(1,5, 1 )
,(2,1, 0 ) ,(2,2, 1 )
,(3,1, 0 ) ,(3,2, 0 )
)
SELECT id, zrow, zevent
, COALESCE((SELECT 1 FROM events ex WHERE ex.id = ev.id AND ex.zrow < ev.zrow AND ex.zevent> 0),0) AS oevent
FROM events ev
;
Or, avoid the COALESCE() by typecasting the boolean EXISTS() to INTEGER:
WITH events(id, zrow,event) AS (
VALUES
(1,1, 0 ) ,(1,2, 0 ) ,(1,3, 1 ) ,(1,4, 0 ) ,(1,5, 1 )
,(2,1, 0 ) ,(2,2, 1 )
,(3,1, 0 ) ,(3,2, 0 )
)
SELECT id, zrow, event
, EXISTS(SELECT 1 FROM events ex WHERE ex.id = ev.id AND ex.zrow < ev.zrow AND ex.event> 0)::integer AS oevent
FROM events ev
;
Find the MAX() value over the previous records within the same group (frame):
WITH events(id, zrow,event) AS (
VALUES
(1,1, 0 ) ,(1,2, 0 ) ,(1,3, 1 ) ,(1,4, 0 ) ,(1,5, 1 )
,(2,1, 0 ) ,(2,2, 1 )
,(3,1, 0 ) ,(3,2, 0 )
)
, drag AS (
SELECT id, zrow, event, MAX(event)
OVER (PARTITION BY id
ORDER BY zrow
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) AS lagged
FROM events ev
)
SELECT id, zrow, event
, COALESCE(lagged,0) AS oevent
FROM drag dr
;
The same without the extra CTE:
WITH events(id, zrow,event) AS (
VALUES
(1,1, 0 ) ,(1,2, 0 ) ,(1,3, 1 ) ,(1,4, 0 ) ,(1,5, 1 )
,(2,1, 0 ) ,(2,2, 1 )
,(3,1, 0 ) ,(3,2, 0 )
)
SELECT id, zrow, event, COALESCE(MAX(event) OVER (PARTITION BY id
ORDER BY zrow
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
),0) AS lagged
FROM events ev
;
Another way to perform the self-join would be to use a recursive query.

How to average 3 values in Sql Server?

I have three variables :-
#ScoreA DECIMAL(10,7)
#ScoreB DECIMAL(10,7)
#ScoreC DECIMAL(10,7)
#FinalScore DECIMAL(10, 7)
I wish to get the average of the three scores. BUT 1, 2 or all 3 values might be zero.
Eg. scenarios:
A = 1.4, B=3.5, C=5.0; FinalScore = 3.3
A = 0.0, B=0.0, C=0.0; FinalScore = 0.0
A = 1.1, B=0.0, C=0.0; FinalScore = 1.1
A = 0.0, B=2.0, C=4.8; FinalScore = 3.4
Cheers!
IF #A > 0 OR #B > 0 OR #C > 0
SELECT ((#A + #B + #C) /
(0 +
CASE WHEN #A = 0 THEN 0 ELSE 1 END +
CASE WHEN #B = 0 THEN 0 ELSE 1 END +
CASE WHEN #C = 0 THEN 0 ELSE 1 END ))
ELSE
SELECT 0.0
EDIT
Modified query to now handle divide by zero scenario's.
EDIT2
Here is "the trick with the AVG(..) function" :) with Common Table Expression
WITH T(I) AS (SELECT #A UNION SELECT #B UNION SELECT #C)
SELECT AVG(I) FROM T
WHERE I > 0
SELECT ((#A + #B + #C) /
(CASE WHEN (#A = 0.0 AND #B = 0.0 AND #C = 0.0) THEN 1 ELSE 0 END
+ CASE WHEN #A = 0 THEN 0 ELSE 1 END
+ CASE WHEN #B = 0 THEN 0 ELSE 1 END
+ CASE WHEN #C = 0 THEN 0 ELSE 1 END
)
)
For me this is easier to read and understand:
DECLARE
#ScoreA DECIMAL(10,7),
#ScoreB DECIMAL(10,7),
#ScoreC DECIMAL(10,7),
#FinalScore DECIMAL(10, 7)
SET #ScoreA = 1.4
SET #ScoreB = 3.5
SET #ScoreC = 5.0
DECLARE
#AVG TABLE (value DECIMAL(10,7))
INSERT INTO #AVG
SELECT #ScoreA WHERE #ScoreA > 0
UNION
SELECT #ScoreB WHERE #ScoreB > 0
UNION
SELECT #ScoreC WHERE #ScoreC > 0
SELECT COALESCE(AVG(value), 0) FROM #AVG