My query is like this....
SELECT tb1.name, COUNT(tb2.payment_date) as first_payment FROM table1 LEFT JOIN table2 tb2 ON tb2.id_user = tb1.id
+-----------+-------------+
| Name | Count |
+-----------+-------------+
| John | 543534543 |
but I wish that my query returns a limit on join, something like:
LEFT JOIN tb2 ON tb2.id_user = tb1.id { LIMIT JOIN }
return only one relationship.....
+-----------+-------------+
| Name | Count |
+-----------+-------------+
| John | 3 |
select tb1.name, count(*) as first_payment
from table1 t1
LEFT JOIN (SELECT id_user, min(payment_date)
FROM table2
GROUP BY id_user) as t2
ON t1.id = t2.id_user
GROUP BY tb1.name
SELECT
tb1.name,
COUNT(tb2.payment_date) as first_payment
FROM table1
LEFT JOIN (SELECT id_user , MIN(id) FROM table2 GROUP BY id_user)as tb2 ON tb2.id_user = tb1.id
Related
I have 2 table
Table 1
id | value
-----------
1 | a
2 | b
3 | c
4 | d
Table 2
id | table1_id | date
------------------------
1 | 1 | 01-01-2020 1:00:00
2 | 1 | 01-01-2020 2:00:00
3 | 1 | 05-01-2020 1:00:00 (*)
4 | 2 | 05-01-2020 1:00:00
5 | 3 | 06-01-2020 1:00:00
6 | 3 | 06-01-2020 2:00:00 (*)
7 | 2 | 07-01-2020 1:00:00 (*)
I want to join table 1 to table 2. get row of table 2 is max value date and group by table1_id
Like exxample, i want get data like this
id | value | table1_id | date
-------------------------------------------------
1 | a | 1 | 05-01-2020 1:00:00
2 | b | 2 | 07-01-2020 1:00:00
3 | c | 1 | 06-01-2020 2:00:00
4 | d | NULL | NULL
I tryed like this, but not work true
SELECT tb1.*, tb2.* FROM table1 AS tb1
LEFT JOIN
( SELECT * FROM table2 ORDER BY date DESC ) AS tb2
ON tb1.id = tb2.table1_id
GROUP BY table1_id
Can someone help me ? Thanks all <3
The old school way of doing this in MySQL might be to join to a subquery which finds the maximum date in the second table for each table1_id:
SELECT
t1.id,
t1.value,
t2.table1_id,
t2.date
FROM table1 t1
LEFT JOIN
(
SELECT t2.table1_id, t2.date
FROM table2 t2
INNER JOIN
(
SELECT table1_id, MAX(date) AS max_date
FROM table2
GROUP BY table1_id
) t
ON t.table1_id = t2.table1_id AND
t.max_date = t2.date
) t2
ON t2.table1_id = t1.id;
Demo
You can try this:
SELECT id, value, table1_id, max(date) date
FROM
(SELECT t1.id, t1.value, t2.table1_id, t2.date
FROM table1 t1 LEFT JOIN table2 t2
ON t1.id = t2.table1_id
) qry
GROUP BY id, value, table1_id
You can also use window function as below
SELECT tb1.*, tb2.table1_id, tb2.date
FROM table1 AS tb1
LEFT JOIN
( SELECT table2.*,
row_number() over(partition by table1_id ORDER BY date DESC) as seq_num
FROM table2 ) AS tb2
ON tb1.id = tb2.table1_id
Where tb2.seq_num = 1 ;
Here is a demo - https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f52a5a930411dcc04900a1a5bacfe6e9. The demo contains both NULL and not NULL versions.
I strongly recommend that you use window functions for this -- assuming you want mulple columns. This looks like:
select t1.*, t2.*
from table1 t1 left join
(select t2.*,
row_number() over (partition by table1_id order by date DESC) as seqnum
from table2 t2
) t2
on t1.id = t2.table1_id and seq_num = 1 ;
However, if you just want one column -- and the table1_id is redundant so I see no need to include it -- then a correlated subquery is often the fastest method:
select t1.*,
(select max(t2.date) from table2 t2 where t1.id = t2.table1_id)
from table1 t1;
In particular, this can take advantage of an index on table2(table1_id, date).
I have to do a select from 3 trables.
table1- idc,title,description..
table2- idc,filename,filepath,tabel1FK
table3- idc,table1FK,tabel2FK
I need a select from table1 and table2 and count unique ocurrences of table1 in table3
the select must be something like this
TB1 | TB2 | COUNT ON TB3
a | aa | 1
b | | 4
c | cc | 3
d | | 0
e | | 3
I think you just want left join and group by:
select tb1.idc, tb2.idc, count(tb3.idc)
from tb1 left join
tb2
on tb2.table1FK = tb1.idc left join
tb3
on tb3.table1FK = tb1.idc and tb3.tabel2FK = tb2.idc
group by tb1.idc, tb2.idc;
I have two similar tables
Table 1
| id | name | amount|
| 2 | Mike | 1000 |
| 3 | Dave | 2500 |
Table 2
| id | name | amount|
| 2 | Mike | 1200 |
| 4 | James| 2500 |
I want to query the tables to get a result like this:
| id | name | amount_table1| amount_table2|
| 2 | Mike | 1000 | 1200 |
| 3 | Dave | 2500 | |
| 4 | james| | 2500 |
UNION ALL the tables. Do GROUP BY to get one row per id/name combo.
select id, name, sum(amount1), sum(amount2)
from
(
select id, name, amount as amount1, null as amount2 from table1
union all
select id, name, null, amount from table2
) dt
group by id, name
You need to do union with left and right join
select a.id , a.name , a.amount amount_table1,b.amount amount_table2 from table1 a left join table2 b on (a.id=b.id)
union
select b.id , b.name ,a.amount,b.amount from table1 a right join table2 b on (a.id=b.id)
MySql doesn't support FULL OUTER JOIN.
But it supports LEFT & RIGHT joins and UNION.
select
t1.id, t1.name, t1.amount as amount_table1, t2.amount as amount_table2
from Table1 t1
left join Table2 t2 on t1.id = t2.id
union all
select t2.id, t2.name, t1.amount, t2.amount
from Table2 t2
left join Table1 t1 on t2.id = t1.id
where t1.id is null
The first select will get those only in Table1 and those in both.
The second select will get those only in Table2.
And the UNION glues those resultsets together.
If this were for a database that supports FULL JOIN then it would be simplified to:
select
coalesce(t1.id, t2.id) as id,
coalesce(t1.name, t2.name) as name,
t1.amount as amount_table1,
t2.amount as amount_table2
from Table1 t1
full join Table2 t2 on t1.id = t2.id
I have two tables, one with names, nametable:
id | name
---------
1 | alice
2 | bob
3 | charlie
A second with related data, datatable:
id | data
------------
1 | chicken
2 | fish
2 | chicken
3 | spaghetti
Now I want to find matching matching data between two names of nametable:
name1 | name2 | data
--------------------
alice | bob | chicken
Now I have this:
SELECT nt0.name, nt1.name, nt0.data
FROM nametable AS nt0
INNER JOIN datatable AS dt0
ON nt0.id = dt0.id
LEFT JOIN nametable AS nt1
INNER JOIN datatable AS dt1
ON nt1.id = dt1.id
WHERE dt0.data = dt1.data AND nt0.name < nt1.name;
But it doesn't work. I guess the JOINs are the reason, but I don't know how else to do it.
You can do a self join on derived tables:
SELECT
t1.name, t2.name, t1.data
FROM (
SELECT n.id, n.name, d.data
FROM nametable n
INNER JOIN datatable d
ON d.id = n.id
) t1
INNER JOIN (
SELECT n.id, n.name, d.data
FROM nametable n
INNER JOIN datatable d
ON d.id = n.id
)t2
ON t2.data = t1.data
AND t2.id > t1.id
I have table like this:
uid | fid | value
1 | 1 | nameOf1
1 | 2 | surnameOf1
1 | 3 | countryOf1
2 | 1 | nameOf2
2 | 2 | surnameOf2
And need to transform/select it like this:
uid | name | surname | country
1 | nameOf1 | surnameOf1 | countryOf1
2 | nameOf2 | surnameOf2 | ..
Try something like:
SELECT t1.uid, t2.value AS name, t3.value AS surname, t4.value AS country FROM table t1
LEFT JOIN table t2 on t2.uid = t1.uid AND t2.fid = 1
LEFT JOIN table t3 on t3.uid = t1.uid AND t3.fid = 2
LEFT JOIN table t4 on t4.uid = t1.uid AND t4.fid = 3
GROUP BY t1.uid;
or:
SELECT DISTINCT t1.uid, t2.value AS name, t3.value AS surname, t4.value AS country FROM table t1
LEFT JOIN table t2 on t2.uid = t1.uid AND t2.fid = 1
LEFT JOIN table t3 on t3.uid = t1.uid AND t3.fid = 2
LEFT JOIN table t4 on t4.uid = t1.uid AND t4.fid = 3;
It's a little complex, but you could do something like:
select distinct uid as uid,
(select value from dataTable as table1
where table1.uid=dataTable.uid and fid = 1) as name,
(select value from dataTable as table2
where table2.uid=dataTable.uid and fid = 2) as surname,
(select value from dataTable as table3
where table3.uid=dataTable.uid and fid = 3) as country
from dataTable group by uid
SQLFiddle