Combining SQL query for greater than and less than into one - mysql

I have following two queries:
select count * form a where temp>str group by x,y
select count * form a where temp<=str group by x,y
This result in parsing of table twice. Since the table size is 100 of gigs I was thinking if we can reduce this to single query.

select sum(IF(temp>'str',1,0)) as GREATER,
sum(IF(temp<'str',1,0)) as LESSER
from a
group by x,y
This will return a single row with two fields, GREATER and LESSER, which contain the counts of the number of rows which are Greater and Lesser than the string respectively.
IF(temp>'str',1,0)) returns a 1 if greater, else 0. Summing these values will give the total number of rwos which are greater.
IF(temp<'str',1,0)) returns a 1 if lesser, else 0. Summing these values will give the total number of rwos which are lesser.

Try this:
SELECT
SUM(CASE WHEN `temp` > `str` THEN 1 ELSE 0 END) AS `greater`,
SUM(CASE WHEN `temp` < `str` THEN 1 ELSE 0 END) AS `less`
FROM
`a`
GROUP BY
`x`,
`y`

Related

How to calculate AVG, MAX and MIN number of rows in a column

I try to collect general statistics on the depth of correspondence: average, maximum and minimum number of messages of each type per one request. Have 2 tables:
First:
ticketId,ticketQueueId,ticketCreatedDate
Second:
articleId,articleCreatedDt,articleType (can be IN or OUT - support responses), ticketId
I reasoned like this:
SELECT AVG(COUNT(articleType='IN')) AS AT_IN, AVG(COUNT(articleType='OUT')) AS AT_OUT
FROM tickets.tickets JOIN tickets.articles
ON tickets.ticketId=articles.ticketId;
GROUP BY tickets.ticketId
but it doesn't work.
Error Code: 1111. Invalid use of group function
you can't use nested aggregation function (AVG(COUNT())) but use proper subquery and apply the aggregation function the the subquery gradually
also your use of of count in improper
the count function count each row where the related column is not null so in your case the evaluation articleType='IN' (or articleType='OUT') returning 0 or 1 is never null
select AVG(T_IN), AVG(T_OUT)
from (
SELECT sum(case when articleType='IN' then 1 else 0 END AS T_IN, sum(case when articleType='OUT' then 1 else 0 END AS T_OUT
FROM tickets.tickets
JOIN tickets.articles ON tickets.ticketId=articles.ticketId
GROUP BY tickets.ticketId
) t
(and You have also a wrong semicolon )

Count Number of rows with negative integers in mysql

i have a timestamp column in my DB and i want to sum the number of rows that are passed due, let me show you the query for that!
SELECT TIMESTAMPDIFF(MINUTE, `Opened`, NOW()) as PastDue FROM `Task`
not this query returns the perfect result and return all rows where past due is negative and others are positive
now i want to count the number of negative rows so i did
SELECT COUNT(TIMESTAMPDIFF(MINUTE, `Opened`, NOW())) < 0 as PastDue FROM `Task`
it currently returns 0 now there are two rows with negative result so it should return two but it always returns 0 , can anyone point out what i am missing?
COUNT(TIMESTAMPDIFF(MINUTE, `Opened`, NOW())) < 0
is a boolean expression (checking whether the COUNT is less than 0), which will always return 0 (false) since a COUNT must be at least 0. What you can do instead is SUM the results of the test (since MySQL treats booleans as 0 or 1 in a numeric context):
SELECT SUM(TIMESTAMPDIFF(MINUTE, `Opened`, NOW()) < 0) as PastDue FROM `Task`
Note that you can simplify this query to just compare Opened with NOW(), either in the SUM:
SELECT SUM(`Opened` > NOW()) AS PastDue
FROM `Task`
or using COUNT(*) with a WHERE clause:
SELECT COUNT(*) AS PastDue
FROM `Task`
WHERE `Opened` > NOW()
Note that based on the wording of your question, you probably want to change the condition from
`Opened` > NOW()
to
`Opened` < NOW()

Query - To display the Failure rate %

I have written this query to get my data, and all the data is fine.
I have one column which has either Pass Or Fail. I want to calculate the % of number of bookings that failed, and output it in a single value.
I will have to write another query to show that one number.
For example : The below data, I have 4 bookings , out which 2 failed. So 50% is the failure rate. I am omitting some columns , in the display, but can be seen in the query.
That's an aggregation over all records and simple math:
select count(case when decision = 'Fail' then 1 end) / count(*) * 100
from (<your query here>) results;
Explanation: COUNT(something) counts non null values. case when decision = 'Fail' then 1 end is 1 (i.e. not null) for failures and null otherwise (as null is the default for no match in CASE/WHEN &dash; you could as well write else null end explicitly).
Modify your original condition to the following. Notice that there is no need to wrap your query in a subquery.
CONCAT(FORMAT((100 * SUM(CASE WHEN trip_rating.rating <= 3 AND
(TIMESTAMPDIFF(MINUTE,booking.pick_up_time,booking_activity.activity_time) -
ROUND(booking_tracking_detail.google_adjusted_duration_driver_coming/60)) /
TIMESTAMPDIFF(MINUTE,booking.pick_up_time,booking_activity.activity_time)*100 >= 15
THEN 1
ELSE 0
END) / COUNT(*)), 2), '%') AS failureRate
This will also format your failure rate in the format 50.0%, with a percentage sign.

complex math routines in mysql

I have a table in Mysql that has field code with a value = 'A' that represents the type of sale of a part. The sale price is displayed as Price. There is a Quantity field that I need to multiply by the Price. The query sum(quantity*price) where code='A' gives me what I want. I also have a code = 'T' that represents the tax of the sum of the transactions. I can get that easy enough by sum(price) where code='T'. I need to subtract the value of the 'T' (tax) value from the sum(quantity*price).
I can do this by looping through two separate queryies but I would like to combine into one query.
You just want conditional aggregation:
select (sum(case when value = 'A' then quantity * price else 0 end) -
sum(case when value = 'T' then price else 0 end)
) as netprice

Query to retrieve values form DB on multiple criteria

I Need to retrieve values from database to plot them in graph. For that I need to get values on criteria basis. Data matching different criteria has to be returned as different rows/ column to my query
(i.e)
I have a table called TABLEA which has a column TIME. I need to get the value based on time critreia as a result, count of rows which are matching TIME>1 and TIME<10 as a result, TIME>11 and TIME <20 as a result and so on. Is it possible to get the values in a single query. I use Mysql with JDBC.
I should plot all the counts in a graph
Thanks in advance.
select sum(case when `time` between 2 and 9 then 1 else 0 end) as count_1,
sum(case when `time` between 12 and 19 then 1 else 0 end) as count_2
from your_table
This can be done with CASE statements, but they can get kind of verbose. You may just want to rely on Boolean (true/false) logic:
SELECT
SUM(TIME BETWEEN 1 AND 10) as `1 to 10`,
SUM(TIME BETWEEN 11 and 20) as `11 to 20`,
SUM(TIME BETWEEN 21 and 30) as `21 to 30`
FROM
TABLEA
The phrase TIME BETWEEN 1 AND 10) will either returnTRUEorFALSEfor each record.TRUEbeing equivalent to1andFALSEbeing equivalent to0`, we then only need sum the results and give our new field a name.
I also made the assumption that you wanted records where 1 <= TIME <= 10 instead of 1 < TIME < 10 which you stated since, as stated, it would drop values where the TIME was 1,10,20, etc. If that was your intended result, then you can just adjust the TIME BETWEEN 1 AND 10 to be TIME BETWEEN 2 AND 9 instead.