Mysql Join Two Queries - php

I have two queries:
SELECT opr, COUNT(*) FROM table WHERE field = 'YES' GROUP BY opr
SELECT opr, MAX(category) FROM table WHERE field = 'NO' GROUP BY opr
So basically in the first query I am getting the number of transactions a user makes.
In the second query I am getting a category that all of those transactions fall under. I don't want to get all categories for each transaction they made, just the Max of the category field so that I have one entry per operator.
Until now, I have been catching both result sets in separate arrays and the looping through both arrays to get the complete opr->picks->category.
This doesn't always work it sometimes associates the wrong category to the wrong operator.
Is there a way to combine these two queries into one, so that I get the operator and picks, then the MAX(category)? The issue is that the conditions for each query are different on the field column.

SELECT opr,
COUNT(CASE WHEN field = 'YES' THEN 1 END) AS number_of_transactions,
MAX(CASE WHEN field = 'NO' THEN category END) AS category
FROM table
GROUP BY opr ;

The above logic can be attained in one query by using CASE
SELECT opr, COUNT(CASE WHEN `field` = 'YES' THEN opr END) as `count`,
MAX(CASE WHEN `field` = 'NO' THEN category END) as `max`
FROM table GROUP BY opr

Just add it in:
SELECT opr,count(*), MAX(category) FROM table WHERE field = 'YES' GROUP BY opr
You might also be able to drop it from 2 queries to 1 with this:
SELECT opr,count(*), MAX(category), field FROM table GROUP BY opr, field

even faster on the processor, use a sum bool:
select
opr,
sum(field='yes') as transactions,
max(if(field='no',category, null)) as category
from table
group by opr

Related

Group data based on range in mysql

I have table products in my database. price column has various repeating values. I want to fetch count of products based on range 10-50, 51-100 and so on.
One way I could identify was to execute multiple queries on the database with different where clauses.
I was wondering if it could be done in one query itself.
what I tried was
$q = "SELECT count(*) FROM products WHERE price>10 AND price<50"
$q1 = "SELECT count(*) FROM products WHERE price>50 AND price<100"
Now this gives me the count of individual ranges, but I have to manually write queries for all the ranges.
select product_name,
count(case when price between 10 and 50 then 1 else null end) as `10-50 count`,
count(case when price between 51 and 100 then 1 else null end) as `51-100 count`
from products
group by product_name

IF in WHERE mysql query

I have this table.
In MySql I want select this user IF key column do not have custom row AND IF key column have custom row -> value column = yes.
This is my query, but it do not work:
where `value` = if(`key` = 'custom', 'yes', '')
you can use the following statement which select any row has key not equal 'custom' or equal 'custom' and value equal 'yes'
Select * from tableName where `key`<> 'custom' or (`key` = 'custom' and `value` = 'yes')
The specification for the query isn't clear, in that it's open to several different interpretations.
I'm thinking the question is about how to return a particular result, not really about using an IF() function in the WHERE clause. (None of the SQL below uses an IF() function in a WHERE clause.)
Here's one possible interpretation of the specification:
By "select this user", we'll take that to mean we want to return a single copy of the user_id column.
By "IF key column do not have custom row", we'll take that to mean that there does not exist such a row for this user_id, then return this user_id. If such a row does exist, then do not return the user.
By "AND IF key column have custom row -> value column = yes.", we'll take that to mean to return this user_id if there is a row for this user_id that matches the condition.
Based on that interpretation, here's an approach to satisfying the specification using conditional aggregation:
SELECT t.user_id
FROM this_table t
GROUP
BY t.user_id
HAVING SUM(1) = SUM(IF(t.key='custom',IF(t.value='yes',1,0),1))
The expression inside the SUM() aggregate gets evaluated for each row. That expression is designed to return either a 1 or a 0, depending on whether the row matches the specified conditions. The SUM() aggregate totals up those 1s and 0s. And then we compare the result to the total number of rows. That tells us if a "matching" row exists or not.
The counts are by user_id, as identified in the GROUP BY clause.
The MySQL IF() function can be replace with a more portable ANSI CASE expression
HAVING SUM(1) = SUM(CASE
WHEN t.key = 'custom'
THEN CASE
WHEN t.value = 'yes'
THEN 1
ELSE 0
END
ELSE 1
END
)
If the intent is to return all of the detail rows for a user, but excluding all user_id that meet the specification, we could use an EXISTS correlated subquery:
SELECT t.user_id
, t.key
, t.value
FROM this_table t
WHERE NOT EXISTS ( SELECT 1
FROM this_table r
WHERE r.user_id = t.user_id
AND r.key = 'custom'
)
OR EXISTS ( SELECT 1
FROM this_table q
WHERE q.user_id = t.user_id
AND q.key = 'custom'
AND q.value = 'yes'
)

