workspace does not return the correct value for me - smalltalk

i have problem with some code.
If i write Recenzes select: [:a | a komponenta nazev = 'Hitachi P21'] i got some right records. But if i use something like this:
| brzdy |
brzdy := (((
(Sekces select: [:b | b nazev = 'Brzdy']) collect: [:b | b komponenty]) flatten)
select: [:c | c vyrobce nazev = 'Hitachi']) collect: [:d | d nazev].
i can get 'Hitachi P21' with ^ command. But if i use variable 'brzdy' here: Recenzes select: [:a | a komponenta nazev = brzdy] i won't get anything.
In a nutshell. I want to show 'Recenzes' for 'Komponenty' which are in 'Sekces' with value 'Brzdy' and they are saved in column 'Komponenty' (Set) for 'Recenzes' and 'Sekces'.
Does anyone know why?

Since brzdy is the result of a #collect: message, it is a collection of strings, not a single string. Therefore no element a would satisfy the condition a komponenta nazev = brzdy, because you would be comparing objects of different classes. Try something on the lines of
Recenzes select: [:a | brzdy includes: a komponenta nazev]
As a side note, remember that you may eliminate some parentheses by using select:thenCollect: other than (select: blah) collect: bluh. For instance
brzdy := (Sekces select: [:b | b nazev = 'Brzdy'] thenCollect: [:b | b komponenty]) flatten
select: [:c | c vyrobce nazev = 'Hitachi']
thenCollect: [:d | d nazev]
(I'm not familiar with the #flatten message, so I can't tell whether it is necessary or superfluous).

Related

Combine query to get all the matching search text in right order

I have the following table:
postgres=# \d so_rum;
Table "public.so_rum"
Column | Type | Collation | Nullable | Default
-----------+-------------------------+-----------+----------+---------
id | integer | | |
title | character varying(1000) | | |
posts | text | | |
body | tsvector | | |
parent_id | integer | | |
Indexes:
"so_rum_body_idx" rum (body)
I wanted to do phrase search query, so I came up with the below query, for example:
select id from so_rum
where body ## phraseto_tsquery('english','Is it possible to toggle the visibility');
This gives me the results, which only match's the entire text. However, there are documents, where the distance between lexmes are more and the above query doesn't gives me back those data. For example: 'it is something possible to do toggle between the. . . visibility' doesn't get returned. I know I can get it returned with <2> (for example) distance operator by giving in the to_tsquery, manually.
But I wanted to understand, how to do this in my sql statement itself, so that I get the results first with distance of 1 and then 2 and so on (may be till 6-7). Finally append results with the actual count of the search words like the following query:
select count(id) from so_rum
where body ## to_tsquery('english','string & string . . . ')
Is it possible to do in a single query with good performance?
I don't see a canned solution to this. It sounds like you need to use plainto_tsquery to get all the results with all the lexemes, and then implement your own custom ranking function to rank them by distance between the lexemes, and maybe filter out ones with the wrong order.

KQL: mv-expand OR bag_unpack equivalent command to convert a list to multiple columns

