Mysql Query Select data on multiple rows - php

I'm now doing four separate queries to select the information i need.
f.e.
SELECT value FROM data where sensor=123 AND value_id=a
SELECT value FROM data where sensor=123 AND value_id=b
SELECT value FROM data where sensor=123 AND value_id=c
SELECT value FROM data where sensor=123 AND value_id=d
Now i'm experementing with some code. I don't know if on my right way but is such a thing possible:
SELECT value180,value181,value182,value183
FROM (
SELECT
MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) as value180,
MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) as value181,
MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) as value182,
MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) as value183
FROM data
WHERE sensor_id = 1605850
AND value_id IN ("1.8.0","1.8.1","1.8.2","1.8.3")
) a
It would be nice to have a single query...thx for helping in advance!
note: i have to use max value of each day per sensor per value. In the above first example this max function was just left out for simplification.
This is the table how it looks like:
as you can see there are hourly taken values for each value_id.
What i need:
I need the highest value of yesterday for defined value_id's.
f.e. 1.8.0 = 3726.12, 1.8.1 = 663.69, ...
With my combined query i'm getting wrong values but the format how i want to get the values is correct:

try
SELECT value FROM data
WHERE sensor=123 AND value_id IN ('a', 'b', 'c' , 'd');
or
SELECT value FROM data
WHERE sensor=123 AND value_id IN (SELECT DISTINCT value_id FROM data);

After a short walk through the nature to take a pause i was able to solve my problem.
SELECT
(SELECT MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) FROM data WHERE sensor_id = 1605850 AND value_id = "1.8.0") as value180,
(SELECT MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) FROM data WHERE sensor_id = 1605850 AND value_id = "1.8.1") as value181,
(SELECT MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) FROM data WHERE sensor_id = 1605850 AND value_id = "1.8.2") as value182,
(SELECT MAX(CASE WHEN DATE(time) = subdate(CURDATE(), 1) THEN value ELSE 0 END) FROM data WHERE sensor_id = 1605850 AND value_id = "1.8.3") as value183
that was all.

Related

Laravel query with case and different table subtraction

Check my laravel query it's not working... but mysql query works fine.
$data1 = DB::table(DB::raw('(select sum(case when type="debit" then amount else -amount end) from report) - (select sum(amount) from total) as balance' ))
For mysql query please refer sqlfiddle : http://sqlfiddle.com/#!9/2d0343/9
Thanks a lot...
Assuming the type can't be null and has either credit/debit value, you can use aggregation with CASE:
select
sum(case when type='credit' then amount else -amount end)
from report;
Demo
In case the column is nullable or other values are allowed in the column type, you can modify the above like:
select
sum(case when type='credit' then amount
else -amount end)
from report
where type in ('credit', 'debit');
EDIT:
For the latest edit, calculate the difference from one table and subtract the aggregate from other:
select (
select sum(case when type='credit' then amount else -amount end)
from report
) - (select sum(amount) from total);
select sum(case type when 'credit' then amount when 'debit' then -amount else 0 end)
from report
select (sum(case when type='credit' then amount else -amount end)) - (select sum(amount) from total)
from report

Query a specific value with Pivot Table mySQL

