mysql query for adding non existing rows with count zero - mysql

"Table A" & "Table B" are my initial tables for the query. Result is the final table as shown in the following figure.Find Non-existing rows
Table A:
| Date | Name | Count |
|:----------:|:----:|:-----:|
| 01-01-2020 | A | 5 |
| 01-01-2020 | B | 15 |
| 02-01-2020 | B | 20 |
| 02-01-2020 | C | 15 |
| 02-01-2020 | D | 30 |
| 03-01-2020 | A | 30 |
| 03-01-2020 | D | 10 |
Table B:
| Name |
|:----:|
| A |
| B |
| C |
| D |
Result:
| Date | Name | Count |
|:----------:|:----:|:-----:|
| 01-01-2020 | A | 5 |
| 01-01-2020 | B | 15 |
| 01-01-2020 | C | 0 |
| 01-01-2020 | D | 0 |
| 02-01-2020 | A | 0 |
| 02-01-2020 | B | 20 |
| 02-01-2020 | C | 15 |
| 02-01-2020 | D | 30 |
| 03-01-2020 | A | 30 |
| 03-01-2020 | B | 0 |
| 03-01-2020 | C | 0 |
| 03-01-2020 | D | 10 |

cross join distinct dates from a to distinct id from b then left join a
drop table if exists t,t1;
create table t
(id varchar(1),dt date);
create table t1
(id varchar(1));
insert into t values
('a','2019-01-01'),('b','2019-01-01'),
('b','2019-02-01'),('d','2019-01-01'),
('c','2019-03-01');
insert into t1 values
('a'),('b'),('c'),('d');
select t3.id,t3.dt,t.id,t.dt
from
(
select distinct dt,s.id from t
cross join
(select distinct id from t1) s
) t3
left join t on t.id = t3.id and t.dt =t3.dt
order by t3.dt,t3.id;
+------+------------+------+------------+
| id | dt | id | dt |
+------+------------+------+------------+
| a | 2019-01-01 | a | 2019-01-01 |
| b | 2019-01-01 | b | 2019-01-01 |
| c | 2019-01-01 | NULL | NULL |
| d | 2019-01-01 | d | 2019-01-01 |
| a | 2019-02-01 | NULL | NULL |
| b | 2019-02-01 | b | 2019-02-01 |
| c | 2019-02-01 | NULL | NULL |
| d | 2019-02-01 | NULL | NULL |
| a | 2019-03-01 | NULL | NULL |
| b | 2019-03-01 | NULL | NULL |
| c | 2019-03-01 | c | 2019-03-01 |
| d | 2019-03-01 | NULL | NULL |
+------+------------+------+------------+
12 rows in set (0.05 sec)
PS - if you want solutions which are close to your model you should include table definitions and sample data as text in the question (which we can use) rather than links to images (which cannot use)

Related

Verification of dates mySQL

I need to check that the steps of each project were done between the start and end dates of the project. (Write a query that allows a human to know if this is the case)
This is my code:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin
FROM (SELECT idprojet,
datedebut,
datefin
FROM projet) AS p
LEFT JOIN etapexprojet AS e
ON e.datedebut < p.datedebut
AND e.datefin < p.datefin
ORDER BY idprojet;
The table of EtapexProjet (There is other date inside the table EtapexProjet ):
+---------+----------+-------------+--------------+--+
| idEtape | idProjet | dateDebut | dateFin | |
+---------+----------+-------------+--------------+--+
| 1 | 1 | 2011-07-01 | 2011-09-01 | |
| 1 | 2 | 2012-05-01 | 2012-05-10 | |
| 1 | 3 | 2011-11-01 | 2012-01-20 | |
| 2 | 1 | | | |
| 2 | 2 | | | |
| 2 | 3 | | | |
| 3 | 1 | | | |
| 3 | 2 | | | |
| 3 | 3 | | | |
| 4 | 1 | | | |
| 4 | 2 | | | |
| 5 | 2 | | | |
+---------+----------+-------------+--------------+--+
The table of Projet:
+----------+----------+-----------+------------+------------+---------------+--+
| idProjet | idClient | nomProjet | dateDebut | dateFin | idResponsable | |
+----------+----------+-----------+------------+------------+---------------+--+
| 1 | 321 | Devl. | 2011-08-01 | | 1876 | |
| 2 | 321 | Maint. | 2012-05-01 | 2012-07-23 | 2231 | |
| 3 | 345 | Devl.2 | 2011-11-01 | | 2231 | |
+----------+----------+-----------+------------+------------+---------------+--+
My expected results is that to check/verify if the beginning and ending date of each idEtape is between the beginning date and the ending date of the projet its related.
You don't need to use a Derived Table (sub-select query), as you are not doing any sort of aggregation, etc on the projet table.
I believe that you are only concerned with the idetape values which lie inside the projet's datedebut and datefin.
You can change Left Join to Inner Join due to above mentioned point.
I have also increased the horizon of cases to check, as there is a possibility of datefin being NULL in either of the tables.
Try the following instead:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin,
p.datedebut AS projet_datedebut,
p.datefin AS projet_datefin
FROM EtapexProjet AS e
JOIN Projet AS p
ON p.idprojet = e.idprojet
AND e.datedebut >= p.datedebut
AND (e.datefin <= p.datefin OR
p.datefin IS NULL OR
e.datefin IS NULL
)
ORDER BY e.idprojet,
e.idetape;
Please try the code below:
SELECT nomEtape, livrable, idEtape, idProjet
FROM Etape
WHERE idEtape= (SELECT MAX(idEtape)
FROM EtapexProjet
WHERE DISTINCT(idProjet)
);

