Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Splunk Search

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Community
- :
- Splunk Answers
- :
- Using Splunk
- :
- Splunk Search
- :
- Find a distinct count using a priority system.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark Topic
- Subscribe to Topic
- Mute Topic
- Printer Friendly Page

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JWBailey

Communicator

11-21-2014
03:03 PM

```
:: my search :: | stats count dc(player) by result
```

Let’s say the result field has two possible values, Win and Lose.

This search will give me the number of unique players for each value of result. So, a count of players that won at least once, and a count of players that lost at least once. So if a player both wins and losses (in different events), they would be counted in both totals.

What I really need, is a count of players that have won at least once, and a count of players that never won. So if a player tried 10 times, loses his first 9, but wins the 10th…. I want that to increment the Win count by one, and not affect the Lose count. Obviously if the player only has 1 result, it will increment the appropriate count.

And getting more complicated, what if the result field had three values? Win, Lose, and Tie, and I wanted to apply the same general idea. So Win > Tie > Loss. So as soon as a player has a result that is ranked higher, they will increment the count of this higher result.

How can I build a search to tally my events in this way?

Thanks.

1 Solution

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

acharlieh

Influencer

11-21-2014
04:59 PM

How about this:

```
:: your search :: | chart count over player by result | eval result=case(Win>=1,"Win",Tie>=1,"Tie",1==1,"Lose") | stats count as num_players by result
```

Assuming result can only have the values "Win" "Tie" and "Lose" of course. We get the stats for each player, then we figure out which one each counts toward, and then build stats of how many players count to each.

If you also want the count of events with each of these results in addition to the players at each... so far what i've come up with is a bit complicated:

```
:: your search :: | chart count over player by result | eval result=case(Win>=1,"Win",Tie>=1,"Tie",1==1,"Lose") | appendpipe [stats count as num_players by result | eval keep=1] | appendpipe [where NOT keep=1 | fields - result num_players keep | untable player result count | where count > 0 | eval keep=1] | where keep=1 | stats sum(count) as events first(num_players) as num_players by result
```

Also just in case you were curious this is what I've been using as `:: your search ::`

to try things out:

```
| gentimes start=-2 increment=1h | rename starttime as _time | fields | eval player="player"+tostring(floor((random()/2147483648)*100)+1) | eval win=floor((random()/2147483648)*3) | eval result= case(win==0,"Lose",win==1,"Tie",win==2,"Win")
```

Update per comment:

Assuming result takes the values 2,1,0 and that 2 means "win", 1 means "tie" and 0 means "loss" (i.e. already priority order). then the simple process still follows basically the same process, except if you are only interested in the priority you don't need the full stats just a simple max:

```
:: your search :: | stats max(result) as result by player | stats count as num_players by result
```

Doing the count of events in addition to the players of each becomes much easier as well:

```
:: your search :: | stats count by player, result | eventstats max(result) as player_result by player | stats sum(count) as events count(eval(player_result==result)) as num_players by result
```

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

acharlieh

Influencer

11-24-2014
05:30 PM

In answering your follow up question I felt like this had some strange machinations of its own, so it deserved it's own answer. (vote up if it's useful, or if mods can take your follow up and this answer and split them out into a new question, that'd be cool too).

The goal being a timechart of the number of players in a particular tier, making sure to remove them from their last tier when they bump up tiers. First the solution I came up with:

```
:: your search ::
| streamstats max(result) as tier by player
| dedup player, tier
| eval add = 1
| streamstats current=false last(tier) as remove by player
| appendpipe [search remove=* | rename remove as tier | eval add = -1]
| sort count=0 _time
| streamstats sum(add) as in_tier by tier
| timechart last(in_tier) by tier
| streamstats last(*) as *
```

So let's break this down.

`| streamstats max(result) as tier by player | dedup player, tier`

- Find the player's tier for every record, and limit only to the times the tier changes

`| eval add = 1`

- for every result we have now, we want to add one to the tier.

