Comparing 2 columns in Hyperion (Oracle) - hyperion

I have two columns in a query.
I have 2 fields (Field 1 and Field 2). What I want to do is:
if Field 1 is blank then use Field 2, but
if it is not blank then I want it to populate it with Field 1.
I am sure it can be done in a computed column but have been unsuccessful with the logic (so far).

"Blank" can mean a lot of things. You can try checking for the most common ones.
In a results set, this will check a few things.
if( Field_1 == null || Field_1.replace(/\s/gi,'') == '' || Field_1 == NaN )
{
Field_2;
}
else
{
Field_1;
}
First is whether your field truly is blank, and contains no data.
Hyperion results-set computed items like "null" to be all-lowercase.
Second is whether you do have data, but it's invisible. Usually,
that's empty strings, but it can also be other whitespace, so we'll
see if replacing all whitespace (not changing the data; it's just
for comparison-sake) with empty strings would yield an empty string.
/\s/gi is regex ... it means "whitespace" global (ie: every match),
case-insensitive.
Lastly (and, I've never had this be the case personally, but I've been told it can happen), check to see if there's a Not-a-Number (NaN) response. This is sort of an error that can appear in data, counts as value, but which might not display on your screen.
If you're doing this in the Query section, you'll have to write it in SQL, and have to match the syntax to your data source (Oracle, DB2, Sybase, etc), but the concept is the same.

Related

How do i remove rows based on comma-separated list of values in a Power BI parameter in Power Query?

