mysql query: data from last three months - mysql

I am doing a query that is retrieving some data from the past three months, the only problem is that some of the data I am getting doesn't have entries in certain months. Since they have no entries I'd like to mark that month as 0.
My first thought was the create a temp table and left join the labels that I need out of it. But that hasnt been successful.
Can anyone think of a way to do this?
Example: I want the last 3 months of Data and I am getting
'Component', 1325.1988
'Component', 554.1652
'Component', 103.6668
'Development', 203.4163
'Development', 59.4500
'Development', 19.7498
'Flash Assets', 285.5334
'Flash Assets', 302.1501
'Flash Assets', 61.1836
'Release', 0.6000
'Release', 2.3666
'Repackage', 416.2169
'Repackage', 5195.0839
'Repackage', 4.5667
'Source Diff', 1.9000
Where 'Source Diff' and 'Release' don't have 3 entries.
Thanks
Query
SELECT bt.name as 'Labels',
SUM(TIME_TO_SEC(TIMEDIFF(bs.eventtime, b.submittime))/60) AS 'Data'
FROM builds b JOIN buildstatuses bs ON bs.buildid = b.id JOIN buildtypes bt
ON bt.id = b.buildtype WHERE DATE(b.submittime)
BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 MONTH) AND DATE(CURDATE())
AND bs.status LIKE 'Started HANDLER' AND b.buildtype != 11
AND b.buildtype != 5 AND b.buildtype != 4 GROUP BY bt.name, MONTH(b.submittime);
Table Schema
builds
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| submittime | datetime | NO | | NULL | |
| buildstatus | int(11) | NO | | NULL | |
| buildtype | varchar(20) | NO | | NULL | |
| buildid | int(11) | NO | | NULL | |
+---------------+------------------+------+-----+---------+----------------+
buildtypes
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(200 | NO | | NULL | |
+---------------+------------------+------+-----+---------+----------------+
buildstatuses
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| buildid | int(11) | NO | MUL | NULL | |
| eventtime | datetime | NO | | NULL | |
+------------+----------+------+-----+---------+----------------+

Here are some similar questions:
How to get values for every day in a month
Group by day and still show days without rows?
MySQL: filling empty fields with zeroes when using GROUP BY

Related

Default value in sql laravel table

I not sure if this is related to Laravel or not but I created the table with Laravel. I've got a table called programmers
DESC programmers;
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| framework_id | int(10) unsigned | NO | | NULL | |
| test | tinyint(1) | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
as you can see there's a column called test that's not nullable and has a default value of null. When I to run the following command from the database I expected an error
INSERT INTO programmers (name, age, framework_id) VALUES ('Melly2', 19, 2)
it actually worked fine and here's the data
SELECT * FROM programmers;
+----+--------+-----+---------------------+---------------------+--------------+------+
| id | name | age | created_at | updated_at | framework_id | test |
+----+--------+-----+---------------------+---------------------+--------------+------+
| 1 | melly | 20 | 2022-05-03 16:36:12 | 2022-05-03 16:36:12 | 1 | 0 |
| 2 | Melly2 | 19 | NULL | NULL | 2 | 0 |
+----+--------+-----+---------------------+---------------------+--------------+------+
the test column actually defaulted to 0 not null, and if I were to run the following command it tells me I can't have null as a value as expected
INSERT INTO programmers (name, age, framework_id, test) VALUES ('Melly2', 19, 3, null);
ERROR 1048 (23000): Column 'test' cannot be null
question: can someone briefly explain why test column didn't default to null?
In this scenario, the default value is null only if you don't provide a value. But when you provide some value, it should be compatible with the datatype you set for the column.
Here the datatype is tinyint. So, you should provide the values from true/false which infact will be converted into 1/0; else you should insert integers example:0,1,2,... etc.

postgresql returns null but mysql doesn't

I have an application for which I am migrating from Mysql to Psql.
I have three tables t1,t2,t3 described below . Table t3 will always have a entry as long as user is available , but both table t1 and t2 may or may not have entry if the user doesn't create DB in his account.
While executing q1 in mysql , I get result set containing values fetched from table t3, even if t1 and t2 doesn't have entry , but it returns null in psql . So I've written two queries pq1 and pq2 to be equivalent to q1 . What is the reason that mysql doesn't return null values but psql does? Is there any better solution to this than breaking down into two queries for psql ?
mysql query (q1)
select
COALESCE(sum(dr.NO_OF_QT),0),
ur.NO_OF_USERS, ur.NO_OF_DB, 0,
COALESCE(sum(dr.NO_OF_SM),0),
COALESCE(sum(dr.NO_OF_RPTS),0)
from DataBaseProps dr
left join DataBaseDetails db on dr.DB_ID=db.ID and db.STATUS=1
left join UserProps ur on db.OWNER_UID=ur.USER_UID
where ur.USER_UID='USER_UID'
Psql-query_1 (pq1)
select
COALESCE(sum(dr.NO_OF_QT),0),
0,0, 0,
COALESCE(sum(dr.NO_OF_SM),0),
COALESCE(sum(dr.NO_OF_RPTS),0)
from DataBaseProps dr
left join DataBaseDetails db on dr.DB_ID=db.ID and db.STATUS=1
left join UserProps ur on db.OWNER_UID=ur.USER_UID
where ur.USER_UID='USER_UID'
psql-query_2(pq2)
select NO_OF_USERS,NO_OF_DB from UserProps
where USER_UID='USER_UID'
Table 1 DataBaseProps (t1)
desc DataBaseProps >
+-----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------+------+-----+---------+-------+
| DB_ID | bigint(19) | NO | PRI | NULL | |
| NO_OF_RPTS | int(10) | YES | | 0 | |
| NO_OF_QT | int(10) | YES | | 0 | |
| NO_OF_SM | int(10) | YES | | 0 | |
+-----------------+------------+------+-----+---------+-------+
Table 2 - DataBaseDetails(t2)
desc DataBaseDetails>
+-------------------+--------------+------+-----+-----------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+-----------------+-------+
| ID | bigint(19) | NO | PRI | NULL | |
| NAME | varchar(50) | NO | | NULL | |
| STATUS | int(10) | NO | | 1 | |
| OWNER_UID | bigint(19) | NO | | NULL | |
+-------------------+--------------+------+-----+-----------------+-------+
Table 3 UserProps(t3)
desc UserProps>
+-----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------+------+-----+---------+-------+
| USER_UID | bigint(19) | NO | PRI | NULL | |
| NO_OF_DB | int(10) | YES | | 0 | |
| NO_OF_USERS | int(10) | YES | | 0 | |
+-----------------+------------+------+-----+---------+-------+

Slow query and use of indexes in MySQL

I have the following query:
SELECT final_query.chr
, final_query.start
, final_query.end
, co.chr
, co.start
, co.end
, final_query.count
FROM (SELECT ed.chr
, ed.start
, ed.end
, case when e.bin1=ed.bin then e.bin2 else e.bin1 end AS target
, count
FROM (SELECT * FROM coordinates
WHERE chr="chr1" AND (start between 3960000 AND 4000000 OR end between 3960000 AND 4000000)
) ed
JOIN counts e ON (e.bin1 = ed.bin OR e.bin2=ed.bin)
SORT BY count LIMIT 1,20)
AS final_query
JOIN coordinates co ON final_query.target=co.bin;
and the output of EXPLAINED is:
+------+-------------+-------------+--------+---------------+---------+---------+-------+----------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------+--------+---------------+---------+---------+-------+----------+------------------------------------+
| 1 | SIMPLE | e | ALL | bin1,bin2 | NULL | NULL | NULL | 30763816 | Using filesort |
| 1 | SIMPLE | coordinates | ref | PRIMARY,chr | chr | 22 | const | 4929 | Using index condition; Using where |
| 1 | SIMPLE | co | eq_ref | PRIMARY | PRIMARY | 22 | func | 1 | Using where |
+------+-------------+-------------+--------+---------------+---------+---------+-------+----------+------------------------------------+
What I am doing is to perform the following query of table coordinates, which has field chr indexed. So, in the subquery shown below, I filter those rows that match my conditions.
... (SELECT * FROM coordinates
WHERE chr="chr1" AND (start between 3960000 AND 4000000 OR end between 3960000 AND 4000000)
) ...
This table outputs field bin, also indexed. This field bin links with bin1 and bin2 both from table counts and indexed as well. So, here, what I want is to get all those rows in table counts having coordinates.bin in fields bin1 and bin2. Why in this step no index is used?
Besides of it, I would like to add an ORDER BY in my query, just before the LIMIT statement. But it slows too much my query. I don't know why, because it have to sort a maximum of 4000 rows...
How can I optimize my query?
My tables, from the DESCRIBE statement:
Table counts
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| bin1 | varchar(20) | NO | MUL | NULL | |
| bin2 | varchar(20) | NO | MUL | NULL | |
| count | float(6,2) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
Table coordinates
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| bin | varchar(20) | NO | PRI | NULL | |
| chr | varchar(20) | NO | MUL | NULL | |
| start | int(11) | NO | | NULL | |
| end | int(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+

WeatherStation : Mysql query join & average on tables

I have two tables like that :
temperature :
+---------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| date | datetime | YES | UNI | NULL | |
| capteur | int(11) | YES | | NULL | |
| valeur | float(3,1) | YES | | NULL | |
+---------+---------------------+------+-----+---------+----------------+
humidite :
+---------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| date | datetime | YES | UNI | NULL | |
| capteur | int(11) | YES | | NULL | |
| valeur | int(11) | YES | | NULL | |
+---------+---------------------+------+-----+---------+----------------+
I have values recorded on those two tables, not at the same time (Around 1 record each minute).
If I enter this command, I get average values for each hour for the last 24h (so, 24 rows) :
$sql->query('SELECT hour(date) AS humhour,ROUND(AVG(valeur),1) AS avghum FROM humidite WHERE date >= (now() - INTERVAL 1 DAY) GROUP BY HOUR(date) ORDER BY DATE;');
Now, I try to get the same thing, but with both tables. Ie, for all value between 0h00 and 0h59, I want average of all temperature and average of all humidity values.
I try this command :
$result = $sql->query('
SELECT hour(temperature.date) AS hourtemp,
hour(humidite.date) AS hourhum,
ROUND(AVG(temperature.valeur),1) AS avgtemp,
ROUND(AVG(humidite.valeur),1) AS avghum
FROM temperature
INNER JOIN humidite on hour(temperature.date) = hour(humidite.date)
WHERE temperature.date >= (now() - INTERVAL 1 DAY)
GROUP BY HOUR(date)
ORDER BY DATE;');
An idea ?
Thank you !

Updating table using group by sum

I have two tables. One is a detail table that contains quantity info and has the following structure
> mysql> DESCRIBE summary_finished;
+---------------+---------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+---------------+---------------+------+-----+---------+
| db_id | int(11) | NO | PRI | NULL |
| finished_id | text | NO | | NULL |
| finished_name | text | NO | | NULL |
| qoh | int(11) | NO | | NULL |
| value | decimal(10,2) | NO | | NULL |
+---------------+---------------+------+-----+---------+
mysql> DESCRIBE detail_finished;
+-------------+---------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+-------------+---------------+------+-----+---------+
| db_id | int(11) | NO | PRI | NULL |
| finished_id | text | NO | | NULL |
| quantity | int(11) | NO | | NULL |
| value | decimal(10,2) | NO | | NULL |
+-------------+---------------+------+-----+---------+
In detail_finished there are many items that have the same finished_id. What I am trying to accomplish is combining items that have the same finished_id and update that sum to the summary_finished.qoh field. This is what I have so far:
function set_qty($total, $finished_id){
global $connection;
$query="UPDATE summary_finished
SET qoh={$total}
WHERE finished_id='$finished_id'";
$quantity=mysql_query($query, $connection);
confirm_query($quantity);
}
$query="SELECT finished_id, SUM(quantity) FROM detail_finished GROUP BY finished_id";
$result=mysql_query($query, $connection) or die(mysql_error());
while($row = mysql_fetch_array($result)){
set_qty($row['SUM(quantity)'], $row['finished_id']);
}
I know the sums are calculating correctly as I can echo them straight out, however I cannot get my table to update. Forgive me for the sloppy code I am very new with mysql entirely. Thank you in advance for the help.
I don't know why you use text type to store id. By the way
update summary_finished as sf
inner join (
select finished_id,
sum(quantity) as total
from detail_finished
group by finished_id )as t
set sf.qoh = t.total
where sf.finished_id = t.finished_id