Returning multiple record IDs with an I-Descriptor - universe

Is it possible to create an I-descriptor that returns multiple record keys when the only the first part of the key is known? For example I have Quote Header record in the QTH file and need to reference all of the Quote Detail records in the QTD file.
A QTH record has an ID of '1159' so I know that all of the related QTD records will begin with '1159*'.
Entering LIST QTD LIKE "1159*]" returns
1159*D080*L*096*20
1159*D060*D*Shipping*
1159*D060*L*063*10
1159*D060*D*Dakota Sign*
1159*D080*L*092*30
I have tried a number of variations of the TRANS() statement in an I-Descriptor to return a multivalued list, all to no avail. Can this be done and if so how?

If I understand you want an I-type in QTH to tell you the IDS in QTD that start with 1159.
You should be able to do this with a subroutine call.
The I-Type would be
1: I
2: SUBR("GETQTDIDS)
3:
4: QTD-IDS
5: 10L
6: M
The subroutine would be:
SUBR GETQTDIDS(IDLIST)
EXECUTE "SELECT QTD WITH #ID LIKE ":(#ID):"..." CAPTURING IDLIST
RETURN
END
I would try something like that. Of course if you had an I-type in QTD which pulled out the first part of the #ID and indexed it you could use GETINDEX instead.
And of course if you had that its much easier to create an I-type in QTD which pulled information from QTH.

Related

UNIQUE formula in Google Sheets for multiple ranges

I have a list of participants in column A. A full employee list in column B. I want to get the list of non-participants in column C. Basically 'B-A' but in list form.
'January' is the participants list:
try:
=FILTER(A:A; NOT(COUNTIF(B:B; A:A)))
It is always an added challenge to write formulas when we don't have access to actual date. But based on what I can see, try this formula in the top cell of any empty column:
=ArrayFormula({"My Header"; FILTER(R2:R,ISERROR(VLOOKUP(TRIM(R2:R),TRIM(T2:T),1,FALSE)))})
You can change "My Header" to something meaningful.
The next part means "FILTER in anything in the range R2:R that cannot be found [i.e., ISERROR(VLOOKUP(...))] in T2:T."
TRIM is used just to account for any accidental/stray spaces that may occur in either list, since that would result in no match if one or the other had extra space.
If this does not do what you expect, please share a link to a sample spreadsheet.

Google Data Studio Calculated Field by Extracting String from Event Label Values

I'm trying to use the CASE statement to output string values for an Event Label field using RegEx to produce a table that shows the number of events for each field value. So, if I'm looking for foobar, and other string values separately, within values for Event Label; it may either stand alone or be part of a URL like so:
|[object HTMLLabelElement] | Foobar |
/images/foobar-26.svg
It seems REGEXP_EXTRACT might suit this the best:
CASE WHEN REGEXP_EXTRACT(Event Label, '.(?i)foobar.') THEN Foobar
However, the table produced using the calculated field as the dimension only contains a blank row that seems to be the sum of the number of events.
What am I missing?
I think you need to use REGEXP_MATCH not REGEXP_EXTRACT, given your existing syntax, or to change the syntax to a straight REGEXP_EXTRACT without the CASE element.

Kettle database lookup case insensitive

I've a table "City" with more than 100k records.
The field "name" contains strings like "Roma", "La Valletta".
I receive a file with the city name, all in upper case as in "ROMA".
I need to get the id of the record that contains "Roma" when I search for "ROMA".
In SQL, I must do something like:
select id from city where upper(name) = upper(%name%)
How can I do this in kettle?
Note: if the city is not found, I use an Insert/update field to create it, so I must avoid duplicates generated by case-sensitive names.
You can make use of the String Operations steps in Pentaho Kettle. Set the Lower/Upper option to Y
Pass the city (name) from the City table to the String operations steps which will do the Upper case of your data stream i.e. city name. Join/lookup with the received file and get the required id.
More on String Operations step in pentaho wiki.
You can use a 'Database join' step. Here you can write the sql:
select id from city where upper(name) = upper(?)
and specify the city field name from the text file as parameter. With 'Number of rows to return' and 'Outer join?' you can control the join behaviour.
This solution doesn't work well with a large number of rows, as it will execute one query per row. In those cases Rishu's solution is better.
This is how I did:
First "Modified JavaScript value" step for create a query:
var queryDest="select coalesce( (select id as idcity from city where upper(name) = upper('"+replace(mycity,"'","\'\'")+"') and upper(cap) = upper('"+mycap+"') ), 0) as idcitydest";
Then I use this string as a query in a Dynamic SQL row.
After that,
IF idcitydest == 0 then
insert new city;
else
use the found record
This system make a query for file's row but it use few memory cache

How to search multiple strings in a string?

I want to check in a powerquery new column if a string like "This is a test string" contains any of the strings list items {"dog","string","bark"}.
I already tried Text.PositionOfAny("This is a test string",{"dog","string","bark"}), but the function only accepts single-character values
Expression.Error: The value isn't a single-character string.
Any solution for this?
This is a case where you'll want to combine a few M library functions together.
You'll want to use Text.Contains many times against a list, which is a good case for List.Transform. List.AnyTrue will tell you if any string matched.
List.AnyTrue(List.Transform({"dog","string","bark"}, (substring) => Text.Contains("This is a test string", substring)))
If you wished that there was a Text.ContainsAny function, you can write it!
let
Text.ContainsAny = (string as text, list as list) as logical =>
List.AnyTrue(List.Transform(list, (substring) => Text.Contains(string, substring))),
Invoked = Text.ContainsAny("This is a test string", {"dog","string","bark"})
in
Invoked
Another simple solution is this:
List.ContainsAny(Text.SplitAny("This is a test string", " "), {"dog","string","bark"})
It transforms the text into a list because there we find a function that does what you need.
If it's a specific (static) list of matches, you'll want to add a custom column with an if then else statement in PQ. Then use a filter on that column to keep or remove the columns. AFAIK PQ doesn't support regex so Alexey's solution won't work.
If you need the lookup to be dynamic, it gets more complicated... but doable you essentially need to
have an ID column for the original row.
duplicate the query so you have two queries, then in the newly created query
split the text field into separate columns, usually by space
unpivot the newly created columns.
get the list of intended names
use list.generate method to generate a list that shows 1 if there's a match and 0 if there isn't.
sum the values of the list
if sum > 0 then mark that row as a match, usually I use the value 1 in a new column. Then you can filter the table to keep only rows with value 1 in the new column. Then group this table on ID - this is the list of ID that contain the match. Now use the merge feature to merge in the first table ensuring you keep only rows that match the IDs. That should get you to where you want to be.
Thanks for giving me the lead. In my own case I needed to ensure two items exist in a string hence I replaced formula as:
List.AllTrue(List.Transform({"/","2017"},(substring) => Text.Contains("4/6/2017 13",substring)))
it returned true perfectly.
You can use regex here with logical OR - | expression :
/dog|string|bark/.test("This is a test string") // retruns true

How can I SELECT records using a select list made of foreign keys?

I have a table, DEBTOR, with a structure like this:
and a second table, DEBTOR.INFO structured like this:
I have a select list made of record IDs from the DEBTOR.INFO table. How can I
select * from DEBTOR WHERE 53 IN (name of select list)?
Is this even possible?
I realize this query looks more like SQL than RetrieVe but I wrote it that way for an easier understanding of what I'm trying to accomplish.
Currently, I accomplish this query by writing
SELECT DEBTOR WITH 53 EQ [paste list of DEBTOR.INFO record IDs]
but obviously this is unwieldy for large lists.
It looks to me that you cant do that. Even if you use and i-descriptor, It only works in one direction. TRANS("DEBTOR.INFO",53,0,"X") works from the DEBTOR file but not the other way. So TRANS("DEBTOR",#ID,53,"X") from DEBTOR.INFO will return nothing.
See this article on U2's site for a possible solution.
Would something like this work (two steps):
SELECT DEBTOR.INFO SAVING PACKET
LIST DEBTOR ....
This creates a select list of the data in the PACKET field in the DEBTOR.INFO file and makes it active. (If you have duplicate values that way you can add the keyword UNIQUE after SAVING).
Then the subsequent LIST command uses that active select list which contains values found in the #ID field of the file DEBTOR.
Not sure if you are still looking at this, but there is a simple option that will not require a lot of programming.
I did it with a program, a subroutine and a dictionary item.
First I set a named common variable to contain the list of DEBTOR.INFO ids:
SETLIST
*
* Use named common to hold list of keys
COMMON /MYKEYS/ KEYLIST
*
* Note for this example I am reading the list from SAVEDLISTS
OPEN "SAVEDLISTS" TO FILE ELSE STOP "CAN NOT OPEN SAVEDLISTS"
READ KEYLIST FROM FILE, "MIKE000" ELSE STOP "NO MIKE000 ITEM"
Now, I can create a subroutine that checks for a value in that list
CHECKLIST
SUBROUTINE CHECKLIST( RVAL, IVAL)
COMMON /MYKEYS/ KEYLIST
LOCATE IVAL IN KEYLIST <1> SETTING POS THEN
RVAL = 1
END ELSE RVAL = 0
RETURN
Lastly, I use a dictionary item to call the subroutine with the field I am looking for:
INLIST:
I
SUBR("CHECKLIST", FK)
IN LIST
10R
S
Now all I have to do is put the correct criteria on my list statement:
LIST DEBTOR WITH INLIST = 1 ACCOUNT STATUS FK
Id use the very powerfull EVAL with an XLATE ;
SELECT DEBTOR WITH EVAL \XLATE('DEBTOR.INFO',#RECORD<53>,'-1','X')\ NE ""