Add a row with total in Log Analytics Kusto query - kql

I query a request log for a summary of status codes. However I would like to add a row at the end of the results, showing the total number of requests. How do I add such a row?
Current query (simplified)
MyLog
| summarize count() by responseCode
Current result looks like
responseCode
count
200
1000
404
20
500
100
I would like to have the totals like this
responseCode
count
200
1000
404
20
500
100
total
1120

you could try this:
MyLog
| summarize c = count() by responseCode
| as hint.materialized=true T
| union (T | summarize c = sum(c) by responseCode = "total")
or this:
MyLog
| summarize c = count() by responseCode
| union (print responseCode = "total", c = toscalar(MyLog | count))
if you want to keep the 'total' row last, you can order the unioned data set. for example:
MyLog
| summarize c = count() by responseCode
| extend _o = 0
| union (
print responseCode = "total",
c = toscalar(MyLog | count),
_o = 1
)
| order by _o asc, c desc
| project-away _o

Related

Sum and Count from joinee and count from joiner table group by single column

I am trying to build a query to be displayed on a table for a web app. The goal is to get a table that looks like this.
source | totalBytes | totalPackets | totalFlows |
----------------------------------------------------------
192.168.1.1 | 53341 | 1002 | 100 |
192.168.1.2 | 4222333 | 2535 | 5 |
192.168.1.3 | 244451 | 110 | 25 |
I can get to this query very easily but once I want to try to get packet count I have problems integrating the total amount of packets for each flow in the group by.
SELECT
source,
SUM("totalPacketLength") AS totalBytes,
COUNT(flows.id) totalFlows
FROM pcaps.flow flows
WHERE flows.pcap_id = 15
GROUP BY source
ORDER BY sum DESC
RESULT:
source | totalBytes | totalFlows |
-------------------------------------------
192.168.1.1 | 53341 | 100 |
192.168.1.2 | 4222333 | 5 |
192.168.1.3 | 244451 | 25 |
I have also tried this query
SELECT
source,
SUM("totalPacketLength") AS totalBytes,
COUNT(DISTINCT packets.id) totalPackets,
COUNT(DISTINCT flows.id) totalFlows
FROM pcaps.flow flows
LEFT JOIN pcaps.packet packets
ON packets.flow = flows.id AND packets.pcap = flows.pcap_id
WHERE flows.pcap_id = 15
GROUP BY source
ORDER BY sum DESC
This produces the wrong totalBytes (even if I use DISTINCT).
You want to aggregate before joining. I think this does what you want:
SELECT f.source,
SUM("totalPacketLength") AS totalBytes,
COUNT(f.id) totalFlows,
SUM(p.num_packets)
FROM pcaps.flow f LEFT JOIN
(SELECT p.flow, p.pcap_id, COUNT(*) as num_packets
FROM pcaps.packet p
GROUP BY p.flow, p.pcap_id
) p
ON packets.flow = flows.id AND packets.pcap = flows.pcap_id
WHERE f.pcap_id = 15
GROUP BY f.source
ORDER BY sum DESC

Sum of two tables using SQL

I'm trying to get the sum of two columns, but it seems to be adding incorrectly. I have a table Tbl_Booths and another table called Tbl_Extras.
In the Tbl_Booths:
BoothId | ExhId | BoothPrice
1 | 1 | 400
2 | 1 | 500
3 | 2 | 400
4 | 3 | 600
So totalBoothPrice for ExhId = 1 is 900
Tbl_Extras:
ExtraId | ExhId | Item | ItemCost
1 | 1 | PowerSupply | 400
2 | 2 | PowerSupply | 400
3 | 1 | Lights | 600
4 | 3 | PowerSupply | 400
5 | 4 | Lights | 400
So totalItemCost for ExhId = 1 is 1000
I need to find a way to get the sum of totalBoothPrice + totalItemCost
The value should of course be 900 + 1000 = 1900
I'm a total beginner to SQL so please have patience :-)
Thank you in advance for any input you can give me, since I'm going made here !
It is used in a Caspio database system.
You can use union all to combine the two tables and then aggregate:
select exhid, sum(price)
from ((select exhid, boothprice as price
from tbl_booths
) union all
(select exhid, itemcost as price
from tbl_extras
)
) e
group by exhid;
This returns the sum for all exhid values. If you want to filter them, then you can use a where clause in either the outer query or both subqueries.
Here is a db<>fiddle.
Booth totals:
select exhid, sum(boothprice) as total_booth_price
from tbl_booths
group by exhid;
Extra totals:
select exhid, sum(itemcost) as total_item_cost
from tbl_extras
group by exhid;
Joined:
select
exhid,
b.total_booth_price,
e.total_item_cost,
b.total_booth_price + e.total_item_cost as total
from
(
select exhid, sum(boothprice) as total_booth_price
from tbl_booths
group by exhid
) b
join
(
select exhid, sum(itemcost) as total_item_cost
from tbl_extras
group by exhid
) e using (exhid)
order by exhid;
This only shows exhids that have both booth and extras, though. If one can be missing use a left outer join. If one or the other can be missing, you'd want a full outer join, which MySQL doesn't support.

