How to aggregate logs by field and then by bin in AWS CloudWatch Insights? - amazon-cloudwatch

I'm trying to do a query that will first aggregate by field count and after by bin(1h) for example I would like to get the result like:
# Date Field Count
1 2019-01-01T10:00:00.000Z A 123
2 2019-01-01T11:00:00.000Z A 456
3 2019-01-01T10:00:00.000Z B 567
4 2019-01-01T11:00:00.000Z B 789
Not sure if it's possible though, the query should be something like:
fields Field
| stats count() by Field by bin(1h)
Any ideas how to achieve this?

Is this what you need?
fields Field | stats count() by Field, bin(1h)

If you want to create a line chart, you can do it by separately counting each value that your field could take.
fields
Field = 'A' as is_A,
Field = 'B' as is_B
| stats sum(is_A) as A, sum(is_B) as B by bin(1hour)
This solution requires your query to include a string literal of each value ('A' and 'B' in OP's example). It works as long as you know what those possible values are.
This might be what Hugo Mallet was looking for, except the avg() function won't work here so he'd have to calculate the average by dividing by a total

Not able to group by a certain field and create visualizations.
fields Field
| stats count() by Field, bin(1h)
Keep getting this message
No visualization available. Try this to get started:
stats count() by bin(30s)

Related

How to apply group_concat in Splunk SPL

I want to implement a group_concat-like behavior in Splunk.Here as in the table where serviceA has 2 entries which need to be combined with a delimiter and the count needs to be added. Is there any way we can achieve the functionality using SPL. Any help is appreciated. Thanks!!
... | stats count, values(Status) by Service_Name
You need to create a multi-value field and values() will be an appropriate way to do it in your case
To combine the Status values with comma separators, add these commands to your query.
| stats count as Count, values(Status) as Status by Service_name
| eval Status = mvjoin(Status, ",")

Filter out values using mstats

I am trying to filter out all negative values in my metrics, I would like to know if the filtering within the mstats call itself possible, to add something like AND metrics_name:data.value > 0 to the query below?
| mstats avg(_value) WHERE metric_name="data.value" AND index="my_metrics" BY data.team
Currently, I am using the msearch and then filtering out the events, so my query is something like the one below but its too slow as I am pulling all the events:
| msearch index=my_metrics
| fields "metrics_name:data.value"
| where mvcount(mvfilter(tonumber(metrics_name:data.value') > 0)) >= 1 OR isnull('metrics_name:data.value')
Unfortunately, you cannot filter or group-by the _value field with Metrics.
You may be able to speed up your search with msearch by including the metric_name in the filter.
| msearch index=my_metrics filter="metric_name=data.value"
Note that using msearch returns a sample of the metric values, not all of them, unless you specify target_per_timeseries=0
Refer to https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Mstats

Calculate data in a second column using data from the first one

I need to create a SQL query which calculates some data.
For instance, I have such SQL query:
SELECT SUM(AMOUNT) FROM FIRMS WHERE FIRM_ID IN(....) GROUP BY FIRM;
which produces such data:
28,740,573
30,849,923
25,665,724
43,223,313
34,334,534
35,102,286
38,556,820
19,384,871
Now, in a second column I need to show relation between one entry and sum of all entries. Like that:
28,740,573 | 0.1123
30,849,923 | 0.1206
25,665,724 | 0.1003
43,223,313 | 0.1689
34,334,534 | 0.1342
35,102,286 | 0.1372
38,556,820 | 0.1507
19,384,871 | 0.0758
For instance, sum of all entries from first column above is gonna be 255,858,044 and the value in a first entry, second cell is gonna be 28,740,573 / 255,858,044 = 0.1123. And same for each entry in a result.
How can I do that?
UPD: Thanks #a_horse_with_no_name, I forgot to DBMS. It's Oracle.
Most databases now support the ANSI standard window functions. So, you can do:
SELECT SUM(AMOUNT),
SUM(AMOUNT) / SUM(SUM(AMOUNT)) OVER () as ratio
FROM FIRMS
WHERE FIRM_ID IN (....)
GROUP BY FIRM;
Note: Some databases do integer division. So, if AMOUNT is an integer, then you need to convert to a non-integer number in these databases. One easy method is to multiple by 1.0.

Transposing a field into fields

I have a query that produces a 2 field result: Email and Interest.
The result is millions of records. But there are about 100 distinct Interests.
I would like to run the query to produce a result that is 101 fields wide like this:
Email | Books | Cats | Dogs | ETC
Where the metric is the count of each.
With my knowledge of SQL thus far I'd have to use CASE WHEN. But I'd have to write 100 lines of code.
Is there a better way?
You could use the PIVOT statement but sounds like terradata does not support that. Pivot would require typing in all column names as well. Don't think you can avoid that

Postgresql (Rails 3) merge rows on column (same table)

First, I've been using mysql for forever and am now upgrading to postgresql. The sql syntax is much stricter and some behavior different, thus my question.
I've been searching around for how to merge rows in a postgresql query on a table such as
id | name | amount
0 | foo | 12
1 | bar | 10
2 | bar | 13
3 | foo | 20
and get
name | amount
foo | 32
bar | 23
The closest I've found is Merge duplicate records into 1 records with the same table and table fields
sql returning duplicates of 'name':
scope :tallied, lambda { group(:name, :amount).select("charges.name AS name,
SUM(charges.amount) AS amount,
COUNT(*) AS tally").order("name, amount desc") }
What I need is
scope :tallied, lambda { group(:name, :amount).select("DISTINCT ON(charges.name) charges.name AS name,
SUM(charges.amount) AS amount,
COUNT(*) AS tally").order("name, amount desc") }
except, rather than returning the first row of a given name, should return mash of all rows with a given name (amount added)
In mysql, appending .group(:name) (not needing the initial group) to the select would work as expected.
This seems like an everyday sort of task which should be easy. What would be a simple way of doing this? Please point me on the right path.
P.S. I'm trying to learn here (so are others), don't just throw sql in my face, please explain it.
I've no idea what RoR is doing in the background, but I'm guessing that group(:name, :amount) will run a query that groups by name, amount. The one you're looking for is group by name:
select name, sum(amount) as amount, count(*) as tally
from charges
group by name
If you append amount to the group by clause, the query will do just that -- i.e. count(*) would return the number of times each amount appears per name, and the sum() would return that number times that amount.