SPARQL Join two graphs : value precedence? - left-join

I have two graphs that contain values for enrollment in clinical trials. Each graph has incomplete records for enrollment so I want to combine the graphs to get a more complete listing of the enrollment values.
The KMD graph should take precedence. If enrollment is present in both the KMD graph and the KCTGOV graph, use the value from KMD. If enrollment is missing in KMD, use the enrollment value from KCTGOV.
I am getting close with the query below: I bring in the enrollment values from each graph by successfully joining on the value of ?nctId. How do I then create a result for ?enrollment that is from KMD when present in that graph or comes from KCTGOV when the value is missing in KMD? The code below creates separate enrollment columns named enrollKMD and enrollKCT. I need a merge of those columns.
Suggestions greatly appreciated!
PREFIX kmd: <http://www.example.org/kmd/>
PREFIX lct: <http://data.linkedct.org/vocab/resource/>
SELECT *
FROM NAMED <http://localhost:8890/KMD>
FROM NAMED <http://localhost:8890/KCTGOV>
WHERE
{
GRAPH <http://localhost:8890/KMD>
{
?obs a kmd:Study ;
kmd:hasOrgId ?orgId .
OPTIONAL
{
?obs kmd:hasNctId ?nctIdURI .
}
OPTIONAL {?obs kmd:hasEnrollment ?enrollkmd.}
# Create STR of NCTID for merge
BIND(strafter(str(?nctIdURI), "kmd/") AS ?nctId )
}
OPTIONAL
{
GRAPH <http://localhost:8890/KCTGOV>
{
OPTIONAL{ ?govNctIdURI lct:enrollment ?enrollKCT.}
# Create STR of NCTID for merge
BIND(UCASE(strafter(str(?govNctIdURI), "trial/")) AS ?nctId )
}
}
}ORDER BY ?orgId

You can do this with an IF operation, like so:
select (if(bound(?enrollkmd), ?enrollkmd, ?enrollKCT) as ?enrollment)
where ...
The IF operator checks if ?enrollkmd is bound to a value, if so, it returns that value, otherwise it returns the value of ?enrollKCT. The outcome of the operator is then bound to the ?enrollment variable in your query result.
Of course, since you are no longer using the wildcard-select ('*'), you will now need to explicitly add all variables you want returned. So the full select-clause will become something like this:
select ?obs ?orgId ?nctId (if(bound(?enrollkmd), ?enrollkmd, ?enrollKCT) as ?enrollment)
adapt to taste.

Related

Dynamic GROUP BY of internal tables in ABAP [duplicate]

This question already has an answer here:
LOOP AT... GROUP BY with dynamic group key
(1 answer)
Closed 2 years ago.
I want to aggregate some specific data in a RFC module. The module takes several parameters like timestamps but also dimensions that specify the kind of aggregation.
For example I want to aggregate all contracts in a specific timerange for the several sales orgs in my system.
For this I use the GROUP BY functionality for internal tables like here:
LOOP AT ls_output-merged_data INTO ls_tmp
GROUP BY ( sales_org = ls_tmp-sales_org
group_quantity = GROUP SIZE )
ASCENDING ASSIGNING FIELD-SYMBOL(<fs_tmp_2>).
lt_tmp_dim1 = VALUE #( BASE lt_tmp_dim1 (
sales_org = <fs_tmp_2>-sales_org
group_quantity = <fs_tmp_2>-group_quantity
) ).
ENDLOOP.
The group-field may change for different cases also it should be possible to use two group-fields in order to e.g. aggregate all sales-orgs and the material they sold.
My question know is, how could I do the GROUP-BY dynamically without the need to programm every combination of group-fields manually?
Thank you very much in advance
Please check: Loop at group by dynamic group condition
I implemented a dynamic 'group by' clause by referring above link. It may also can be answer your question.
LOOP AT t_actual_data INTO DATA(actual)
GROUP BY cond string( when i_prodh_based eq abap_true THEN
|{ actual-prodh } { actual-vkorg } { actual-hl_kunnr } { actual-period }|
else
|{ actual-matnr } { actual-vkorg } { actual-hl_kunnr } { actual-period }| )
ASSIGNING FIELD-SYMBOL(<group>).
"following assignment does not give any result. So I did a loop to get group conditions
"ASSIGN COMPONENT 'PRODH' of STRUCTURE <group> to <prodh>. "no result
"get group condition values
LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<line_data>).
ASSIGN COMPONENT 'PRODH' of STRUCTURE <line_data> to <prodh>.
ASSIGN COMPONENT 'VKORG' of STRUCTURE <line_data> to <vkorg>.
ASSIGN COMPONENT 'MATNR' of STRUCTURE <line_data> to <matnr>.
ASSIGN COMPONENT 'HL_KUNNR' of STRUCTURE <line_data> to <tl_kunnr>.
ASSIGN COMPONENT 'PERIOD' of STRUCTURE <line_data> to <period>.
EXIT.
ENDLOOP.
ENDLOOP.

Conditional WHERE clause in KDB?