How can I merge multiple rows with same ID into one row?

How can I merge multiple rows with same ID into one row.
I have table:
+----+------+------+------+
| ID | A | B | C |
+----+------+------+------+
| 1 | 123 | 31 | 456 |
| 1 | 412 | NULL | 1 |
| 2 | 567 | 38 | 4 |
| 2 | 567 | NULL | NULL |
| 3 | 2 | NULL | NULL |
| 3 | 5 | NULL | NULL |
| 4 | 6 | 1 | NULL |
| 4 | 8 | NULL | 5 |
| 4 | NULL | NULL | 5 |
+----+------+------+------+
I want to have table :
I have table:
+----+-----+------+------+-----+------+------+------+------+----+
| ID | A | B | C | A2 | B2 | C2 | A3 | B3 | C3 |
+----+-----+------+------+-----+------+------+------+------+----+
| 1 | 123 | 31 | 456 | 412 | NULL | 1 | | | |
| 2 | 567 | 38 | 4 | 567 | NULL | NULL | | | |
| 3 | 2 | NULL | NULL | 5 | NULL | NULL | | | |
| 4 | 6 | 1 | NULL | 8 | NULL | 5 | NULL | NULL | 5 |
+----+-----+------+------+-----+------+------+------+------+----+
Try This:-
1 :- Please Change data table structure to disallow null value.
Query :-
SELECT
GROUP_CONCAT(if (`A` ='0', 'NOVAL', `A`)SEPARATOR '----') as A,
GROUP_CONCAT(if (`B` ='0', 'NOVAL', `B`)SEPARATOR '----') as B,
GROUP_CONCAT(if (`C` ='0', 'NOVAL', `C`)SEPARATOR '----') as C
FROM que1
GROUP BY id
Now You can get the value using mysql_fetch_array

MySQL update all values in column based on max date and group

I'm trying to use group by clause to update the dt column based on column 'last'. I need find last date for group 'group by hid,tid,tdate,fid,did,depid,acc' and set 'dt' value for all record in this group.
For example:
| id | hid | tid | tdate | fid | did | p2 | depid | acc | dt | last |
|----------|-------|-----|------------|-----|-----|-------|-------|------|------|----------------------|
| 3742030 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9560 | 1 | 5334 | 1 | 2016-11-03T09:00:20Z |
| 3799297 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8480 | 1 | 5352 | 1 | 2016-11-03T11:12:55Z |
| 4848877 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8720 | 1 | 5352 | 2369 | 2016-12-17T16:59:22Z |
| 10706343 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9660 | 1 | 5334 | 2065 | 2017-03-01T12:32:27Z |
| 14546682 | 2386 | 1 | 2017-08-29 | 1 | 1 | 11720 | 1 | 5352 | 4431 | 2017-05-12T10:24:09Z |
| 15824920 | 12332 | 1 | 2017-09-02 | 1 | 1 | 10820 | 1 | 5334 | 1111 | 2017-07-15T05:19:04Z |
to
| id | hid | tid | tdate | fid | did | p2 | depid | acc | dt | last |
|----------|-------|-----|------------|-----|-----|-------|-------|------|------|----------------------|
| 3742030 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9560 | 1 | 5334 | 1111 | 2016-11-03T09:00:20Z |
| 3799297 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8480 | 1 | 5352 | 4431 | 2016-11-03T11:12:55Z |
| 4848877 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8720 | 1 | 5352 | 4431 | 2016-12-17T16:59:22Z |
| 10706343 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9660 | 1 | 5334 | 1111 | 2017-03-01T12:32:27Z |
| 14546682 | 2386 | 1 | 2017-08-29 | 1 | 1 | 11720 | 1 | 5352 | 4431 | 2017-05-12T10:24:09Z |
| 15824920 | 12332 | 1 | 2017-09-02 | 1 | 1 | 10820 | 1 | 5334 | 1111 | 2017-07-15T05:19:04Z |
Schema:
http://sqlfiddle.com/#!9/4fad1d/1
Is there some way to update all rows in the table based on group?
Thanks
Join the table with the subquery that will find the most recent row per group.
update of t
join (
select t1.*
from of t1
join (
select hid,tid,tdate,fid,did,depid,acc, max(last) as last
from of
group by hid,tid,tdate,fid,did,depid,acc
) t2 using (hid,tid,tdate,fid,did,depid,acc,last)
) t3 using (hid,tid,tdate,fid,did,depid,acc)
set t.dt = t3.dt;
http://sqlfiddle.com/#!9/93708/2
For the join in the subquery you can also use NATURAL JOIN
natural join (
select hid,tid,tdate,fid,did,depid,acc, max(last) as last
from of
group by hid,tid,tdate,fid,did,depid,acc
) t2
http://sqlfiddle.com/#!9/e7e5ee/1

