MySQL: How to get values from Multiple Columns in one column - mysql

I have 2 tables with data. "keywords" and "Data".
key_id (P)
key_word
key_prod (I)
kay_country
key_is_wr
and
id (P)
dat_id (I)
dat_date
dat_is_weekly
For each keyword there are a few different rows linked in the data table - with different or the same dates in dat_date. I want to get all variations of dates that exist in this table only once so i can display them all in an array on my PHP code.
This is the query im currently using - it gets me a list of the same dates from the specific "key_app" value I need. But I only want to get an array of dates that exist for this specific key_id.
SELECT * FROM `keywords`
JOIN `data`
ON `keywords`.`key_id` = `data`.`dat_id`
WHERE `keywords`.`key_app`= 10
I Just haven't figure out yet how to:
1. Get only the dat_date section (I guess i need data.dat_date instead of the "*" in my query.
2. How to get only the different dates that exist for each key_prod.
I tried using all sorts of ORDER BY and MAX(id) and nothing seem to work well in terms of sytaxes
SELECT * FROM `keywords`
JOIN (
SELECT MAX(id) AS id
FROM `data`
GROUP BY `data`.`dat_date`
) `keywords`
ON `keywords`.`key_prod`=10
I have been digging it for a while but no right result
Example:
If I have under dat_date the vars
2016-06-21
2016-06-21
2016-06-21
2016-06-22
2016-06-22
2016-06-23
2016-06-23
for a specific key_app - I will get:
2016-06-21
2016-06-22
2016-06-23
as a query result

Try this.
select distinct data.dat_date
FROM `keywords`, `data`
ON `keywords`.`key_prod` = `data`.`dat_id`
WHERE `keywords`.`key_app`= 10
Your first query was how to display only the date. This can be done using select data.dat_date instead of select *.
Distinct will list only distinct dates not the same dates which was your query 2.

Related

How to treat missing id 's value as 0 and order by it?

When I use in keyword in sql, there may be some id is missing , but I want treat them like they exist and other columns are null or 0.
For example, suppose I have a table with two columns and some rows:
[id,value1]
1      1
2      4
3      3
5      5
I may write sql like this:
select * from table where id in (1,4,5) order by value1 limit 0,2 ;
When this sql is executed, the return result is [(1,1),(5,5)].
But what I want is [(4,0),(1,1)], because I want to treat the missing id 4 like it exists in the table.
So the question is : Is there some elegant way to achieve it using sql instead of select all rows and sort them in memory.
Use a left join:
select *
from (select 1 as id union all
select 4 union all
select 5
) i left join
table t
using (id)
order by t.value1
limit 0, 2 ;
Note that you are ordering by a value in the existing table, so this depends on the fact that NULL is ordered before other values.

How to sum daily resetting data using MySQL

I am attempting to plot data cumulatively from a MySQL table which logs a value, resetting to 0 every day. After selecting the values using select * from table where DateTime BETWEEN DateA AND DateB, the data looks like this: current data. I would like the output to look like this: preferred data, ignoring the daily resets.
As I am a novice in SQL I was unable to find a solution to this. I did, however, obtain the correct output in Matlab using a for loop:
output = data;
for k=1:(size(data, 1)-1)
% check if next value is smaller than current
if data(k+1)<data(k)
% add current value to all subsequent values
output = output + (1:size(data, 1)>k)'.*input(k);
end
end
I would like the final product to connect to a web page, so I am curious if it would be possible obtain a similar result using only SQL. While I have tried using SUM(), I have only been able to sum all values, but I need to add the last value each day to all subsequent values.
Using CTE and comparing dates, you can sum all values each date.
Let's say that table1 below is defined.
create table table1 (col_date date, col_value int);
insert into table1 values
('2020-07-15',1000),
('2020-07-15',2000),
('2020-07-16',1000),
('2020-07-16',3000),
('2020-07-16',4000),
('2020-07-17',1000),
('2020-07-18',2000),
('2020-07-19',1000),
('2020-07-19',1000),
('2020-07-19',2000),
('2020-07-19',3000),
('2020-07-20',4000),
('2020-07-20',5000),
('2020-07-21',6000)
;
In this case, the query looks like this:
with cte1 as (
select col_date, sum(col_value) as col_sum from table1
where col_date between '2020-07-16' and '2020-07-20'
group by col_date
)
select a.col_date, max(a.col_sum), sum(b.col_sum)
from cte1 a inner join cte1 b on a.col_date >= b.col_date
group by a.col_date;
The output is below:
col_date |max(a.col_sum) |sum(b.col_sum)
2020-07-16 |8000 | 8000
2020-07-17 |1000 | 9000
2020-07-18 |2000 |11000
2020-07-19 |7000 |18000
2020-07-20 |9000 |27000
The column of max() is just for reference.

Minus the value based on data using MySQL

I've the following data.
What I need like below
I need to minus order by 1 with 2.
Example : (1-2) and I've display the result in order by 3.
If the branch having order_by as 1 - display as it is.
Using MySQL, how can I get this result?
You can get this result with a UNION query. The first part selects all rows from your table, the second uses a self-join to find branches which have order_by values of both 1 and 2, and subtracts their due values to get the new due value:
SELECT *
FROM data
UNION ALL
SELECT 3, d1.branch, d1.due - d2.due
FROM data d1
JOIN data d2 ON d2.branch = d1.branch AND d2.order_by = 2
WHERE d1.order_by = 1
ORDER BY branch, order_by
Demo on dbfiddle

MySQL - Trying to get minimum value for each day

Got a table that holds dates and values, looks like this:
...Date........Value
2016-10-01 2.3
2016-10-01 1.6
2016-10-01 7.0
2016-10-02 2.4
2016-10-02 1.9
2016-10-02 7.3
etc, so multiple dates with multiple values for each date.
I can't figure out how to write the SQL to get to return a single row with the minimum value for each day.
Tried this but get error:Error in query (1054): Unknown column 'm.seldate' in 'on clause'
SELECT DISTINCT seldate
FROM mytable s
LEFT
JOIN
( SELECT MIN(myval) minval
FROM mytable
GROUP
BY seldate
) m
ON s.seldate = m.seldate
The following will return the minimum myvalue and the corresponding 'description' column (which I omitted in the original post) for each unique value of seldate within the table:
SELECT seldate, description, myvalue
FROM selections s1
WHERE myvalue=(SELECT min(s2.myvalue)
FROM selections s2
WHERE s1.seldate = s2.seldate);
Try:
select seldate, min(myval) as minval
from mytable
group by seldate

Retrieve maximum value from a table containing duplicate values according to a condition

I have a table tbl_usertests from which i want to retrieve the user who have maximum testscore for each test.
Note: User here means usertestid which is unique.
Its colums are:
pk_usertestid attemptdate uploaddate fk_tbl_tests_testid fk_tbl_users_userid testscore totalquestionsnotattempted totalquestionscorrect totalquestionsincorrect totalquestions timetaken iscurrent
data :
1;NULL;"2010-06-24 22:48:07";"11";"3";"1";"53";"1";"21";"75";"92";"1"
2;NULL;"2010-06-25 01:21:37";"11";"4";"13";"0";"13";"62";"75";"801";"1"
3;NULL;"2010-06-25 01:21:50";"10";"4";"17";"5";"17";"53";"75";"640";"1"
4;NULL;"2010-06-25 01:24:23";"11";"4";"13";"0";"13";"62";"75";"801";"1"
5;NULL;"2010-06-25 01:24:47";"10";"4";"17";"5";"17";"53";"75";"640";"1"
6;NULL;"2010-06-25 01:36:04";"11";"5";"13";"0";"13";"62";"75";"801";"1"
7;NULL;"2010-06-25 01:47:26";"7";"5";"10";"1";"10";"49";"60";"302";"1"
My Query is :
SELECT max(`testscore`) , `fk_tbl_tests_testid` , `fk_tbl_users_userid` , `pk_usertestid`
FROM `tbl_usertests`
GROUP BY `fk_tbl_tests_testid`
This query output:
max(`testscore`) fk_tbl_tests_testid fk_tbl_users_userid pk_usertestid
10 7 5 7
17 10 4 3
13 11 3 1
But the problem is that if there are two users who have same score, it displays only one user because i have used group by clause.
For. e.g. testid =10 i have two records(pk_usertestid 3 and 5) but it displays 3 only.
I want the user whose upload date is less than the other user(in case of two users having same testscore). It should display for usertestid=3 since 3 upload date is less than 5.
Right now its displaying 3 but it is due to group by clause.
I am unable to construct the query.
Please help me on this
Thanks
Try this:
SELECT t.`fk_tbl_tests_testid` , t.`fk_tbl_users_userid` , t.`pk_usertestid`, maxscores.maxscore
FROM `tbl_usertests` t
JOIN (SELECT `fk_tbl_tests_testid`,max(`testscore`) as maxscore
FROM `tbl_usertests`
GROUP BY `fk_tbl_tests_testid`) maxscores ON t.`fk_tbl_tests_testid` = maxscores.`fk_tbl_tests_testid`
the logic behind is to separate the whole thing into two parts: get the maximum (or any other aggregate) values for each group (this is the subquery part), then for each element, join the corresponding aggregate. (JOIN it back to the riginal table)