Full Query:
{[tier;company;ccy; startdate; enddate] select Deal_Time, Deal_Date from DEALONLINE_REMOVED where ?[company = `All; 1b; COMPANY = company], ?[tier = `All;; TIER = tier], Deal_Date within(startdate;enddate), Status = `Completed, ?[ccy = `All;1b;CCY_Pair = ccy]}
Particular Query:
where ?[company = `All; 1b; COMPANY = company], ?[tier = `All; 1b; TIER = tier],
What this query is trying to do is to get the viewstate of a dropdown.
If there dropdown selection is "All", that where clause i.e. company or tier is invalidated, and all companies or tiers are shown.
I am unsure if the query above is correct as I am getting weird charts when displaying them on KDB dashboard.
What I would recommend is to restructure your function to make use of the where clause using functional qSQL.
In your case, you need to be able to filter based on certain input, if its "All" then don't filter else filter on that input. Something like this could work.
/Define sample table
DEALONLINE_REMOVED:([]Deal_time:10#.z.p;Deal_Date:10?.z.d;Company:10?`MSFT`AAPL`GOOGL;TIER:10?`1`2`3)
/New function which joins to where clause
{[company;tier]
wc:();
if[not company=`All;wc:wc,enlist (=;`Company;enlist company)];
if[not tier=`All;wc:wc,enlist (=;`TIER;enlist tier)];
?[DEALONLINE_REMOVED;wc;0b;()]
}[`MSFT;`2]
If you replace the input with `All you will see that everything is returned.
The full functional select for your query would be as follows:
whcl:{[tier;company;ccy;startdate;enddate]
wc:(enlist (within;`Deal_Date;(enlist;startdate;enddate))),(enlist (=;`Status;enlist `Completed)),
$[tier=`All;();enlist (=;`TIER;enlist tier)],
$[company=`All;()enlist (=;`COMPANY;enlist company)],
$[ccy=`All;();enlist (=;`CCY_Pair;enlist ccy)];
?[`DEALONLINE_REMOVED;wc;0b;`Deal_Time`Deal_Date!`Deal_Time`Deal_Date]
}
The first part specifies your date range and status = `Completed in the where clause
wc:(enlist (within;`Deal_Date;(enlist;startdate;enddate))),(enlist (=;`Status;enlist `Completed)),
Next each of these conditionals checks for `All for the TIER, COMPANY and CCY_Pair column filtering. It then joins these on to the where clause when a specific TIER, COMPANY or CCY_Pair are specified. (otherwise an empty list is joined on):
$[tier=`All;();enlist (=;`TIER;enlist tier)],
$[company=`All;();enlist (=;`COMPANY;enlist company)],
$[ccy=`All;();enlist (=;`CCY_Pair;enlist ccy)];
Finally, the select statement is called in its functional form as follows, with wc as the where clause:
?[`DEALONLINE_REMOVED;wc;0b;`Deal_Time`Deal_Date!`Deal_Time`Deal_Date]

How to use select syntax for group by field which is array in Dynamics AX

I have field Value in table finStatementTrans which is array.
How should I write select syntax with group by and sum by this field?
while select finStatementTable join DataClassParagraph,sum(Value) from finStatementTrans
group by finStatementTrans.DataClassParagraph
where finStatementTable.RecId == finStatementTrans.FinStatementTable_FK
&& finStatementTable.FinStatementTableParent_FK == 5637569094
{
info(strFmt(%1,%2",finStatementTrans.DataClassParagraph,finStatementTrans.Value[1]));
}
Is this correct?
sum(Value[1])
with this I can't compile.
As Aliaksandr Maksimau mentioned in his comment, aggregating array fields is not possible. Aggregations are only supported for integer and real data type fields.
See also X++ data selection and manipulation, paragraph select statements, last sentence.

FileMaker calculated filtered list

I am currently getting a list of related field like so
List ( join_table::id_b;)'
and what i would like to do is filter that list by a second field in the same related table pseudo code as follows
List ( join_table::id_b;jointable:other="foo")
not really sure how to filter it down
The List() function will return a list of (non-empty) values from all related records.
To get a list filtered by a second field, you could do any one of the following:
Define a calculation field in the join table = If ( other = "foo" ; id_b ) and use this field in your List() function call instead of the id_b field;
Construct a relationship filtered by the other field;
Use the ExecuteSQL() function instead of List();
Write your own recursive custom function (requires the Advanced version to install).

I am trying to create a formula with multiple parameters that may or may not have a value entered

I am trying to create a formula with multiple parameters that may or may not have a value entered.
The database field and corresponding parameters are:
{DataTableTicket.Master_Account_Code}={?MastNo})
{DataTableTicket.Description}={?RTCode}
{DataTableTicket.Problem_Code}={?ProbCode}
{DataTableTicket.Resolution_Code}={?ResCode}
{DataTableTicket.Customer_Number}={?CustNo}
{DataTableTicket.Master_Account_Code}={?MastNo})
I am trying to write an IF THEN statement that takes into consideration the various combinations, since you can enter in a ?MastNo value but not populate the rest of the parameters.
I think the basic formula would be something like this (if parameter is blank then all records else parameter). What I am struggling with is how to get that basic formula created since there are so many combinations.
For each parameter that "may or may not have a value", set it to a default value.
If the value for the parameter is entered then set the parameter to the entered value.
I usually do something like:
// Assumes that 0 represents all values; single value; numeric
( 0={?Parameter} OR {Table.Field}={?Parameter} )
// Assumes that 0 represents all values; multiple values; numeric
( 0 IN {?Parameter} OR {Table.Field} IN {?Parameter} )
In your situation:
( 0={?MastNo} OR DataTableTicket.Master_Account_Code}={?MastNo} ) AND
( 0={?RTCode} OR {DataTableTicket.Description}={?RTCode} )
...