I have a list of data with a title column (among many other columns) and I have a Power BI parameter that has, for example, a value of "a,b,c". What I want to do is loop through the parameter's values and remove any rows that begin with those characters.
For example:
Title
a
b
c
d
Should become
Title
d
This comma separated list could have one value or it could have twenty. I know that I can turn the parameter into a list by using
parameterList = Text.Split(<parameter-name>,",")
but then I am unsure how to continue to use that to filter on. For one value I would just use
#"Filtered Rows" = Table.SelectRows(#"Table", each Text.StartsWith([key], <value-to-filter-on>))
but that only allows one value.
EDIT: I may have worded my original question poorly. The comma separated values in the parameterList can be any number of characters (e.g.: a,abcd,foo,bar) and I want to see if the value in [key] starts with that string of characters.
Try using List.Contains to check whether the starting character is in the parameter list.
each List.Contains(parameterList, Text.Start([key], 1)
Edit: Since you've changed the requirement, try this:
Table.SelectRows(
#"Table",
(C) => not List.AnyTrue(
List.Transform(
parameterList,
each Text.StartsWith(C[key], _)
)
)
)
For each row, this transforms the parameterList into a list of true/false values by checking if the current key starts with each text string in the list. If any are true, then List.AnyTrue returns true and we choose not to select that row.
Since you want to filter out all the values from the parameter, you can use something like:
= Table.SelectRows(#"Changed Type", each List.Contains(Parameter1,Text.Start([Title],1))=false)
Another way to do this would be to create a custom column in the table, which has the first character of title:
= Table.AddColumn(#"Changed Type", "FirstChar", each Text.Start([Title],1))
and then use this field in the filter step:
= Table.SelectRows(#"Added Custom", each List.Contains(Parameter1,[FirstChar])=false)
I tested this with a small sample set and it seems to be running fine. You can test both and see if it helps with the performance. If you are still facing performance issues, it would probably be easier if you can share the pbix file.
This seems to work fairly well:
= List.Select(Source[Title], each Text.Contains(Parameter1,Text.Start(_,1))=false)
Replace Source with the name of your table and Parameter1 with the name of your Parameter.

Having different count per key in jsonb

I have values in a table called Translation, that contains for every values per example:
=> {"fr"=>"Jaune", "de"=>"", "en"=>"", "bg"=>"", "hr"=>"", "es"=>"", "hu"=>"", "it"=>"", "lt"=>"", "lv"=>"", "nl"=>"", "pl"=>"", "pt"=>"", "ro"=>"", "cs"=>""}
and I'm looking to get the the number of the translation for each language:
I'm trying :
Translation.where("values->>'fr' IS NOT NULL").count
but it giving me 0, which is not correct, do anyone knows how to do it correctly?
The problem that you have is that the keys that don't have values, still exist in the json, so "is not null" will return all of them because the key exist. you have two options here, you can remove the empty keys from the database, so not null will work, or, change it to see if the key is empty
You can do it like this
Translation.where("values->>'fr' <> ''").count
and it will work with the structure that you have right now.

multiple line where clauses

I've got a search page with multiple inputs (text fields). These inputs may or may not be empty - depending on what the user is searching for.
In order to accommodate this I create a base searchQuery object that pulls in all the correct relationships, and then for each non-empty input I modify the query using the searchQuery.Where function.
If I place multiple conditions in the WHERE clause I get the following error:
Cannot compare elements of type 'System.Collections.Generic.ICollection`1'. Only primitive types, enumeration types and entity types are supported.
searchQuery = searchQuery.Where(Function(m) (
(absoluteMinimumDate < m.ClassDates.OrderBy(Function(d) d.Value).FirstOrDefault.Value) _
OrElse (Nothing Is m.ClassDates)
)
)
I know that code looks funky, but I was trying to format it so you didn't have to scroll horizontally to see it all
Now, if I remove the ORELSE clause, everything works (but of course I don't get the results I need).
searchQuery = searchQuery.Where(Function(m) (
(absoluteMinimumDate < m.ClassDates.OrderBy(Function(d) d.Value).FirstOrDefault.Value)
)
)
This one works fine
So, what am I doing wrong? How can I make a multi-condition where clause?
Multiple conditions in the Where isn't the problem. m.ClassDates Is Nothing will never be true and doesn't make sense in SQL terms. You can't translate "is the set of ClassDates associated with this record NULL?" into SQL. What you mean is, are there 0 of them.
If there are no attached ClassDate records, m.ClassDates will be an empty list. You want m.ClassDates.Count = 0 OrElse...

core data subquery

I have an an entity containing two optional to-many relationships (childA <<-> parent <->> childB). Each of these two child entities contain an optional string that I am interested in querying on.
Using the same format, I get the results I expect for one, but not the other. I understand that means I don't understand the tools I'm working with; and hoped for some insight. This is what the two queries look like:
childA.#count != 0 AND (0 == SUBQUERY(childA, $a, $a.string != NIL).#count)
childB.#count != 0 AND (0 == SUBQUERY(childB, $a, $a.string != NIL).#count)
I would expect to get back results from non-nil instances of both childA and childB only if each entity instances' string is also nil. My question is, why would one give the results that I expect; while the other does not?
Clarification:
I'm trying to solve the general problem where I'm searching for one of two things. I'm either searching for a default value in an attribute. When the attribute is optional, I'm additionally searching for a nil attribute. The problem is further compounded when optional relationships' should only be considered when the are populated. Without the relationship count != 0, I get back all parents with a nil relationship. In one case, this is the desired behavior. In another case, this appears to diminish the returned parent count (to 0 results).
For the optional attribute case, the query might look like:
parent.#count != 0 AND (parent.gender == -1) OR (parent.gender == NIL)
Where there are optional relationships in the key-paths, the query takes the form exemplified in the first example.
Again, I have gotten the results I have expected with all but one case, where there doesn't seem to be anything unique to it's relationships nor attribute characteristics. Or I should say, there's nothing unique about this exception in data model structure or query format...
Maybe you mixed up == and != in the second clause, and it should be
childA.#count != 0 AND (SUBQUERY(childA, $a, $a.string != NIL).#count != 0)
It would be clearer what you want to achieve if you could formulate the query in plain English first.
BTW, you can use expressionForSubquery:usingIteratorVariable:predicate: of class NSExpression to build the subquery for you. You might get useful error reporting more easily then.
I understand the problem now.
In my case, it's usually logical correct to first filter out NSSets with 0 count. But, in the problematic case, it's logically correct to return the results of both NSSets with 0 count, and NSSets with > 0 count where the attribute is nil (when optional), or the attribute is set to its default value. In other words, in the problematic case, the left condition needs to be removed, resulting in the following format:
(0 == SUBQUERY(childA, $a, $a.string != NIL).#count)
It seems I'll need to have the managed objects indicate which scenario is appropriate on a case by case basis...yuk!

SQL Query: Using IF statement in defining new field

I have a table with many fields and additionally several boolean fields (ex: BField1, BField2, BField3 etc.).
I need to make a Select Query, which will select all fields except for boolean ones, and a new virtual field (ex: FirstTrueBool) whose value will equal to the name of the first TRUE Boolean Field.
For ex: Say I have BField1 = False, BField2 = True, BField3 = true, BField4=false, in that case SQL Query should set [FirstTrueBool] to "BField2". Is that possible?
Thank you in advance.
P.S. I use Microsoft Access (MDB) Database and Jet Engine.
If you want to keep the current architecture (mixed 'x' non-null status and 'y' non-status fields) you have (AFAIS now) only the option to use IIF:
Select MyNonStatusField1, /* other non-status fields here */
IIF([BField1], "BField1",
IIF([BField2], "BField2",
...
IIF([BFieldLast], "BFieldLast", "#No Flag#")
))))) -- put as many parenthesis as it needs to close the imbricated IIFs
From
MyTable
Of course you can add any Where clause you like.
EDIT:
Alternatively you can use the following trick:
Set the fields to null when the flag is false and put the order number (iow, "1" for BField1, "2" for BField2 etc.) when the flag is true. Be sure that the status fields are strings (ie. Varchar(2) or, better, Char(2) in SQL terminology)
Then you can use the COALESCE function in order to return the first non-value from the status fields which will be the index number as string. Then you can add in front of this string any text you like (for example "BField"). Then you will end with something like:
Select "BField" || Coalesce(BField1, BField2, BField3, BField4) /*etc. (add as many fields you like) */
From MyTable
Much clearer IMHO.
HTH
You would be better using a single 'int' column as a bitset (provided you have up to 32 columns) to represent the columns.
e.g. see SQL Server: Updating Integer Status Columns (it's sql server, but the same technique applies equally well to MS Access)

Resources