Join 2 tables SQL query - mysql

I'm trying to write a query for Select from 2 tables.
Tables are the following:
Table_1:
id (int)
name (varchar)
status int (0,1)
Table_2:
id (int)
table_1_id (int)
name (varchar)
time (datetime)
I need to select all the rows from Table_2 which are no older than 1 day and that are associated with table_1 with status 1. The way I do it now is using 2 queries and 2 foreach arrays, which is very inefficient. Could someone help me to write a query with join? Thank you for your time.

No need of looping, you can do a JOIN between the tables like
select t2.*
from Table_2 t2 join Table_1 t1 on t2.table_1_id = t1.id
where t1.status = 1
and date(t2.`time`) = date(now() - interval 1 day);

SELECT table_2.* FROM table_1 t1 INNER JOIN table_2 t2 ON t2.table_1_id=t1.id
WHERE t1.status=1 AND time < (NOW() - INTERVAL 1 DAY);
You have to use ON to join tables since the fields in question do not have the same name. Otherwise you could have joined with USING(id_field). In your case inner join is probably most useful. You could have used left join if you wanted matching results from table_1 even if there is no counterpart in table_2, e.g.

Do not need 2 queries. You can use 1 query as:
SELECT t2.* FROM Table_1 t1, Table_2 t2
WHERE t1.id = t2.table_1_id AND
t1.status = 1 AND
DATE(t2.'time') >= DATE(now() - INTERVAL 1 DAY)
Because you want
I need to select all the rows from Table_2 which are no older than 1 day
so we must have greater than or equal operator:
DATE(t2.'time') >= DATE(now() - INTERVAL 1 DAY)

Related

Select column from another table based on matching condition

I have two tables that have time-series data in the following form. I want to select all of the columns of TABLE1 and an additional column Limit_At_Time which is the value of the Limit column of TABLE2 for the row which has the most recent Date (relative to TABLE1.Date)
TABLE1:
Customer_ID Date Amount
1 01/01/2019 5
2 02/05/2019 15
TABLE2:
Customer_ID Date Limit
1 12/05/2018 10
1 12/25/2018 20
2 01/05/2019 30
2 03/08/2019 50
Result:
Customer_ID Date Amount Limit_At_Time
1 01/01/2019 5 20
2 02/05/2019 15 30
The closest I have gotten is selecting a previous_date column with this query:
SELECT *,
(SELECT MAX(Date) FROM TABLE2 t2
WHERE t2.Date < t1.Date
AND t2.Customer_ID = t1.Customer_ID)
as previous_date
FROM TABLE1 AS t1
This gets me the date of the event from TABLE2 that I am interested in for each TABLE1 row, but I need to extract the Limit column value of the row that contains that previous_date.
How can I achieve the result that I want?
I would just use a correlated subquery:
select t1.*,
(select t2.limit
from table2 t2
where t2.date <= t1.date
order by t2.date desc
limit 1
) as Limit_At_Time
from table1 t1;
Usually in these types of problems, the comparison is <= rather than <, so I used that. Of course, the exact equivalent to your query is <.
You can use your subquery as a JOIN condition between table1 and table2 which will then allow you to get the Limit value from table2:
SELECT t1.Customer_ID, t1.Date, t1.Amount, t2.Limit
FROM table1 t1
JOIN table2 t2 ON t2.Customer_ID = t1.Customer_ID
AND t2.Date = (SELECT MAX(Date) FROM table2 t2b
WHERE t2b.Date < t1.Date
AND t2b.Customer_ID = t1.Customer_ID)
Output:
Customer_ID Date Amount Limit
1 2019-01-01 5 20
2 2019-02-05 15 30
Demo on dbfiddle

Query group by 2 column