how to divide the amount for each record on specific condition

I have a table let's assume X
and I want to join it to another table Y
this the content of X
ID | value
------------------
100 | -500
200 | 45
300 | -100
table Y
ID | store_code
---------------------
100 | 7001
100 | 7002
100 | 7003
200 | 3001
200 | 3002
300 | 5001
If I made a relationship between X & Y tables
the amount it will be duplicated, so if I used sum function the total will be wrong
I decided to divide the amount between the stores for each ID
for example
the amount for ID 200 will be like this
ID | store_code | amount
200 | 3001 | 22.5
200 | 3002 | 22.5
when I use sum function the result will return to its original value 45
how can I do this calculation in SQL code?
Hmmm . . . If I understand correctly, you want to allocate the full value over multiple rows. Use window functions:
select y.id, y.store_code,
(x.value / count(*) over (partition by y.id)) as amount
from x join
y
on x.id = y.id
Try this:
Select id, store_code, value/count amount
from(select x.id, y.store_code, y.value,
count(x.id) OVER (PARTITION BY store_code) count
from x JOIN y ON x.id = y.id)
Looks like you need to aggregate that?
If yes, you can just add X.value into group-by list and select-list as-is.

how to get daily profit from sql table

I'm stucking for a solution at the problem of finding daily profits from db (ms access) table. The difference wrt other tips I found online is that I don't have in the table a field "Price" and one "Cost", but a field "Type" which distinguish if it is a revenue "S" or a cost "C"
this is the table "Record"
| Date | Price | Quantity | Type |
-----------------------------------
|01/02 | 20 | 2 | C |
|01/02 | 10 | 1 | S |
|01/02 | 3 | 10 | S |
|01/02 | 5 | 2 | C |
|03/04 | 12 | 3 | C |
|03/03 | 200 | 1 | S |
|03/03 | 120 | 2 | C |
So far I tried different solutions like:
SELECT
(SELECT SUM (RS.Price* RS.Quantity)
FROM Record RS WHERE RS.Type='S' GROUP BY RS.Data
) as totalSales,
(SELECT SUM (RC.Price*RC.Quantity)
FROM Record RC WHERE RC.Type='C' GROUP BY RC.Date
) as totalLosses,
ROUND(totalSales-totaleLosses,2) as NetTotal,
R.Date
FROM RECORD R";
in my mind it could work but obviously it doesn't
and
SELECT RC.Data, ROUND(SUM (RC.Price*RC.QuantitY),2) as DailyLoss
INTO #DailyLosses
FROM Record RC
WHERE RC.Type='C' GROUP BY RC.Date
SELECT RS.Date, ROUND(SUM (RS.Price*RS.Quantity),2) as DailyRevenue
INTO #DailyRevenues
FROM Record RS
WHERE RS.Type='S'GROUP BY RS.Date
SELECT Date, DailyRevenue - DailyLoss as DailyProfit
FROM #DailyLosses dlos, #DailyRevenues drev
WHERE dlos.Date = drev.Date";
My problem beyond the correct syntax is the approach to this kind of problem
You can use grouping and conditional summing. Try this:
SELECT data.Date, data.Income - data.Cost as Profit
FROM (
SELECT Record.Date as Date,
SUM(IIF(Record.Type = 'S', Record.Price * Record.Quantity, 0)) as Income,
SUM(IIF(Record.Type = 'C', Record.Price * Record.Quantity, 0)) as Cost,
FROM Record
GROUP BY Record.Date
) data
In this case you first create a sub-query to get separate fields for Income and Cost, and then your outer query uses subtraction to get actual profit.

SQLlite strftime function to get grouped data by months

i have table with following structure and data:
I would like to get grouped data by months in given date range for example (from 2014-01-01 to 2014-12-31). Data for some months cannot be available but i still need to have in result information that in given month is result 0.
Result should have following format:
MONTH | DIALS_CNT | APPT_CNT | CONVERS_CNT | CANNOT_REACH_CNT |
2014-01 | 100 | 50 | 20 | 30 |
2014-02 | 100 | 40 | 30 | 30 |
2014-03 | 0 | 0 | 0 | 0 |
etc..
WHERE
APPT_CNT = WHERE call.result = APPT
CONVERS_CNT = WHERE call.result = CONV_NO_APPT
CANNOT_REACH_CNT = WHERE call.result = CANNOT_REACH
How can i do it please with usage function strftime ?
Many thanks for any help or example.
SELECT Month,
(SELECT COUNT(*)
FROM MyTable
WHERE date LIKE Month || '%'
) AS Dials_Cnt,
(SELECT SUM(Call_Result = 'APPT')
FROM MyTable
WHERE date LIKE Month || '%'
) AS Appt_Cnt,
...
FROM (SELECT '2014-01' AS Month UNION ALL
SELECT '2014-02' UNION ALL
SELECT '2014-03' UNION ALL
...
SELECT '2014-12')