Priority Sorting on a column Kusto Query - database
Scenario: Players can be marked with the status winner, tied, or loser. The priorities of the status is as such: If a player is ever "tied", they can't be a "loser", if they are ever a "winner", they can't be a "loser" or "tied". Table 1 has error rows recorded but the desired table should display the players and their up-to-date status and the timestamp of the most recent correct records. Is this something that is doable with Kusto? I can select the most recent by timestamp with the query below. I am unsure how to compare. I've started looking at the prev() function but I'm not certain this will do what I want in terms of comparing based on a priority. (https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/prevfunction)
let T1 = datatable(player:string, status:string, timestamp:datetime)
[
"A", "winner", datetime(2020-11-24 08:00),
"A", "winner", datetime(2020-11-24 10:00),
"B", "tied", datetime(2020-11-24 09:00),
"B", "tied", datetime(2020-11-24 11:00),
"B", "tied", datetime(2020-11-24 14:00),
"B", "loser", datetime(2020-11-24 15:00),
"C", "loser", datetime(2020-11-24 08:00),
"C", "loser", datetime(2020-11-24 10:00),
"C", "loser", datetime(2020-11-24 11:00),
"C", "loser", datetime(2020-11-24 13:00),
"C", "tied", datetime(2020-11-24 14:00),
"C", "winner", datetime(2020-11-24 15:00),
"D", "winner", datetime(2020-11-24 07:00),
"D", "winner", datetime(2020-11-24 11:00),
"D", "winner", datetime(2020-11-24 16:00),
"D", "tied", datetime(2020-11-24 21:00),
"E", "tied", datetime(2020-11-24 09:00),
"E", "tied", datetime(2020-11-24 11:00),
"E", "loser", datetime(2020-11-24 13:00),
"E", "tied", datetime(2020-11-24 18:00),
"F", "loser", datetime(2020-11-24 10:00),
"F", "loser", datetime(2020-11-24 11:00),
"F", "loser", datetime(2020-11-24 18:00),
"G", "loser", datetime(2020-11-24 11:00),
"G", "tied", datetime(2020-11-24 14:00),
"G", "loser", datetime(2020-11-24 16:00),
"G", "tied", datetime(2020-11-24 18:00),
"G", "loser", datetime(2020-11-24 21:00),
]
;
T1
| summarize arg_max(timestamp, *) by player
| order by player asc
result:
player| timestamp | status
_____________________________________________
A | 2020-11-24 10:00:00.0000000 | winner
B | 2020-11-24 15:00:00.0000000 | loser
C | 2020-11-24 15:00:00.0000000 | winner
D | 2020-11-24 21:00:00.0000000 | tied
E | 2020-11-24 18:00:00.0000000 | tied
F | 2020-11-24 18:00:00.0000000 | loser
G | 2020-11-24 21:00:00.0000000 | loser
H | 2020-11-24 21:00:00.0000000 | loser
final desired result table:
player| timestamp | status
_____________________________________________
A | 2020-11-24 10:00:00.0000000 | winner
B | 2020-11-24 14:00:00.0000000 | tied
C | 2020-11-24 15:00:00.0000000 | winner
D | 2020-11-24 16:00:00.0000000 | winner
E | 2020-11-24 18:00:00.0000000 | tied
F | 2020-11-24 18:00:00.0000000 | loser
G | 2020-11-24 18:00:00.0000000 | tied
H | 2020-11-24 09:00:00.0000000 | winner
If I understand your question correctly, the following could work.
Calculate the aggregated status per player, according the logic you've provided (using make_set() and array_index_of().
Find the max. timestamp per player/state, using a join
let T =
datatable(player: string, status: string, timestamp: datetime)
[
"A", "winner", datetime(2020-11-24 08:00),
"A", "winner", datetime(2020-11-24 10:00),
"B", "tied", datetime(2020-11-24 09:00),
"B", "tied", datetime(2020-11-24 11:00),
"B", "tied", datetime(2020-11-24 14:00),
"B", "loser", datetime(2020-11-24 15:00),
"C", "loser", datetime(2020-11-24 08:00),
"C", "loser", datetime(2020-11-24 10:00),
"C", "loser", datetime(2020-11-24 11:00),
"C", "loser", datetime(2020-11-24 13:00),
"C", "tied", datetime(2020-11-24 14:00),
"C", "winner", datetime(2020-11-24 15:00),
"D", "winner", datetime(2020-11-24 07:00),
"D", "winner", datetime(2020-11-24 11:00),
"D", "winner", datetime(2020-11-24 16:00),
"D", "tied", datetime(2020-11-24 21:00),
"E", "tied", datetime(2020-11-24 09:00),
"E", "tied", datetime(2020-11-24 11:00),
"E", "loser", datetime(2020-11-24 13:00),
"E", "tied", datetime(2020-11-24 18:00),
"F", "loser", datetime(2020-11-24 10:00),
"F", "loser", datetime(2020-11-24 11:00),
"F", "loser", datetime(2020-11-24 18:00),
"G", "loser", datetime(2020-11-24 11:00),
"G", "tied", datetime(2020-11-24 14:00),
"G", "loser", datetime(2020-11-24 16:00),
"G", "tied", datetime(2020-11-24 18:00),
"G", "loser", datetime(2020-11-24 21:00),
]
;
T
| summarize make_set(status) by player
| project player, status = case(array_index_of(set_status, "winner") > -1, "winner",
array_index_of(set_status, "tied") > -1, "tied",
"loser")
| join (
T
| summarize timestamp = max(timestamp) by player, status
) on player, status
| project player, timestamp, status
Related
Ruby merge a nested array based on inner array's first element [closed]
Closed. This question needs details or clarity. It is not currently accepting answers. Want to improve this question? Add details and clarify the problem by editing this post. Closed 7 months ago. Improve this question I have a nested Ruby array: array = [["id1", "Mike", "a", "aa"], ["id1", "Mike", "a", "bb"], ["id1", "Mike", "a", "cc"], ["id1", "Mike", "b", "aa"], ["id1", "Mike", "b", "bb"], ["id1", "Mike", "b", "cc"], ["id2", "Joe", "a", "aa"], ["id2", "Joe", "a", "bb"], ["id2", "Joe", "a", "cc"], ["id2", "Joe", "b", "aa"], ["id2", "Joe", "b", "bb"], ["id2", "Joe", "b", "cc"], ["id2", "Joe", "c", "aa"], ["id2", "Joe", "c", "bb"], ["id2", "Joe", "c", "cc"]] I want to merge it based on the first element, with grouping as such: result = [["id1", "Mike", ["a", "b"], ["aa", "bb", "cc"]], ["id2", "Joe", ["a", "b", "c"], ["aa", "bb", "cc"]]] What's the best way to do this?
Code result = array.group_by { |a| [a[0], a[1]] }.map do |k, v| v.map { |id, name, v1, v2| [v1, v2] }.transpose.map(&:uniq).prepend(*k) end p result Output [["id1", "Mike", ["a", "b"], ["aa", "bb", "cc"]], ["id2", "Joe", ["a", "b", "c"], ["aa", "bb", "cc"]]]
How do I merge arrays from multiple documents without duplicates in MongoDB aggregation?
I have 3 documents: { "id": 1, "user": "Brian1", "configs": [ "a", "b", "c", "d" ] } ---- { "id": 2, "user": "max_en", "configs": [ "a", "h", "i", "j" ] } ---- ---- { "id": 3, "user": "userX", "configs": [ "t", "u", "s", "b" ] } I want to merge all the "configs" arrays into one array without dublicates,like this: { "configs": [ "a", "b", "c", "d", "h", "i", "j", "t", "u", "s", ] } I've tried the following: Aggregation.group("").addToSet("configs").as("configs") and { _id: "", 'configs': { $addToSet: '$configs' } } The first one gives an error because I've left the fieldname empty (I don't know what to put there). The second one returns a merged array but with duplicates.
When you want to group all the documents, you need to add {_id: null} It means group all documents. Probably you need this db.collection.aggregate([ { "$unwind": "$configs" }, { $group: { _id: null, configs: { "$addToSet": "$configs" } } } ]) But be cautious when you need to use on larger collection without a match.
JQ how to merge multiple objects in an array into one
A little more sophisticated as my question mentioned below. I learned to use arrays more, but it screws things up too. Input: { "a": [ { "b": "c", "d": "e" }, { "b": "f", "d": "g" } ], "h": [ { "b": "c", "i": "j" }, { "b": "f", "i": "k" } ] } desired output: { "l": [ { "b": "c", "d": "e", "i": "j" }, { "b": "f", "d": "g", "i": "k" } ] } Things that I've tried, based up on JQ How to merge multiple objects into one { x: [ inputs | .a[] | { (.h[]): .i } ] | add}
The key to a simple solution is transpose: [.a, .h] | transpose | map(add) | {l: .}
Adding parameters to Array Product function in Ruby
So I've been scratching my head trying to find a solution to this. I need a method that will take any number of arrays that I need to collect the product of. 1 array: return [A, B, C] # => [A, B, C] 2 arrays: return [A, B, C].product([1, 2, 3]) # => [[A, 1], [A, 2], [A, 3], [B, 1] ... [C, 3]] 3 arrays: return [A, B, C].product([1, 2, 3,],[x, y, z]) # => [[A, 1, x], [A, 1, y], ... [C, 3, z]] So my current solution is this case switch, which is functional but inconvenient. case options.count when 1 options[0].values when 2 options[0].values.product(options[1].values) when 3 options[0].values.product(options[1].values, options[2].values) when 4 options[0].values.product(options[1].values, options[2].values, options[3].values) end What I'm looking for is a method that procedurally or recursively returns the product of an unknown number of arrays. The output needs to be like the above arrays. I've tried: array = options[0].values options.each_with_index do |option, i| array = array.product(option.values) if i > 0 end return array But it returns: [[[A, 1], x], [[A, 1], y], [[A, 1], z], [[A, 2], x], ... [[C, 3], z]] Which groups the values incorrectly.
How about something like: def multi_product(base, *args) base.product(*args) end results: multi_product(['A', 'B', 'C']) # => [["A"], ["B"], ["C"]] multi_product(['A', 'B', 'C'], [1, 2, 3]) # => [["A", 1], ["A", 2], ["A", 3], ["B", 1], ["B", 2], ["B", 3], ["C", 1], ["C", 2], ["C", 3]] multi_product(['A', 'B', 'C'], [1, 2, 3], ['x', 'y', 'z']) # => [["A", 1, "x"], ["A", 1, "y"], ["A", 1, "z"], ["A", 2, "x"], ["A", 2, "y"], ["A", 2, "z"], ["A", 3, "x"], ["A", 3, "y"], ["A", 3, "z"], ["B", 1, "x"], ["B", 1, "y"], ["B", 1, "z"], ["B", 2, "x"], ["B", 2, "y"], ["B", 2, "z"], ["B", 3, "x"], ["B", 3, "y"], ["B", 3, "z"], ["C", 1, "x"], ["C", 1, "y"], ["C", 1, "z"], ["C", 2, "x"], ["C", 2, "y"], ["C", 2, "z"], ["C", 3, "x"], ["C", 3, "y"], ["C", 3, "z"]] multi_product(['A', 'B', 'C'], [1, 2, 3], ['x', 'y', 'z'], [4, 5, 6]) # => [["A", 1, "x", 4], ["A", 1, "x", 5], ["A", 1, "x", 6], ["A", 1, "y", 4], ["A", 1, "y", 5], ["A", 1, "y", 6], ["A", 1, "z", 4], ["A", 1, "z", 5], ["A", 1, "z", 6], ["A", 2, "x", 4], ["A", 2, "x", 5], ["A", 2, "x", 6], ["A", 2, "y", 4], ["A", 2, "y", 5], ["A", 2, "y", 6], ["A", 2, "z", 4], ["A", 2, "z", 5], ["A", 2, "z", 6], ["A", 3, "x", 4], ["A", 3, "x", 5], ["A", 3, "x", 6], ["A", 3, "y", 4], ["A", 3, "y", 5], ["A", 3, "y", 6], ["A", 3, "z", 4], ["A", 3, "z", 5], ["A", 3, "z", 6], ["B", 1, "x", 4], ["B", 1, "x", 5], ["B", 1, "x", 6], ["B", 1, "y", 4], ["B", 1, "y", 5], ["B", 1, "y", 6], ["B", 1, "z", 4], ["B", 1, "z", 5], ["B", 1, "z", 6], ["B", 2, "x", 4], ["B", 2, "x", 5], ["B", 2, "x", 6], ["B", 2, "y", 4], ["B", 2, "y", 5], ["B", 2, "y", 6], ["B", 2, "z", 4], ["B", 2, "z", 5], ["B", 2, "z", 6], ["B", 3, "x", 4], ["B", 3, "x", 5], ["B", 3, "x", 6], ["B", 3, "y", 4], ["B", 3, "y", 5], ["B", 3, "y", 6], ["B", 3, "z", 4], ["B", 3, "z", 5], ["B", 3, "z", 6], ["C", 1, "x", 4], ["C", 1, "x", 5], ["C", 1, "x", 6], ["C", 1, "y", 4], ["C", 1, "y", 5], ["C", 1, "y", 6], ["C", 1, "z", 4], ["C", 1, "z", 5], ["C", 1, "z", 6], ["C", 2, "x", 4], ["C", 2, "x", 5], ["C", 2, "x", 6], ["C", 2, "y", 4], ["C", 2, "y", 5], ["C", 2, "y", 6], ["C", 2, "z", 4], ["C", 2, "z", 5], ["C", 2, "z", 6], ["C", 3, "x", 4], ["C", 3, "x", 5], ["C", 3, "x", 6], ["C", 3, "y", 4], ["C", 3, "y", 5], ["C", 3, "y", 6], ["C", 3, "z", 4], ["C", 3, "z", 5], ["C", 3, "z", 6]] What it does is take one required parameter (base) which responds to product and then the *args takes a variable number of other parameters and stores them in an array args. You can then use * to deconstruct an array back into an argument list, which is done inside the call to product(*args) so that (in the case of the second example) ends up looking like ['A', 'B', 'C'].product([1, 2, 3], ['x', 'y', 'z'])
Hope this helps a = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]] a[0].product(*a[1..a.length]) #=> [["a", "d", "g"], ["a", "d", "h"], ["a", "d", "i"], ["a", "e", "g"], ["a", "e", "h"], ["a", "e", "i"], ["a", "f", "g"], ["a", "f", "h"], ["a", "f", "i"], ["b", "d", "g"], ["b", "d", "h"], ["b", "d", "i"], ["b", "e", "g"], ["b", "e", "h"], ["b", "e", "i"], ["b", "f", "g"], ["b", "f", "h"], ["b", "f", "i"], ["c", "d", "g"], ["c", "d", "h"], ["c", "d", "i"], ["c", "e", "g"], ["c", "e", "h"], ["c", "e", "i"], ["c", "f", "g"], ["c", "f", "h"], ["c", "f", "i"]] # or a.slice!(0).product(*a) #Note: this mutates array. # or a[0].product(*a.drop(1)) # suggested by Cary Swoveland
turn array columns into rows ruby [closed]
Closed. This question needs details or clarity. It is not currently accepting answers. Want to improve this question? Add details and clarify the problem by editing this post. Closed 6 years ago. Improve this question I have an array of arrays called puzzle and I'm trying to return a new array with the first array consisting of ["a", "s", "i", "o", "s", "u", "z"] Then the next array consisting of the array"s second index ["k", "o", "t", "t", "e", "r", "s"] etc etc. What are some good ways to do this. I was thinking of using map and two counters but could not get them to operate or or increase at different times properly. Any help would be awesome. Thanks! I want to return a new array from this puzzle: puzzle = [ ["a", "k", "f", "o", "x", "e", "s"], ["s", "o", "a", "w", "a", "h", "p"], ["i", "t", "c", "k", "e", "t", "n"], ["o", "t", "s", "d", "h", "o", "h"], ["s", "e", "x", "g", "s", "t", "a"], ["u", "r", "p", "i", "w", "e", "u"], ["z", "s", "b", "n", "u", "i", "r"] ]
Array#transpose is there for you: puzzle = [ ["a", "k", "f", "o", "x", "e", "s"], ["s", "o", "a", "w", "a", "h", "p"], ["i", "t", "c", "k", "e", "t", "n"], ["o", "t", "s", "d", "h", "o", "h"], ["s", "e", "x", "g", "s", "t", "a"], ["u", "r", "p", "i", "w", "e", "u"], ["z", "s", "b", "n", "u", "i", "r"] ] puzzle.transpose # => [["a", "s", "i", "o", "s", "u", "z"], # ["k", "o", "t", "t", "e", "r", "s"], # ["f", "a", "c", "s", "x", "p", "b"], # ["o", "w", "k", "d", "g", "i", "n"], # ["x", "a", "e", "h", "s", "w", "u"], # ["e", "h", "t", "o", "t", "e", "i"], # ["s", "p", "n", "h", "a", "u", "r"]]
class Array def my_transpose! size.times do |i| 0.upto(i) do |j| # iterate only through lower half self[i][j], self[j][i] = self[j][i], self[i][j] # swap rows and cols end end self # return the array itself end def my_transpose dup.map(&:dup).my_transpose! # inner arrays are dup'ed, too end end OR if you don't need a mutator.... .transpose method then pick the array you want with [] puzzle.transpose[0] The [0] says give me the first result. puzzle.transpose[0] => ["a", "s", "i", "o", "s", "u", "z"] puzzle.transpose[1] => ["k", "o", "t", "t", "e", "r", "s"]