Select Same Column From 2 Tables into 1 Column in View

I have two column with the same name in different tables.
I want to join them into one column in a view.
Here my first table stocks:
+----------+------------+------------+---------+----------------+--------+
| stock_id | stock_cost | stock_left | item_id | purchasedtl_id | trx_id |
+----------+------------+------------+---------+----------------+--------+
| 1 | 1000 | 0 | 1 | 1 | 1 |
| 2 | 1000 | 5 | 1 | 2 | 2 |
| 3 | 1000 | 1 | 1 | 3 | 4 |
+----------+------------+------------+---------+----------------+--------+
Second table stocks_out
+-------------+----------------+--------------+---------+----------+------------+--------+
| stockout_id | stockout_price | stockout_qty | item_id | stock_id | saledtl_id | trx_id |
+-------------+----------------+--------------+---------+----------+------------+--------+
| 1 | 2000 | 1 | 1 | 1 | 1 | 3 |
+-------------+----------------+--------------+---------+----------+------------+--------+
And I want to join them to be like this trx_id, trx_no, trx_closetime, trx_type stock_id, stock_cost, stockout_id, stock_out_cost, stockout_price, item_id
item_id is the field I want to join in one column.
The current Query is :
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price` from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the current result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
Found it guys.
I just need to add the following query as the column
COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id`
So the query will be like
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price`, COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price | item_id |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL | 1 |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL | 1 |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 | 1 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL | 1 |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+

How to get value from multiple tables but the value should be min and group wise

How to get value from multiple Table that should be minimum and group wise
Like:
I have Three tables
Table1 Table3
| ID | GPN | PKGID | | GPN | Amt |
| 1 | A | PKG01 | | A | 10 |
| 2 | B | PKG02 | | A | 15 |
| 3 | C | PKG03 | | A | 20 |
| 4 | D | PKG04 | | A | 25 |
| A | 65 |
| A | 30 |
----------------------------- | B | 17 |
| D | 90 |
| B | 20 |
Table2 | B | 40 |
| GPN | Date | | D | 60 |
| A | 2016-09-10 | | B | 80 |
| A | 2016-09-18 | | B | 100 |
| B | 2016-09-10 | | C | 3 |
| B | 2016-09-11 | | C | 6 |
| B | 2016-09-12 | | C | 9 |
| C | 2016-10-12 | | C | 12 |
| C | 2016-10-13 | | C | 15 |
| C | 2016-10-14 | | D | 7 |
| D | 2016-09-10 | | D | 10 |
| D | 2016-10-13 | | D | 13 |
And i have to get values from three of table so how can i do that.
For Example
Date = 2016-09-10
and i have to get values behalf of that
so result should contain all groups min value.
As Result
| ID | PKGID | GPN | Amt | Date |
| 1 | PKG01 | A | 10 | 2016-09-10 |
| 2 | PKG02 | B | 17 | 2016-09-10 |
| 4 | PKG04 | D | 7 | 2016-09-10 |
Should be this
select table.id, table1.PKGID, table1.GPN, min(table3.Amt), table2.`date`
from table1
inner join table3 on table1.GPN= table3.GPN
inner join table2 on table1.GPN= table2.GPN
where date(table2.date ) = str_to_date('2016-09-10', '%Y-%m-%d')
group by table1.GPN, table.id, table1.PKGID, table2.`date`
You can try this too
SELECT t1.*, MIN(t3.Amt) as Amt, t2.Date
FROM table1 t1
INNER JOIN table2 t2 on t1.GPN= t2.GPN
INNER JOIN table3 t3 on t1.GPN= t3.GPN
WHERE t2.Date = '2016-09-10'
GROUP BY t1.GPN
You can try something like this. First get the MIN(Amt) by grouping and then perform a JOIN
select t1.*,
xxx.Amt,
t2.`Date`
from table1 t1 join table2 t2 on t1.GPN = t2.GPN
join (select GPN, min(Amt) as Amt from table3 group by GPN) xxx
on t1.GPN = xxx.GPN;