I have 1 table with 4 columns
id, name, key, date
1,'A' ,'x1','2015-11-11'
2,'A' ,'x1','2015-11-11'
3,'B' ,'x2','2015-11-11'
4,'B' ,'x2','2015-11-11'
5,'A' ,'x1','2015-11-12'
6,'A' ,'x1','2015-11-12'
7,'B' ,'x2','2015-11-12'
8,'B' ,'x2','2015-11-12'
9,'D' ,'x3','2015-11-12'
I want group by [key] and [date]. Result I want is:
2015-11-11 2
2015-11-12 1
2: date 2015-11-11 have 4 rows (1,2,3,4) but duplicate key, so when group by we only have 2 row.
1: date 2015-11-12 have 5 rows (5,6,7,8,9) but have 4 rows (5,6,7,8) duplicate with date 2015-11-11, I don't want calculator => we only have 1 rows (9)
I'm sorry for my english. I hope you can understand my question.
Please help me every way. I'm using mysql.
select key, date, (select count(*) from tablename t2
where t2.key = t1.key
and t2.date = t1.date
and not exists (select 1 from tablename t3
where t3.key = t2.key
and t3.date < t2.date))
from tablename t1
You can use a correlated sub-query to count that date's keys. Do not count if that date's key-value have already been found for an older date.
Alternative solution:
select t1.key, t1.date, count(*)
from tablename t1
LEFT JOIN (select key, min(date) as date from tablename group by key) t2
ON t2.key = t1.key and t2.date = t1.date
group by t1.key, t1.date

How can I add subtotal to table in MySQL?

Assume my table looks like the following:
id count sub_total
1 10 NULL
2 15 NULL
3 10 NULL
4 25 NULL
How can I update this table to look like the following?
id count sub_total
1 10 10
2 15 25
3 10 35
4 25 60
I can do this easy enough in the application layer. But I'd like to learn how to do it in MySQL. I've been trying lots of variations using SUM(CASE WHEN... and other groupings to no avail.
If your id field is sequential and growing then a correlated subquery is one way:
select *, (select sum(count) from t where t.id <= t1.id)
from t t1
or as a join:
select t1.id, t1.count, sum(t2.count)
from t t1
join t t2 on t2.id <= t1.id
group by t1.id, t1.count
order by t1.id
To update your table (assuming the column sub_total already exists):
update t
join (
select t1.id, sum(t2.count) st
from t t1
join t t2 on t2.id <= t1.id
group by t1.id
) t3 on t.id = t3.id
set t.sub_total = t3.st;
Sample SQL Fiddle showing the update.

mysql extract rows with max values

I'm trying to figure out best way to take required rows from database.
Database table:
id user cat time
1 5 1 123
2 5 1 150
3 5 2 160
4 5 3 100
I want to take DISTINCT cat ... WHERE user=5 with MAX time value. How should I do that in efficient way?
You will want to use an aggregate function with a GROUP BY:
select user, cat, max(time) as Time
from yourtable
group by user, cat
See SQL Fiddle with Demo
If you want to include the id column, then you can use a subquery:
select t1.id,
t1.user,
t1.cat,
t1.time
from yourtable t1
inner join
(
select max(time) Time, user, cat
from yourtable
group by user, cat
) t2
on t1.time = t2.time
and t1.user = t2.user
and t1.cat = t2.cat
See SQL Fiddle with Demo. I used a subquery to be sure that the id value that is returned with each max(time) row is the correct id.

Join Tables Based on Correlated Subquery, SQL

I need to join two tables that are described below:
Table1:
ID Date Info1
1 1/29/2011 i10
1 1/30/2011 i11
Table2:
ID Date Info2
1 1/31/2011 i2
I would like to left join the records in Table 2 identified by ID, Month, Year to that in Table 1 identified by the same ID, Month, Year but use the last available record date as the joining record. So for example, in the data above I would join the record in Table 2 to the second record in Table 1 because they match in ID, Month, Year and record 2 of Table 1 has the greatest available day for that (ID, Month, Year) combination. The correct result is:
ID Date Info1 Info2
1 1/30/2011 i11 i2
The SQL code I am coming up with so far is pretty convoluted. Please suggest something. I am using MySQL.
[I want to] ...use the last available record date as the joining record
Solve that first, with a derived table. Assuming that ID, Date is unique, then you can easily group by ID and take the MAX date.
SELECT
T1.*,
T2.*
FROM Table1 as T1
JOIN (
SELECT
ID, MAX(Date) as Date
FROM Table1
GROUP BY
ID
) as Last ON
T1.ID = Last.ID
AND T1.Date = Last.Date
LEFT OUTER JOIN Table2 as T2 ON
T1.ID = Last.ID
AND MONTH(T1.Date) = MONTH(T2.Date)
AND YEAR(T1.Date) = YEAR(T2.Date)