I have searched all over the internet and I have had no luck in finding the answer to my question. I hope this has not specifically been posted yet, but if you can point to where i can find the answer I would appreciate it.
I was able to take the following table data below:
id lead_id form_id field_number value
1 1 1 1 Hosker
2 1 1 7 b**********#yahoo.com
3 1 1 6 Hyundai Tournament of Champions
4 1 1 3 Adam Scott
5 1 1 4 Harris English
6 1 1 5 2014-01-02 23:59:47
7 1 1 8 5b409692-e9ed-486e-8d77-7d734f1e023d
And get the result below using this query string:
SELECT id, lead_id, form_id,
MAX(case when field_number = 1 then value end) username,
MAX(case when field_number = 7 then value end) email,
MAX(case when field_number = 6 then value end) tournament_name,
MAX(case when field_number = 3 then value end) primary_golfer,
MAX(case when field_number = 4 then value end) backup_golfer,
MAX(case when field_number = 5 then value end) date,
MAX(case when field_number = 8 then value end) tournament_id
FROM `wp_rg_lead_detail` GROUP BY lead_id
id lead_id form_id field_number value value value value value value value
1 1 1 1 Hosker b**********#yahoo.com Hyundai Tournament of Champions Adam Scott Harris English 2014-01-02 23:59:47 5b409692-e9ed-486e-8d77-7d734f1e023d
I just want that query string to only pull the related data when the value of the tournament_id column equals a specific value. How would I do that?
try this query. I think you can use the HAVING clause.
SELECT id, lead_id, form_id,
MAX(case when field_number = 1 then value end) username,
MAX(case when field_number = 7 then value end) email,
MAX(case when field_number = 6 then value end) tournament_name,
MAX(case when field_number = 3 then value end) primary_golfer,
MAX(case when field_number = 4 then value end) backup_golfer,
MAX(case when field_number = 5 then value end) date,
MAX(case when field_number = 8 then value end) tournament_id
FROM `wp_rg_lead_detail` GROUP BY lead_id
HAVING tournament_id = '5b409692-e9ed-486e-8d77-7d734f1e023d'
sqlFiddle In the sqlFiddle I have sample data for 2 different tournament_id and the HAVING clause is applied so that only values for that tournament_id would be returned, you can try removing the HAVING and see that it returns 2 rows.
Your Group By is not standard since you're selecting id and form_id as well. I suggest you drop the the id or use MIN(id) or MAX(id) and GROUP BY lead_id,form_id
If I understand what you're asking, try:
SELECT * FROM TABLE_NAME
WHERE tournament_id = specific_value;

Closing percent MATH in MYSQL