`| streamstats current=false last(tier) as remove by player`

- at every step, find the last tier the player was in if any

`| appendpipe [search remove=* | rename remove as tier | eval add = -1]`

- for every previous tier, add a result for the same time, for the previous tier with the add being a decrement instead of an increment.

`| sort count=0 _time`

- put the decrementing results in the proper time series order

`| streamstats sum(add) as in_tier by tier`

- calculate the number currently in each tier as each record comes in

`| timechart last(in_tier) by tier`

- for every time segment, the number currently in the tier is the last value we saw for a number in the tier for any given tier

`| streamstats last(*) as *`

- fill in gaps where a a particular time segment has no change for a particular tier

and voila!

Now dear reader, I'll leave it as an exercise to you to figure out the best way to start each tier in your search with a particular non-zero value. (but you probably want to insert events at the same time as or just before the first event or the beginning of your search window with tier and add fields specified before calculating the number in a particular tier).

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

acharlieh

Influencer

11-21-2014
04:59 PM

How about this:

```
:: your search :: | chart count over player by result | eval result=case(Win>=1,"Win",Tie>=1,"Tie",1==1,"Lose") | stats count as num_players by result
```

Assuming result can only have the values "Win" "Tie" and "Lose" of course. We get the stats for each player, then we figure out which one each counts toward, and then build stats of how many players count to each.

If you also want the count of events with each of these results in addition to the players at each... so far what i've come up with is a bit complicated:

```
:: your search :: | chart count over player by result | eval result=case(Win>=1,"Win",Tie>=1,"Tie",1==1,"Lose") | appendpipe [stats count as num_players by result | eval keep=1] | appendpipe [where NOT keep=1 | fields - result num_players keep | untable player result count | where count > 0 | eval keep=1] | where keep=1 | stats sum(count) as events first(num_players) as num_players by result
```

Also just in case you were curious this is what I've been using as `:: your search ::`

to try things out:

```
| gentimes start=-2 increment=1h | rename starttime as _time | fields | eval player="player"+tostring(floor((random()/2147483648)*100)+1) | eval win=floor((random()/2147483648)*3) | eval result= case(win==0,"Lose",win==1,"Tie",win==2,"Win")
```

Update per comment:

Assuming result takes the values 2,1,0 and that 2 means "win", 1 means "tie" and 0 means "loss" (i.e. already priority order). then the simple process still follows basically the same process, except if you are only interested in the priority you don't need the full stats just a simple max:

```
:: your search :: | stats max(result) as result by player | stats count as num_players by result
```

Doing the count of events in addition to the players of each becomes much easier as well:

```
:: your search :: | stats count by player, result | eventstats max(result) as player_result by player | stats sum(count) as events count(eval(player_result==result)) as num_players by result
```

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JWBailey

Communicator

11-24-2014
01:27 PM

Follow up question:

How can I get this data broken down over a time window? This search gives me the entire time window in 1 set of data, if I wanted to break it down by day, or hour for example.

When I try to use timechart I get no results found. I assume this is caused by the stats command not making the _time field accessible anymore?

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

acharlieh

Influencer

11-24-2014
01:51 PM

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JWBailey

Communicator

11-24-2014
07:24 AM

Yes, this is great!

One other question. I realized my example might not be a perfect representation of what I am trying to do. In my real data, the values of “result” are not text strings. How would it effect this if instead of “win” and “loss” it was numbers? So now result could be a 2, 1, or 0.

It seems like this falls short in the case function. How do I reference the number of twos or ones identified in the chart command?

I know I could use eval and if statements to get a field with text values in it, but I don’t want to add extra work to the search if I don’t need to.

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

acharlieh

Influencer

11-24-2014
08:21 AM

- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JWBailey

Communicator

11-24-2014
08:42 AM

Yes, this is exactly it. Thank you.

Sorry for the misrepresentation of my question resulting in a more complex answer. I do appreciate knowing how to do it each way now...