How to specify two if conditions using and in xquery? - xquery

I m trying the below code :-
if($var1=$var2) and if(fn:contains($somevar1, $somestring)
then
(do (this....)
else ()
However it doesnt work. Which logical operator can be used between those two ifs?

The second if keyword can be omitted:
if (
$var1 = $var2 and fn:contains($somevar1, $somestring)
) then (
...
) else (
...
)

Related

how to write for loop with nested if statement in xquery

I am trying the below code :-
return
fn:concat (fn:string-join ((
"somevalue.1.",
"somevalue.2.",
"some val 3",
"some val4",
$somevariable), " "),
for $i in $loopvar
if ((fn:exists($loopvar)) and (fn:count($loopvar) > 1)) then
" where ( " || $loopvar[i] || " and "
else if(fn:exists($loopvar) and (fn:count($loopvar) > 0)) then
" where " || $loopvar[i]
else() )
This code is forming some part of a sql query in which i am trying to get the where conditions separated by "and". The variable $loopvar is of type string and it can have multiple values like column1=3, column2=4, column3=5...and so on. I want to check if this variable has some values then it form the query(as per the above code). However I am getting error in the fn:concat part:-
fn:concat( fn:string-join( ("some val 1", "someval2"......" -- arg1 is not of type xs:anyAtomicType?
Can someone pls suggest where am I going wrong with the above piece of code?
You list MarkLogic as a tag. If so, i would consider using the Optic API where you can more elegantly express your exact query.
Your code has several issues.
In your first return statement, you are returning the fn:concat(). You could have that as the end of the first FLWOR statement, but the second FLWOR is referencing the $loopvar. IF that is in the scope of the first FLWOR, then you need to ensure that the second FLWOR is one of a sequence of items returned in the first. Wrap both the concat and that for loop inside of parenthesis to indicate that you want to return a sequence of items that are all within the scope of that first FLWOR.
The error message is telling you that the if statement following the for is unexpected, because in that FLWOR statement you started a for loop and then have an expression that you want to return, so you need to add a return statement.
https://www.w3.org/TR/xpath-full-text-10/#prod-xquery10-FLWORExpr
(ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle
Lastly, it seems you are iterating over the $loopvar sequence and attempting to use $i as an index in a predicate, but forgot the $ for the $i variable i.e. $loopvar[$i]. However, unless the $i is a number, that probably won't select what you want. And if it is, it's still easier and more efficient to just use the $i variable:
(: I added some dummy variables, just to have a more complete example that would run :)
let $somevariable := "somevariable"
let $loopvar := ("a", "b", "c")
return (
fn:concat (fn:string-join ((
"somevalue.1.",
"somevalue.2.",
"some val 3",
"some val4",
$somevariable), " ")),
for $i in $loopvar
return
if ((fn:exists($loopvar)) and (fn:count($loopvar) > 1))
then " where ( " || $i || " and "
else
if(fn:exists($loopvar) and (fn:count($loopvar) > 0))
then " where " || $i
else()
)
If you did want the position of the $i in your for loop, you can use the positional variable at expression and assign a position variable: for $i at $j in $loopvar
https://www.w3.org/TR/xpath-full-text-10/#doc-xquery10-ForClause

PL/SQL procedure has mutliple 'AND' conditions and OR comditions . How to make sure all conditions it executes?

*where (citiStatus NOT IN ('Paid Off' ,'PAID-O'))
and (
revolver = 0
and (
(commitmentDate = '')
or (
(commitmentDate != '')
and (#currentDate < DATEADD(day, #noofDays, commitmentDate))
)
)
) // until here should verify with where condition . even if it is failed or not should execute next statement .
and (citiStatus NOT IN ('CANCELLED','Cancelled/Dead') or #currentMonth = MONTH(statusModifiedDate))-- this is will if above AND condition fails even if its true(but this should execute even to filter data).*
You need to have in mind two simple rules, the Associativity of Logical Operators is always from left to right, and the correct use of Parentheses having in consideration the logic of your problem for example:
select case when 1=1 and 1=2 or 3=3 then 1 else 0 end as result from dual;--result 1
First we evaluate 3=3 TRUE -> 1=2 FALSE -> evaluate OR OPERATOR (TRUE OR FALSE)-> TRUE
Second 1=1 TRUE -> evaluate AND OPERATOR -> TRUE AND TRUE -> TRUE
IF TRUE THEN 1
My advice is always to use Parentheses, in this way you will evaluate the whole expression and no token by token for example
select case when ((1=1 and 2=2) or 3=3) and 5=6 then 1 else 0 end as result from dual; --0
select case when (1=1 and 2=2) or (3=3 and 5=6) then 1 else 0 end as result from dual; --1

DAX: How to check if (All) value selected for specific Dimension

I have a task to convert existing MDX measures (from multidimensional model) into DAX (tabular model).
There is a part of code which I'm doing right now:
IIF(
[Product].[Status].Level IS [Product].[Status].[(All)]
AND
[Product].[Brand].Level IS [Product].[Brand].[(All)]
AND
[Product].[Category].Level IS [Product].[Category].[(All)]
,[Measures].[Full_Amount]
,NULL
)
How can I do the same on DAX?
The problem is to check that .[(All)] member is selected. Do we have the same option n DAX?
As #RADO mentions you can do something like this in DAX:
IF(
NOT ISFILTERED( Product[Status] )
&& NOT ISFILTERED( Product[Brand] )
&& NOT ISFILTERED( Product[Category] ),
[Measures].[Full_Amount],
BLANK()
)

MDX - COUNT ( TOPPERCENT () ) returns 1 when no value

We wrote this MDX query:
COUNT(
TOPPERCENT(
{[d_gca].[h_gca].[l_gca].MEMBERS},
80,
[Measures].[m_invoice_item_amount]
)
)
The problem is, when there is no value for [d_gac].[h_gac].[l_gac].MEMBERS, the displayed result is always 1.
Is there something I missed?
Can you just wrap the inner set in the NonEmpty function?
COUNT(
TOPPERCENT(
NONEMPTY(
{[d_gca].[h_gca].[l_gca].MEMBERS}
,[Measures].[m_invoice_item_amount]
),
80,
[Measures].[m_invoice_item_amount]
)
)

Get several id from pipe-separated string to concat data from another table

I've got two tables, where one holds several id's as pipe-separated string and another that holds names for each id. I want to concat the names as one-liner string with \n between the names.
Tables:
Id-table
| StringIds |
'1|2|3|4|5|4|1'
Name-table
| StringId | String Name |
1 'One'
2 'Two'
3 'Three'
4 'Four'
5 'Five'
I've tried with following code without any success:
SELECT GROUP_CONCAT(StringName || '\n')
FROM Names
WHERE
StringId
IN
(
SELECT DISTINCT
GROUP_CONCAT(REPLACE(StringIds,'|',','))
FROM Ids
)
ORDER BY StringName ASC
Expected output: 'One'\n'Two'\n'Three'\n'Four'\n'Five'\n
Fiddle
The problem is, that the sub query that you have used
SELECT DISTINCT
group_concat(replace(StringIds,'|',','))
FROM Ids
actually returns a string '1,2,3,...' not a number list 1,2,3,... as expected.
The WHERE StringId IN ((SELECT...)) wil not work with strings, it expects a list of elements and the string is ONE element.
So instead you will have to look at the string functions, and there you can use the INSTR(X,Y) function to find the StringId.
But here we must pay attention, because if i.E. we where searching for
the number 3 then we would find it in:
1,2,3,4
but it would also find it in
1,2,30,4
So the trick is to wrap the separator around the query string
and the string to search in. So if we would search for ',3,' in ',1,2,3,4,'
we would have a match, as expected, and if we search in ',1,2,30,4,', then we will not match, which is also as expected. So this is the reason we have these strange concats in our query :)
SELECT group_concat(StringName || '\n') as AllNames
FROM Names
WHERE INSTR(
(',' || (
SELECT DISTINCT
group_concat(replace(StringIds,'|',','))
FROM Ids
) || ','),
(',' || StringId || ',')
) > 0
ORDER BY StringName ASC;
Well now, if we think about it, and since we are searching in a string,
we might as well use your oringinal string instead
of converting it in advance:
SELECT group_concat(StringName || '\n') as AllNames
FROM Names
WHERE INSTR(
('|' || (
SELECT StringIds FROM Ids LIMIT 1
) || '|'),
('|' || StringId || '|')
) > 0
ORDER BY StringName ASC;
And actually there are many more ways we could do this. Let me give you one last version using LIKE comparison instead of INSTR function:
SELECT group_concat(StringName || '\n') as AllNames
FROM Names
WHERE
('|' || (
SELECT StringIds FROM Ids LIMIT 1
) || '|')
LIKE
('%|' || StringId || '|%')
ORDER BY StringName ASC;
Hope this link works, so you can Fiddle around here
UPDATE
If you end up having more entries in your Ids table and you want to print out the unique names for each entry in the Ids table, then you have to turn around the query:
SELECT
( SELECT group_concat(StringName || '\n')
FROM Names
WHERE
('|' || (
StringIds
) || '|')
LIKE
('%|' || StringId || '|%')
ORDER BY StringName ASC
) as AllNames FROM Ids
Now here Ids is the outer table looped through and for each entry the sub query is performed, which returns the AllNames value.

Resources