can you help me guys to join two queries in one?
This is my first query:
SELECT estimated_sum_all, story_point_sum_all, time_spent, reg_date
FROM burndown_snap_all WHERE project_id='72'
Results:
| estimated_sum_all | story_point_sum_all | time_spent | reg_date |
| 300 | 20 | 20.30 | 2017-09 |
| 300 | 20 | 19.30 | 2017-09 |
| 300 | 20 | 18.30 | 2017-09 |
| 300 | 20 | 15.32 | 2017-09 |
This is my second query:
SELECT time_spent FROM status_history_hours where
project_id = '72'
Results:
| time_spent |
| 20.30 |
| 20.30 |
| 20.30 |
| 20.30 |
What I wanna to do is to build one mysql query that have to contain select/join to time_spent from the second query. Final table should looks like this:
| estimated_sum_all | story_point_sum_all | time_spent | reg_date |
| 300 | 20 | 20.30 | 2017-09 |
| 300 | 20 | 20.30 | 2017-09 |
| 300 | 20 | 20.30 | 2017-09 |
| 300 | 20 | 20.30 | 2017-09 |
Regards,
Solution for this would be like:
SELECT t1.id, t1.estimated_sum_all,
t1.story_point_sum_all, t1.time_spent,
t2.id, t2.time_spent FROM
burndown_snap_all t1, status_history_hours
t2 WHERE t1.project_id = 72 AND
t2.project_id = 72 group by t1.id
But how to group by t2.id in the same time???
SELECT estimated_sum_all, story_point_sum_all, time_spent, reg_date
FROM burndown_snap_all WHERE project_id='72'
UNION ALL
SELECT time_spent FROM status_history_hours where
project_id = '72'
From the data that you have provided, you can take any matching value from the second table. So, you could do:
SELECT bsa.estimated_sum_all, bsa.story_point_sum_all, bsa.time_spent,
bsa.reg_date,
(SELECT MAX(shh.time_spent)
FROM status_history_hours shh
WHERE shh.project_id = bsa.project_id
) as time_spent
FROM burndown_snap_all bsa
WHERE project_id = 72;
Related
We have two tables credit_points and debit_points having user_id is reference. Our concern is we want to fetch all the records in a single query order by created_date DESC with limit and offset. Please find the table list and Output table.
credit_points
+----+----------+--------------+---------------------+
| id | user_id | credit_value | created_date |
+----+----------+--------------+---------------------+
| 1 | 111 | 13 | 2020-01-08 10:20:26 |
| 2 | 111 | 11 | 2020-01-09 11:20:23 |
| 3 | 111 | 7 | 2020-01-09 13:25:12 |
| 4 | 111 | 20 | 2020-01-13 12:25:17 |
+----+----------+--------------+---------------------+
debit_points
+----+----------+--------------+---------------------+
| id | user_id | debit_value | created_date |
+----+----------+--------------+---------------------+
| 1 | 111 | 13 | 2020-01-09 10:20:25 |
| 2 | 111 | 11 | 2020-01-11 11:18:54 |
| 3 | 111 | 15 | 2020-01-14 13:50:24 |
| 4 | 111 | 5 | 2020-01-14 15:23:12 |
+----+----------+------------+-----------------------+
Output should be:
+----------+--------------+---+------------------------------+
| user_id | credit_value | debit_value | created_date |
+----------+--------------+-------------+--------------------+
| 111 | NULL | 5 |2020-01-14 15:23:12 |
| 111 | NULL | 15 |2020-01-14 13:50:24 |
| 111 | 20 | NULL |2020-01-13 12:25:17 |
| 111 | NULL | 11 |2020-01-11 11:18:54 |
| 111 | 7 | NULL |2020-01-09 13:25:12 |
| 111 | 11 | NULL |2020-01-09 11:20:23 |
| 111 | NULL | 13 |2020-01-09 10:20:25 |
| 111 | 13 | NULL |2020-01-08 10:20:26 |
+----------+--------------+-------------+-----+--------------+
Query1:
SELECT
c.user_id, c.credit_value, d.debit_value, d.created_date
FROM credit_points c
RIGHT JOIN debit_points d ON(c.user_id=d.user_id)
WHERE c.user_id=111
ORDER BY c.created_date,d.created_date DESC
limit 20;
I know the above query is completely wrong. Please help me to fetch it in the right way.
Query2:
SELECT user_id,credit_value, created_date
FROM credit_points where user_id=111
UNION ALL
SELECT user_id,debit_value,created_date
FROM debit_points where user_id=111 ORDER BY created_date DESC
The above query(Query2) is working fine but we are unable to fetch the debit_value column. Both credit_value and debit_value is coming in one column.
You can combine the data from both tables into a derived table by using UNION and then execute a SELECT over it with needed offset:
SELECT * FROM
(
SELECT user_id, credit_value, NULL AS debit_value, created_date FROM muvi_credit_points
UNION ALL
SELECT user_id, NULL AS credit_value, debit_value, created_date FROM muvi_debit_points
) t
WHERE user_id = 111
ORDER BY created_date DESC
LIMIT 0, 20
Of course, the filtering by user_id could be done into internal SELECT statements if needed.
This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 4 years ago.
I have the following table.
+--------------------+--------------+-------+
Date | SymbolNumber | Value
+--------------------+--------------+-------+
2018-08-31 15:00:00 | 123 | data
2018-09-31 15:00:00 | 456 | data
2018-09-31 15:00:00 | 123 | data
2018-09-31 15:00:00 | 555 | data
2018-10-31 15:00:00 | 555 | data
2018-10-31 15:00:00 | 231 | data
2018-10-31 15:00:00 | 123 | data
2018-11-31 15:00:00 | 123 | data
2018-11-31 15:00:00 | 555 | data
2018-12-31 15:00:00 | 123 | data
2018-12-31 15:00:00 | 555 | data
I need a query that can select the last row of each SymbolNumber stated in the query.
SELECT
*
FROM
MyTable
WHERE
symbolNumber IN (123, 555)
AND
**lastOfRow ordered by latest-date**
Expected results:
2018-12-31 15:00:00 | 123 | data
2018-12-31 15:00:00 | 555 | data
How can I do this?
First, you will need a query that get the latest date for each symbolNumber. Second, you can inner join to this table (using date) for get the rest of the columns. Like this:
SELECT
t.*
FROM
<table_name> AS t
INNER JOIN
(SELECT
symbolNumber,
MAX(date) AS maxDate
FROM
<table_name>
GROUP BY
symbolNumber) AS latest_date ON latest_date.symbolNumber = t.symbolNumber AND latest_date.maxDate = t.date
The previous query will get latest data for each existing symbolNumber on the table. If you want to restrict to symbolNumbers: 123 and 555, you will need to made next modification:
SELECT
t.*
FROM
<table_name> AS t
INNER JOIN
(SELECT
symbolNumber,
MAX(date) AS maxDate
FROM
<table_name>
WHERE
symbolNumber IN (123, 555)
GROUP BY
symbolNumber) AS latest_date ON latest_date.symbolNumber = t.symbolNumber AND latest_date.maxDate = t.date
We can do a "self-left-join" on symbolNumber, and match to other rows in the same group with higher Date value on the right side.
We will eventually consider only those rows, where higher date could not be found (meaning the current row belongs to highest date in the group).
Here is a solution avoiding subquery, and utilizing Left Join:
SELECT t1.*
FROM MyTable AS t1
LEFT JOIN MyTable AS t2
ON t2.symbolNumber = t1.symbolNumber AND
t2.Date > t1.Date -- Joining to a row in same group with higher date
WHERE t1.symbolNumber IN (123, 555) AND
t2.symbolNumber IS NULL -- Higher date not found; so this is highest row
EDIT:
Benchmarking studies comparing Left Join method v/s Derived Table (Subquery)
#Strawberry ran a little benchmark test in 5.6.21. Here's what he found...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,dense_user INT NOT NULL
,sparse_user INT NOT NULL
);
INSERT INTO my_table (dense_user,sparse_user)
SELECT RAND()*100,RAND()*100000;
INSERT INTO my_table (dense_user,sparse_user)
SELECT RAND()*100,RAND()*100000 FROM my_table;
-- REPEAT THIS LINE A FEW TIMES !!!
SELECT COUNT(DISTINCT dense_user) dense
, COUNT(DISTINCT sparse_user) sparse
, COUNT(*) total
FROM my_table;
+-------+--------+---------+
| dense | sparse | total |
+-------+--------+---------+
| 101 | 99999 | 1048576 |
+-------+--------+---------+
ALTER TABLE my_table ADD INDEX(dense_user);
ALTER TABLE my_table ADD INDEX(sparse_user);
--dense_test
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.dense_user = x.dense_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY dense_user
LIMIT 10;
+------+------------+-------------+
| id | dense_user | sparse_user |
+------+------------+-------------+
| 1212 | 0 | 1950 |
| 153 | 1 | 23193 |
| 255 | 2 | 27472 |
| 28 | 3 | 86440 |
| 18 | 4 | 47886 |
| 291 | 5 | 76563 |
| 15 | 6 | 85049 |
| 16 | 7 | 78384 |
| 135 | 8 | 52304 |
| 62 | 9 | 40930 |
+------+------------+-------------+
10 rows in set (2.64 sec)
SELECT x.*
FROM my_table x
JOIN
( SELECT dense_user, MIN(id) id FROM my_table GROUP BY dense_user ) y
ON y.dense_user = x.dense_user
AND y.id = x.id
ORDER
BY dense_user
LIMIT 10;
+------+------------+-------------+
| id | dense_user | sparse_user |
+------+------------+-------------+
| 1212 | 0 | 1950 |
| 153 | 1 | 23193 |
| 255 | 2 | 27472 |
| 28 | 3 | 86440 |
| 18 | 4 | 47886 |
| 291 | 5 | 76563 |
| 15 | 6 | 85049 |
| 16 | 7 | 78384 |
| 135 | 8 | 52304 |
| 62 | 9 | 40930 |
+------+------------+-------------+
10 rows in set (0.05 sec)
Uncorrelated query is 50 times faster.
--sparse test
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.sparse_user = x.sparse_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY sparse_user
LIMIT 10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 165055 | 75 | 0 |
| 37598 | 63 | 1 |
| 170596 | 70 | 2 |
| 46142 | 87 | 3 |
| 33546 | 21 | 4 |
| 323114 | 87 | 5 |
| 86592 | 96 | 6 |
| 156711 | 36 | 7 |
| 17148 | 62 | 8 |
| 139965 | 71 | 9 |
+--------+------------+-------------+
10 rows in set (0.03 sec)
SELECT x.*
FROM my_table x
JOIN ( SELECT sparse_user, MIN(id) id FROM my_table GROUP BY sparse_user ) y
ON y.sparse_user = x.sparse_user
AND y.id = x.id
ORDER
BY sparse_user
LIMIT 10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 165055 | 75 | 0 |
| 37598 | 63 | 1 |
| 170596 | 70 | 2 |
| 46142 | 87 | 3 |
| 33546 | 21 | 4 |
| 323114 | 87 | 5 |
| 86592 | 96 | 6 |
| 156711 | 36 | 7 |
| 17148 | 62 | 8 |
| 139965 | 71 | 9 |
+--------+------------+-------------+
10 rows in set (4.73 sec)
Exclusion Join is 150 times faster
However, as you move further up the result set, the picture begins to change very dramatically...
SELECT x.*
FROM my_table x
JOIN ( SELECT sparse_user, MIN(id) id FROM my_table GROUP BY sparse_user ) y
ON y.sparse_user = x.sparse_user
AND y.id = x.id
ORDER
BY sparse_user
LIMIT 10000,10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 9810 | 93 | 10000 |
| 162438 | 4 | 10001 |
| 467371 | 62 | 10002 |
| 8258 | 13 | 10003 |
| 297049 | 17 | 10004 |
| 68354 | 23 | 10005 |
| 192701 | 64 | 10006 |
| 176225 | 92 | 10007 |
| 156595 | 37 | 10008 |
| 318266 | 1 | 10009 |
+--------+------------+-------------+
10 rows in set (9.17 sec)
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.sparse_user = x.sparse_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY sparse_user
LIMIT 10000,10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 9810 | 93 | 10000 |
| 162438 | 4 | 10001 |
| 467371 | 62 | 10002 |
| 8258 | 13 | 10003 |
| 297049 | 17 | 10004 |
| 68354 | 23 | 10005 |
| 192701 | 64 | 10006 |
| 176225 | 92 | 10007 |
| 156595 | 37 | 10008 |
| 318266 | 1 | 10009 |
+--------+------------+-------------+
10 rows in set (32.19 sec) -- !!!
In summary, the exclusion join (the so-called 'strawberry query' can be (significantly) faster in certain, limited situations. More generally, an uncorrelated query will be faster.
I have been working on this for about two days now and cant seem to figure it out so I would love some help.
I have two tables:
mysql> select id, date, volume, symbol_id from control_quotedaily limit 5;
+-------+---- -------+----------+-----------+
| id | date | volume | symbol_id |
+-------+------------+----------+-----------+
| 13263 | 2017-11-02 | 7800191 | AXISBANK |
| 13264 | 2017-11-02 | 9303981 | SBIN |
| 13265 | 2017-11-02 | 8013536 | HDFCBANK |
| 13266 | 2017-11-03 | 9642624 | AXISBANK |
| 13267 | 2017-11-04 | 19642327 | AXISBANK |
+-------+------------+----------+-----------+
5 rows in set (0.00 sec)
14 rows in set (0.01 sec)
mysql> select * from control_oidaily
+-----------+------------+-------------+--------------+
| symbol_id | date | expiry_date | val_in_lakhs |
+-----------+------------+-------------+--------------+
| AXISBANK | 2017-11-02 | 2017-11-30 | 166881.8 |
| AXISBANK | 2017-11-02 | 2017-12-28 | 2676.84 |
| AXISBANK | 2017-11-02 | 2018-01-25 | 97.13 |
| HDFCBANK | 2017-11-02 | 2017-11-30 | 76351.11 |
| HDFCBANK | 2017-11-02 | 2017-12-28 | 1509.48 |
| HDFCBANK | 2017-11-02 | 2018-01-25 | 0 |
| SBIN | 2017-11-02 | 2017-11-30 | 88654.3 |
| SBIN | 2017-11-02 | 2017-12-28 | 1060.51 |
| SBIN | 2017-11-02 | 2018-01-25 | 0 |
| AXISBANK | 2017-11-03 | 2017-11-30 | 87640.06 |
+-----------+------------+-------------+--------------+
So for every quote in the control_quotedaily table this is what I want:
closest expiry_date for that quote from the control_oidaily table
I want the val_in_lakhs for that expiry_date.
Eg: For date 2017-11-02, the closest expiry is 2017-11-30 and I want the val_in_lakhs (76351.11) returned.
This is what I am trying:
select o.date, o.expiry_date as expiry_date, o.symbol_id, q.date, q.symbol_id, o.val_in_lakhs, q.tottrdval, q.volume, q.symbol_id
FROM control_oidaily o
JOIN ( select o.date, MIN(expiry_date) as expiry_date, symbol_id
FROM control_oidaily o
GROUP by o.date,o.symbol_id
ORDER BY o.date asc) as ed
ON ed.date = o.date
AND ed.symbol_id = o.symbol_id
AND ed.expiry_date = o.expiry_date
JOIN control_quotedaily q
ON q.date = ed.date
AND q.symbol_id = ed.symbol_id
This is the output I am expecting:
+-------+------------+----------+-----------+--------------+--------------+
| id | date | volume | symbol_id | expiry_date | val_in_lakhs |
+-------+------------+----------+-----------+--------------+--------------+
| 13263 | 2017-11-02 | 7800191 | AXISBANK | 2017-11-30 | 166881.8 |
| 13264 | 2017-11-02 | 9303981 | SBIN | 2017-11-30 | 88654.3 |
| 13265 | 2017-11-02 | 8013536 | HDFCBANK | 2017-11-30 | 76351.11 |
| 13266 | 2017-11-03 | 9642624 | AXISBANK | 2017-11-30 | 87640.06 |
+-------+------------+----------+-----------+--------------+--------------+
In a Derived Table, get the closest_expiry_date (minimum value of expiry_date), for a grouping of symbol_id and date, from control_oidaily table.
Join this with the control_quotedaily table on symbol_id and date, to get closest_expiry_date value for every row in the control_quotedaily table.
Now, use the same derived table again to join with control_oidaily table, matching up on date, expiry_date (with closest expiry date) and symbol_id to get val_in_lakhs.
You possibly want the following query:
SELECT q.id,
q.`date`,
q.volume,
q.symbol_id,
o1.expiry_date,
o1.val_in_lakhs
FROM control_quotedaily AS q
JOIN (SELECT o2.`date`,
o2.symbol_id
MIN(o2.expiry_date) as closest_expiry_date
FROM control_oidaily AS o2
GROUP by o2.`date`, o2.symbol_id
) AS dt
ON dt.`date` = q.`date`
AND dt.symbol_id = q.symbol_id
JOIN control_oidaily AS o1
ON dt.`date` = o1.`date`
AND dt.symbol_id = o1.symbol_id
AND dt.closest_expiry_date = o1.expiry_date
How can I write a single query that will give me SUM(Entrance.quantity) - SUM(Buying.quantity) group by product_id.
The problem is in rows that not exist in the first or second table. Is possible to do this?
Entrance:
+---+--------------+---------+
| id | product_id | quantity|
+---+--------------+---------+
| 1 | 234 | 15 |
| 2 | 234 | 35 |
| 3 | 237 | 12 |
| 4 | 237 | 18 |
| 5 | 101 | 10 |
| 6 | 150 | 12 |
+---+--------------+---------+
Buying:
+---+------------+-------------+
| id | product_id | quantity|
+---+------------+-------------+
| 1 | 234 | 10 |
| 2 | 234 | 20 |
| 3 | 237 | 10 |
| 4 | 237 | 10 |
| 5 | 120 | 15 |
+---+------------+------------+
Desired result:
+--------------+-----------------------+
| product_id | quantity_balance |
+--------------+-----------------------+
| 234 | 20 |
| 237 | 10 |
| 101 | 10 |
| 150 | 12 |
| 120 | -15 |
+--------------+-----------------------+
This is tricky, because products could be in one table but not the other. One method uses union all and group by:
select product_id, sum(quantity)
from ((select e.product_id, quantity
from entrance e
) union all
(select b.product_id, - b.quantity
from buying b
)
) eb
group by product_id;
SELECT product_id ,
( Tmp1.enterquantity - Tmp2.buyquantity ) AS Quantity_balance
FROM entrance e1
CROSS APPLY ( SELECT SUM(quantity) AS enterquantity
FROM Entrance e2
WHERE e1.product_id = e2.product_id
) Tmp1
CROSS APPLY ( SELECT SUM(quantity) AS buyquantity
FROM Buying b2
WHERE e1.product_id = b2.product_id
) Tmp2
GROUP BY Product_id,( Tmp1.enterquantity - Tmp2.buyquantity )
how can I delete rows from this table in mysql database that after the delete I should have 4 distinct values in the column valeurs .
the actual state of my database :
+----+-----------+---------+---------------------+
| id | action_id | valeurs | temps_action |
+----+-----------+---------+---------------------+
| 81 | 1 | ON_1 | 2016-04-26 11:14:43 |
| 80 | 2 | OFF_2 | 2016-04-26 11:14:41 |
| 84 | 2 | OFF_2 | 2016-04-26 11:14:48 |
| 83 | 1 | ON_1 | 2016-04-26 11:14:46 |
| 79 | 1 | OFF_1 | 2016-04-26 11:14:40 |
| 78 | 2 | ON_2 | 2016-04-26 11:14:38 |
| 77 | 1 | ON_1 | 2016-04-26 11:14:35 |
| 82 | 2 | OFF_2 | 2016-04-26 11:14:45 |
+----+-----------+---------+---------------------+
I want to end up with :
+----+-----------+---------+---------------------+
| id | action_id | valeurs | temps_action |
+----+-----------+---------+---------------------+
| 81 | 1 | ON_1 | 2016-04-26 11:14:43 |
| 80 | 2 | OFF_2 | 2016-04-26 11:14:41 |
| 79 | 1 | OFF_1 | 2016-04-26 11:14:40 |
| 78 | 2 | ON_2 | 2016-04-26 11:14:38 |
+----+-----------+---------+---------------------+
such query saves the rows with max temps_action for each action_id, valeurs
delete
from my_table
where (action_id, temps_action, valeurs) not in
(select * from (select action_id, max(temps_action), valeurs
from my_table
group by action_id, valeurs) t1);
You can use this way
delete from my_table as t
where (t.id, t.valeurs) not in ( select max(t2.id), t2.valeurs
from my_table as t2
group by valeurs);
What you're really trying to do is to remove duplicate rows. Here's an example query that could help you with that:
DELETE FROM TableName
WHERE valeurs IN (SELECT *
FROM (SELECT valeurs FROM TableName
GROUP BY valeurs
HAVING (COUNT(*) > 1) AS Something
)
);