How to perform multiple table operations in mysql?

I just want to perform multiple table operations in single query. The query is:
select name,sno , id as ids ,(select sum(amount) from client_credits
where user_id = ids) As total from clients where sno = '4' and total > '0'
This query is not working when I am trying use ** total > 0 **. Is there any other possibility ways? Please help me.
total is an alias. Aliases are not resolved when the WHERE clause is reached.
Try: where sno = 4 having total > 0
Alternatively, and more efficiently:
SELECT `c`.`name`, `c`.`sno`, `c`.`id`, SUM(`ccr`.`amount`) AS `total`
FROM `clients` AS `c`
JOIN `client_credits` AS `ccr` ON `c`.`id`=`ccr`.`user_id`
WHERE `c`.`sno` = 4
GROUP BY `c`.`id`
Notice how the total > 0 part is gone? That's because if there are no rows to join, then nothing will be joined and the rows are removed from the result ;)

Getting Count with different conditions in Select Query

The scenario is I have a column named "States" in a table, States can be 0,1,2,3 or 4. What I want to do is get a count of each state using WHERE State = in a single query.
The main purpose is I want to show the count of records (identified by their state). Like this, 20 records have State 0 etc.
Is this possible? If yes, then how can I achieve this?
Edit: I know about Count. Here's what I have tried:
SELECT State, Date_Created, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=1) as State_One, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=2) as State_Two, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=0) as State_Zero, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=4) as State_Four FROM [ECOS].[eco].[tb_projects_details] WHERE Date_Created < dateadd(week,-3,getdate());
If I understand it correctly, you want to group and count:
SELECT mt.States, COUNT(*) total
FROM my_table mt
GROUP BY mt.States
To generate a list of values and their counts you can do this:
SELECT State, COUNT(*) AS C
FROM mytable
GROUP BY State
To generate one row that contains value counts as columns you can do this:
SELECT
COUNT(CASE State WHEN 0 THEN 1 ELSE NULL END) AS State_0_Count,
COUNT(CASE State WHEN 1 THEN 1 ELSE NULL END) AS State_1_Count,
COUNT(CASE State WHEN 2 THEN 1 ELSE NULL END) AS State_2_Count,
COUNT(CASE State WHEN 3 THEN 1 ELSE NULL END) AS State_3_Count,
COUNT(CASE State WHEN 4 THEN 1 ELSE NULL END) AS State_4_Count
FROM [...]
WHERE [...]
It will be very easy if you use group by clause after where condition. Then you will get the number of each state very easily.
SELECT state, count(*)
FROM table_name
GROUP BY state
Next time read a sql for beginers book first.
Select state, count(*)
from table
group by state

Select ticket ID if, customer with closed status exists

I have customers on my DB with too many tickets, and these tickets have too many statuses. I want a query that could pull the cutomer's ticket number, only if the ticket with status!='Closed'. Otherwise it should return null.
Your fast response is highly appreciated.
Edit: Here is my query:
SELECT CASE WHEN custom_field_3 != 'Closed' THEN item_id ELSE NULL END AS ticketID
FROM aims_items
WHERE custom_field_22 =221226
It works now, and here is my solution:
SELECT
CASE WHEN
(
SELECT COUNT(*)
FROM aims_items
WHERE custom_field_3 != 'Closed'
AND custom_field_22 =221226
)>0
THEN
item_id
ELSE
NULL
END
AS ticketID
FROM aims_items
WHERE
custom_field_3 != 'Closed'
AND
custom_field_22 =221226
Thanks for your cooperation.
Try this query:
SELECT IF(custom_field_3!='Closed',item_id,'') as ticketID FROM `aims_items`
Remember, i have not written the exact fields that you have in your table. This is just example to show you. Refer to below link for detailed informationhttp://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
Without table structure it is not possible to evaluate what the issue is. From your description a simple query like
SELECT item_id from aim_items WHERE custom_field_3 != 'Closed' AND custom_field_22 = 221226
Would suffice. You can then count the number of rows returned to determine result.
If, however, you require null to be returned as a result, try the following :
SELECT (SELECT item_id from aim_items WHERE custom_field_3 != 'Closed' AND custom_field_22 = 221226) AS ticketID
The above encapsulates the basic select into a subquery, to provide a null result.

Categories