According to mv-expand documentation:
Expands multi-value array or property bag.
mv-expand is applied on a dynamic-typed column so that each value in the collection gets a separate row. All the other columns in an expanded row are duplicated.
Just like the mv-expand operator will create a row each for the elements in the list -- Is there an equivalent operator/way to make each element in a list an additional column?
I checked the documentation and found Bag_Unpack:
The bag_unpack plugin unpacks a single column of type dynamic by treating each property bag top-level slot as a column.
However, it doesn't seem to work on the list, and rather works on top-level JSON property.
Using bag_unpack (like the below query):
datatable(d:dynamic)
[
dynamic({"Name": "John", "Age":20}),
dynamic({"Name": "Dave", "Age":40}),
dynamic({"Name": "Smitha", "Age":30}),
]
| evaluate bag_unpack(d)
It will do the following:
Name Age
John 20
Dave 40
Smitha 30
Is there a command/way (see some_command_which_helps) I can achieve the following (convert a list to columns):
datatable(d:dynamic)
[
dynamic(["John", "Dave"])
]
| evaluate some_command_which_helps(d)
That translates to something like:
Col1 Col2
John Dave
Is there an equivalent where I can convert a list/array to multiple columns?
For reference: We can run the above queries online on Log Analytics in the demo section if needed (however, it may require login).
you could try something along the following lines
(that said, from an efficiency standpoint, you may want to check your options of restructuring the data set to begin with, using a schema that matches how you plan to actually consume/query it)
datatable(d:dynamic)
[
dynamic(["John", "Dave"]),
dynamic(["Janice", "Helen", "Amber"]),
dynamic(["Jane"]),
dynamic(["Jake", "Abraham", "Gunther", "Gabriel"]),
]
| extend r = rand()
| mv-expand with_itemindex = i d
| summarize b = make_bag(pack(strcat("Col", i + 1), d)) by r
| project-away r
| evaluate bag_unpack(b)
which will output:
|Col1 |Col2 |Col3 |Col4 |
|------|-------|-------|-------|
|John |Dave | | |
|Janice|Helen |Amber | |
|Jane | | | |
|Jake |Abraham|Gunther|Gabriel|
To extract key value pairs from text and convert them to columns without hardcoding the key names in query:
print message="2020-10-15T15:47:09 Metrics: duration=2280, function=WorkerFunction, count=0, operation=copy_into, invocationId=e562f012-a994-4fc9-b585-436f5b2489de, tid=lct_b62e6k59_prd_02, table=SALES_ORDER_SCHEDULE, status=success"
| extend Properties = extract_all(#"(?P<key>\w+)=(?P<value>[^, ]*),?", dynamic(["key","value"]), message)
| mv-apply Properties on (summarize make_bag(pack(tostring(Properties[0]), Properties[1])))
| evaluate bag_unpack(bag_)
| project-away message

PIG : How to print only certain attributes from Grouped Bag

I have a grouped result which looks exactly like below :
| grouped | group:chararray | log:bag{:tuple(driverId:chararray,truckId:chararray,eventTime:chararray,eventType:chararray,longitude:chararray,latitude:chararray,eventKey:chararray,CorrelationId:chararray,driverName:chararray,routeId:chararray,routeName:chararray,eventDate:chararray)}
When I perform below :
x = FOREACH grouped GENERATE {log.driverId, log.truckId, log.driverName};
illustrate x;
The out put am getting is :
| x | :bag{:tuple(:bag{:tuple(driverId:chararray)})} |
------------------------------------------------------------------------------------
| | {({(11), (11)}), ({(74), (39)}), ({(Jamie Engesser), (Jamie Engesser)})} |
------------------------------------------------------------------------------------
Where as my expectation is :
{({(11, 74, Jamie Engesser), (11,39,Jamie Engesser)})
Got the Solutions
Since
Group was a tuple and The adjacent result was Bag i had to use Nested FOREACH like below :
x = FOREACH grouped{
val1 = group;
vals = FOREACH log GENERATE driverId, truckId, driverName;
GENERATE val1, vals;
};
So this selected only the required attributes from the given result.
Please comment if some one knows a better/optimal/easier way of doing it.
Thanks

SQL join on returns none values

// EDIT Found the problem. I changed all type from text to varchar. Now it works fine.
I have a table called "sounds" which looks like this:
rowID type int(11) | userID type text | name type text| soundfile type text
1 | "mod001:02" | "Jimmy" | "music/song.mp3"
and a table called "soundlist" which looks like this:
soundID type int(11) | name type text | soundfile type text | used type tinyint(1)
1 | "topSong" | "music/song.mp3" | 1
My problem is, when i'm run this query
SELECT *
FROM sounds
INNER JOIN soundlist
ON STRCMP(soundlist.soundfile, sounds.soundfile) = 0
WHERE STRCMP(sounds.userID, "mod001:02") = 0;
i'm getting an empty result!
My goal is to set "soundlist.used" to 0. I only have "sounds.userID" given.
I'm currently using this query:
UPDATE soundlist
INNER JOIN sounds
ON STRCMP(sounds.userID, "mod001:02") = 0
SET soundlist.used = 0
WHERE STRCMP(soundlist.soundfile, sounds.soundfile) = 0;
You can use nested queries :
UPDATE soundlist
set soundlist.used=0
where soundfile IN ( -- using IN keyword instead of = if you want to update multiple entries
select sounds.soundfile
from sounds
where sounds.rowID=1 -- or any other condition
);
I am assuming that rowID is an INT.
And if you want to go even further and don't bother comparing strings, why not using foreign keys ?
Let Sounds the same way :
rowID | userID | name | soundfile
1 | "mod001:02" | "Jimmy" | "music/song.mp3"
And modify sound list to reference sounds :
soundID | name | soundId | used
1 | "topSong" | 1 | 1
Your query :
SELECT *
FROM sounds
INNER JOIN soundlist
ON STRCMP(soundlist.soundfile, sounds.soundfile) = 0
WHERE STRCMP(sounds.userID, "mod001:02") = 0;
would become
SELECT *
FROM sounds s
INNER JOIN soundlist l
ON s.rowId=l.soundId
where STRCMP(s.userID, "mod001:02") = 0;
This saves you one STRCMP.
Consider using indexes on varchar columns used for conditions, it is faster and sometimes easier to read queries (s.userID = "mod001:02" is more straigthforward)
Edited: This will update sounds.userid to "0" where soundlist.used is "1"
UPDATE sounds
INNER JOIN soundlist ON
sounds.soundfile = soundlist.soundfile
SET sounds.userid = "0"
WHERE soundlist.used = "1"
If, instead you want the sounds.userid to equal soundlist.us
UPDATE sounds
INNER JOIN soundlist ON
sounds.soundfile = soundlist.soundfile
SET sounds.userid = soundlist.used
The problem is that you the text data type, if I use varchar the first query gets me the desired result set

Query with conditions on multiple value column

I am building report in Oracle Apex 4.2. Table that report is build on has multiple values inside one of the columns.
-----------------------------------
| ID | NAME | PROJECT_ID |
-----------------------------------
| 1 | P1 | 23:45:56 |
| 2 | P2 | 23 |
| 3 | P3 | 45:65 |
-----------------------------------
I would like to build a query to retrieve names based on project_id's.
Select name from table where project_id = 23;
This obviously will return P2 only however I would like to build a query which would return P1 and P2 if we searched for 23.
Any help greatly appreciated.
You can use LIKE instead of = :
Select name from table where project_id LIKE '%23%';
If you've got a common delimiter such as the ':' in your example you could use the following to exclude results like '123':
SELECT name FROM table WHERE ':' || project_id || ':' LIKE '%:23:%'
By concatenating the delimiter to the front and back of the string, you don't have to write multiple criteria: LIKE '23:%' OR LIKE '%:23:%' OR LIKE '%:23' to handle the first and last number in the list.
This is a common design in Apex due to its builtin support for colon-delimited strings (e.g. to drive shuttle controls and other item types).
I generally use this pattern:
Select name from table where INSTR(':'||project_id||':',':23:') > 0;
P.S. It's a pity about that column name - I would have called it something like PROJECT_ID_LIST.