how to implement two aggregate functions on the same column mysql - mysql

SELECT max(sum(`orderquantity`)), `medicinename`
FROM `orerdetails`
WHERE `OID`=
(
SELECT `OrderID`
FROM `order`
where `VID` = 5 AND `OrerResponse` = 1
)
GROUP BY `medicinename`
i want to get the max of the result(sum of the order quantity) but it gives error any soultion to solve this

You don't need Max() here. Instead sort your recordset by that Sum('orderquantity') descending, and take the first record returned:
SELECT sum(`orderquantity`) as sumoforderqty, `medicinename`
FROM `orerdetails`
WHERE `OID`=
(
SELECT `OrderID`
FROM `order`
where `VID` = 5 AND `OrerResponse` = 1
)
GROUP BY `medicinename`
ORDER BY sumoforderqty DESC
LIMIT 1

Related

How do I select (N-1) rows from my MYSQL table where N is the number of rows fetched, while I am fetching DISTINCT elements?

I have a mysql query where I am trying to fetch DISTINCT elements:
SELECT DISTINCT(`Prev Date`), `Current Date`
FROM `electric_transaction`
WHERE `Flag`=1
AND `ipas_flag`=1
AND `SlNo` != (
SELECT MAX(`SlNo`) FROM `electric_transaction`
);
I want to fetch all the rows except the last one.
How do I proceed? Please guide me.
You could use an offset of 1 record in your LIMIT clause
SELECT DISTINCT `Prev Date`,`Current Date`
FROM `electric_transaction`
WHERE `Flag` = 1
AND `ipas_flag` = 1
ORDER BY SlNo DESC
LIMIT 1, 1000000

SQL Query about percentage selection

I am trying to write a query for a condition:
If >=80 percent (4 or more rows as 4/5*100=80%) of the top 5 recent rows(by Date Column), for a KEY have Value =A or =B, then change the flag from fail to pass for the entire KEY.
Here is the input and output sample:
I have highlighted recent rows with green colour in the sample.
Can someone help me in this?
I tried till finding the top 5 recent rows by the foll code:
select * from(
select *, row_number() over (partition by "KEY") as 'RN' FROM (
select * from tb1
order by date desc))
where "RN"<=5
Couldnt figure what to be done after this
Test this:
WITH
-- enumerate rows per key group
cte1 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY `key` ORDER BY `date` DESC) rn
FROM sourcetable ),
-- take 5 recent rows only, check there are at least 4 rows with A/B
cte2 AS ( SELECT `key`
FROM cte1
WHERE rn <= 5
GROUP BY `key`
HAVING ( SUM(`value` = 'A') >= 4
OR SUM(`value` = 'B') >= 4 )
-- AND SUM(rn = 5) )
-- update rows with found key values
UPDATE sourcetable
JOIN cte2 USING (`key`)
SET flag = 'PASS';
5.7 version – Ayn76
Convert CTEs to subqueries. Emulate ROW_NUMBER() using user-defined variable.

Set MYSQL WHERE condition from previous SELECT

I have the following MySQL query
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
This will grab me a random category where there is at least 5 questions in that category.
Now I want to grab all the rows for that category. So how can I do a second SELECT WHERE category is equal to the category returned from the previous query?
I tried the following but I believe the RAND() is causing it to crash/timeout.
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)
You can use the above query as a subquery. Something like this:
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)

Reorder results from another query

SELECT * FROM (
SELECT * FROM cars WHERE site = '5'
ORDER BY cost DESC LIMIT 0 , 10
)
ORDER BY time
How would I execute a sql query like this? So first it selects the 10 cars with the highest cost, THEN it reorders those 10 cars by what time they were added to the DB.
I tried to figure it out but I just cannot get a grip on the syntax :P
Just give an alias to the sub-query.
SELECT * FROM (
SELECT * FROM `cars` WHERE `site` = '5'
ORDER BY `cost` DESC LIMIT 0 , 10
)t
ORDER BY `time`;
This query will give you the desired results
SELECT * FROM ( SELECT * FROM cars WHERE site = 5
ORDER BY cost DESC LIMIT 0 , 10 ) as t ORDER BY time

Unknown Column in 'IN/ALL/ANY' subquery

I've got 2 tables: members and member_logs.
Members can belong to groups, which are in the members table. Given a date range and a group I'm trying to figure out how to get the 10 days with the highest number of successful logins. What I have so far is a massive nest of subquery terror.
SELECT count(member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and `reg_date` IN
(SELECT DISTINCT DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and (DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' and '2014-03-04'))
and `member_id` IN
(SELECT `member_id`
FROM members
WHERE `group_id` = 'XXXXXXX'
and `deleted` = 0)
ORDER BY `num_users` desc
LIMIT 0, 10
As far as I understand what is happening is that the WHERE clause is evaluating before the subqueries generate, and that I also should be using joins. If anyone can help me out or point me in the right direction that would be incredible.
EDIT: Limit was wrong, fixed it
The first subquery is totally unnecessary because you can filter by dates directly in the current table member_logs. I also prefer a JOIN for the second subquery. Then what you are missing is grouping by date (day).
A query like the following one (not tested) will do the job you want:
SELECT COUNT(ml.member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs ml
INNER JOIN members m ON ml.member_id = m.member_id
WHERE `login_success` = 1
AND DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' AND '2014-03-04'
AND `group_id` = 'XXXXXXX'
AND `deleted` = 0
GROUP BY `reg_date`
ORDER BY `num_users` desc
LIMIT 10
SELECT count(member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and `login_date` IN
(SELECT `login_date`
FROM member_logs
WHERE `login_success` = 1
and (DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' and '2014-03-04'))
and `member_id` IN
(SELECT `member_id`
FROM members
WHERE `group_id` = 'XXXXXXX'
and `deleted` = 0)
Group by `login_date`
ORDER BY `num_users` desc
LIMIT 0, 10
As a slightly more index friendly version of the previous answers;
To make the query index friendly, you shouldn't do per row calculations in the search conditions. This query removes the per row calculation of the string format date in the WHERE, so it should be faster if there are many rows to eliminate by date range;
SELECT COUNT(*) num_users, DATE(login_date) reg_date
FROM member_logs JOIN members ON member_logs.member_id = members.member_id
WHERE login_success = 1 AND group_id = 'XXX' AND deleted = 0
AND login_date >= '2012-02-25'
AND login_date < DATE_ADD('2014-03-04', INTERVAL 1 DAY)
GROUP BY DATE(login_date)
ORDER BY num_users DESC
LIMIT 10