I want to do math in a query, and was wondering if its better to do it in PHP or MYSQL.
Also, if I choose MYSQL can anyone help me with the query.
So far I have
SELECT COUNT(*) as total, booker, appdate,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot
FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker
I want one more stat from this query.
I want to do book / (book+tot)
But obviously only if book!=0 or tot!=0, since obviously I don't want to divide anything by zero.
Is there a way to do this in a MYSQL query??
I want my output to be.....
book | 14
tot | 25
hold | 35%
Id also like to ORDER BY the hold percent from highest to lowest. Is this possible????
You can achieve what you ask for using a subquery, like this:
SELECT *, IF(book + tot, 100*book/(book + tot), NULL) AS hold
FROM (
SELECT COUNT(*) as total, booker, appdate,
SUM(status='DNS') book, SUM(status!='DNS') tot
FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker
) AS subquery
ORDER BY hold DESC
Note that in several places I'm using the fact that MySQL uses numbers for logical values. So you can sum up conditions without CASE, and you can write a formula for IF without <> 0 check.
Naive method:
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
IF( ( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) ) = 0,
0,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) /
( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) )
) AS hold
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
ORDER BY hold;
Or in order not to repeat your aliases, use a subquery:
SELECT *, IF (book + tot = 0, 0, book / (book + tot) * 100)
FROM (
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;
Or, more cleverly :) (book + tot = total)
SELECT *, IF (total = 0, 0, book / total * 100)
FROM (
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;
And, just for fun, the hackishly compactest form:
SELECT *, COALESCE(book / total * 100, 0) AS hold -- a division by 0 returns NULL
FROM (
SELECT
COUNT(*) total,
SUM(status='DNS') book, -- boolean "true" is internally integer "1"
SUM(status!='DNS') tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;

select/sum of a column with different conditions in 1 query

$pos = select * from score_history where content_id = 6 && val = 1
$neg = select * from score_history where content_id = 6 && val = -1
i want to get the pos and neg scores in one query
but i dont want to use join
so perhaps some sort of IF/case statement ?
i've this but as you can guess it fails
SELECT count(*) as total ,
CASE
WHEN `val` = 1 THEN count(*) as `pos`
WHEN `val` = -1 THEN count(*) as `neg`
END
FROM score_history WHERE `content_id` = '46083' ";
is there any way to do this without using join or sub query ?
You can make use of the flexibility of MySQL to handle booleans and integers:
SELECT count(*) total, sum(val = 1) pos, sum(val = -1) neg
FROM score_history
WHERE content_id = '46083';
Whenever the condition is true it is a 1. Otherwise a 0. No CASE needed nor GROUP BY.
Close! A CASE statement doesn't return multiple columns, so you'll need 2 CASE statements and to wrap them in a SUM():
SELECT count(*) as total
,SUM(CASE WHEN `val` = 1 THEN 1 ELSE 0 END) as `pos`
,SUM(CASE WHEN `val` = -1 THEN 1 ELSE 0 END) as `neg`
FROM score_history WHERE `content_id` = '46083' ;
SELECT
SUM(CASE WHEN `val` = 1 THEN 1 ELSE O END) AS pos_count,
SUM(CASE WHEN `val` = -1 THEN 1 ELSE O END) AS neg_count
FROM score_history WHERE `content_id` = '46083';
Try this. Sorry I can't test, no database on this laptop.
select
count(*) as total,
sum(case val when 1 then 1 else 0 end) as pos,
sum(case val when -1 then 1 else 0 end) as neg
from score_history
where content_id = 6
Not sure if this is the best answer (and you would certainly want an index on your val column assuming there are many rows in the table) but this should certainly work - also assuming you only have 1 and -1 as values:
SELECT count(*), val from score_history where content_id = 6 group by val;
You were close; try the SUM function:
SELECT count(*) as total
, sum(CASE WHEN `val` = 1 THEN 1 ELSE 0 END) as `pos`
, sum(CASE WHEN `val` = -1 THEN 1 ELSE 0 END) as `neg`
FROM score_history
WHERE `content_id` = '46083';
select count(*)
from score_history
where content_id = 6 &&
(val = -1 or val=1)
group by val
I think this statement should work but I have tested on DBMS.
SELECT count(*) as total ,
count(case when val = 1 then 1 else null end) as pos,
count(case when val = -1 then 1 else null end) as neg
FROM score_history
WHERE `content_id` = '46083';
See SQLFIDDLE
Okay, a lot of these answers are close, but whenever you use an aggregate function you should use a group by.
SELECT count(*) as total
, (CASE WHEN `val` >= 0 THEN 'positive' ELSE 'negative' END) as interpreted_value
END
FROM score_history
WHERE `content_id` = '46083'
GROUP BY (CASE WHEN `val` >= 0 THEN 'positive' ELSE 'negative' END);
If you want to read up on how to use group by and aggregate functions here: https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

Mysql addition and add them as new column

I want to fetch 2 coulmns count and do their total as a new column.
How can I do this?
i wrote this query, but this is returning wrong total.
SELECT count(case when `status`='1' then 1 else 0 end) AS HOT,
count(case when `status`='5' then 1 end)
AS Special_Case,count(case when 1=1 then 1 end) AS TOTAL
FROM `tbl_customer_conversation` group by
date(`dt_added`),user_id
COUNT will only give the times a record is matched, which in your query will always return 1. Because the values can either be 1 or 0. So count(1) is also 1 and count(0) is also 1.
AS, you want the total number of HOT cases and SPECIAL_CASE you have to use SUM.
SELECT
SUM(case when `status`='1' then 1 else 0 end) AS HOT,
SUM(case when `status`='5' then 1 end) AS Special_Case,
SUM(case when `status` = '1' or `status` = '5' then 1 end) AS TOTAL
FROM `tbl_customer_conversation`
group by date(`dt_added`),user_id

Categories