I've got those two tables:
Table a:
--- ID --- Name ---
Table b:
--- ID --- ID_of_a --- Date ---
Now I want to order the rows of table a by the Date (desc) of table b by the newest date.
Example:
Table a has rows with ID "1" and "2".
Table b has rows like this: {ID, ID_of_a, Date} {1, 1, "2013-06-30"}, {2, 1, "2013-07-01" }, {3, 2, "2013-07-02" }
The correct order of IDs from table a would be: 1 --- 2
Query:
SELECT DISTINCT a.ID, a.Name FROM a, b WHERE a.ID=b.ID_of_a ORDER BY b.Date desc
But this doesn't work sometimes.
Assuming there is a 1-1 relationship between the tables:
select a.*
from a left outer join
b
on a.id = b.id
order by b.date desc
If there are multiple rows in b for each a, then you need a group by:
select a.*
from a left outer join
b
on a.id = b.id
group by a.id
order by max(b.date) desc
How about
select a.name,a.id from a join (select id_of_a as id_a,max(dt) as max_dt from b group by id_of_a order by max_dt desc) e on e.id_a=a.id
Example
mysql> select * from a;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
+----+------+
2 rows in set (0.00 sec)
mysql> select * from b;
+----+---------+------------+
| id | id_of_a | dt |
+----+---------+------------+
| 1 | 1 | 2013-06-20 |
| 2 | 2 | 2013-07-01 |
| 3 | 1 | 2013-07-02 |
+----+---------+------------+
3 rows in set (0.00 sec)
mysql> select a.name,a.id from a join (select id_of_a as id_a,max(dt) as max_dt from b group by id_of_a order by max_dt desc) e on e.id_a=a.id;
+------+----+
| name | id |
+------+----+
| a | 1 |
| b | 2 |
+------+----+
2 rows in set (0.00 sec)
Basically you first select the maximum date for each id_of_a and then join it to a
I think it can be re-written to run more efficiently
Related
I am trying to form a mysql query where I want to concat all the previous values until the current row -1 . For example
select * from a;
+------+
| id |
+------+
| 1 |
| 3 |
| 4 |
+------+
Desired o/p
+------+============
| id |concat_prev_to_cur
+------+============
| 1 |null
| 3 |1
| 4 |1,3
+------+============
Can this be achieved with using SELECT only
Tried this but this doesn't work
with recursive b as (select id from a union all select concat(a.id,',',b.id) from b join a on a.id=b.id) select * from b;
Update: This seems to be close to the desired output
With b as (Select id, row_number() Over(order by id) r from a) select c.id,group_concat(b.id) from b join b c on b.r < c.r group by c.r ;
+------+--------------------+
| id | group_concat(b.id) |
+------+--------------------+
| 3 | 1 |
| 4 | 1,3 |
+------+--------------------+
Maybe a recursive query is not needed.
SELECT id, (
SELECT GROUP_CONCAT(id) AS ids
FROM a AS agg
WHERE agg.id < a.id
) AS ids
FROM a
db<>fiddle
What is the maximum number of rows from a left join from the below query?
select t1.tribe_name, t2.*
from tribe_master as t1
left join demography as t2
on t1.stc_code=t2.stc_code
In the above query table tribe_master has total 868 records
and table demography has 16924 records,
but the output of the query shows 14,899 records.
How is this possible.
Please explain.
Let's say we have two tables, A & B and both tables have each id of 1 & 2 like below. When you use A.id=B.id you'll get two matches:
Ex1:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 1 id UNION SELECT 2) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
| 2 | 2 |
+----+----+
*2 row(s);
If table A only have id 1 and table B have id 1 & 2, result will show only 1 match:
Ex2:
SELECT * FROM
(SELECT 1 id) A LEFT JOIN
(SELECT 1 id UNION SELECT 2) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
+----+----+
*1 row(s);
If table A have id 1 & 2 and table B only have id 1, you'll get 2 rows of result regardless of how many matching id there is. However in the id section from table B, you'll only get data for whatever matches and get NULL for non-matching data.
Ex3:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 1 id) B ON A.id=B.id;
+----+---------+
| id | id |
+----+---------+
| 1 | 1 |
| 2 | (NULL) |
+----+---------+
*2 row(s);
When you have id 1 & 2 in table A and duplicate id 2 in table B, you'll get 3 rows since id 2 from table A matches with two rows if id 2 data in table B. And of course, NULL for non-matching data.
Ex4:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 2 id UNION ALL SELECT 2) B ON A.id=B.id;
+----+---------+
| id | id |
+----+---------+
| 1 | (NULL) |
| 2 | 2 |
| 2 | 2 |
+----+---------+
*3 row(s);
Then the last test here showing both tables have two rows of duplicate id 1 which resulted in 4 total rows because each of the id 1 row in table A recognizes that there are two matching id in table B
Ex5:
SELECT * FROM
(SELECT 1 id UNION ALL SELECT 1) A LEFT JOIN
(SELECT 1 id UNION ALL SELECT 1) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
+----+----+
*4 row(s);
Yours probably have a few data in table tribe_master that don't exists in table demography and some repeated stc_code values in the demography. Something like Ex4 example above.
I have below mentioned table:
ID Val1
1 AVD1R
1 ART1R
2 CFD4E
3 DER1R
3 DER1F
I want to fetch those records where same ID is more than one time with different Val1.
Required Output:
ID Val1
1 AVD1R
1 ART1R
3 DER1R
3 DER1F
I have tried this:
select id, Val1 from Table1 where count(Val1)>1 group by id; But it didn't work.
Sorry, i have change my answer to:
SELECT t1.* FROM Table1 t1
INNER JOIN Table1 t2
ON t1.id=t2.id AND t1.VAl1 <> t2.Val1;
Sample
MariaDB [bernd]> select * from Table1;
+----+-------+
| id | VAl1 |
+----+-------+
| 1 | AVD1R |
| 1 | ART1R |
| 2 | CFD4E |
| 3 | DER1R |
| 3 | DER1F |
+----+-------+
5 rows in set (0.00 sec)
MariaDB [bernd]> SELECT t1.* FROM Table1 t1
-> INNER JOIN Table1 t2 ON t1.id=t2.id AND t1.VAl1 <> t2.Val1;
+----+-------+
| id | VAl1 |
+----+-------+
| 1 | ART1R |
| 1 | AVD1R |
| 3 | DER1F |
| 3 | DER1R |
+----+-------+
4 rows in set (0.00 sec)
MariaDB [bernd]>
SELECT a.* FROM (
SELECT ID, Val1, COUNT(*) AS Cn FROM Table1 GROUP BY ID, Val1) AS a
LEFT JOIN (
SELECT ID, COUNT(*) AS Cn FROM Table1 GROUP BY ID
) AS b ON a.ID = b.ID
WHERE a.Cn <> b.Cn
I don't know what are the others columns are.
But in SQL Server:
select distinct a.id,val1 from
(
select id,val1
from different
)a
inner join
(
select id,count(id) as cnt
from different
group by id
having count(*)>1
) b
on a.id=b.id
I have three tables:
mysql> select * from a;
+----+---------+
| ID | Name |
+----+---------+
| 1 | John |
| 2 | Alice |
+----+---------+
mysql> select * from b;
+------+------------+----------+
| UID | date | received |
+------+------------+----------+
| 1 | 2017-10-02 | 5 |
| 1 | 2017-09-30 | 1 |
| 1 | 2017-09-29 | 4 |
+------+------------+----------+
mysql> select * from c;
+------+------------+------+
| UID | date | sent |
+------+------------+------+
| 1 | 2017-09-25 | 7 |
| 1 | 2017-09-30 | 2 |
| 1 | 2017-09-29 | 3 |
+------+------------+------+
If I try to calculate the total number of sent for John, it would be 12. And for received, it would be 10.
But if I try to join all three tables, the result is weird. Here is my query to join three tables:
mysql> select sum(sent), sum(received) from a
-> join c on c.UID = a.ID
-> join b on b.UID = a.ID
-> where a.ID = 1;
+-----------+---------------+
| sum(sent) | sum(received) |
+-----------+---------------+
| 36 | 30 |
+-----------+---------------+
But I need correct numbers (12 and 10, respectively). How can I have correct numbers?
You should join the aggregated result and not the raw tables
select a.uid, t1.received, t2.sent
from a
inner join (
select uid, sum(received) received
from b
group by uid
) t1 on t1.uid = a.id
inner join (
select uid, sum(sent) sent
from c
group by uid
) t2 on t2.uid = a.id
where a.id = 1
You could try below
select bx.id, recieved, sum(c.sent) sent from
(
SELECT a.id, sum(b.received) recieved
from a
INNER JOIN b
ON a.id=b.uid
group by a.id
) bx
INNER JOIN c
ON c.uid=bx.id
group by bx.id, bx.recieved;
>>>Demo<<<
This gets rid of the subquery, but introduces something else you might not want:
( SELECT uid, 'Received' AS direction, SUM(received) AS HowMany
WHERE uid = 1
GROUP BY uid )
UNION ALL
( SELECT uid, 'Sent' AS direction, SUM(sent) AS HowMany
WHERE uid = 1
GROUP BY uid )
I have a users table with columns: user_id, teacher_id1, teacher_id2, teacher_id3
and
teachers table with id
Each user can have the same id's for teacher_id1, teacher_id2, teacher_id3
I would like to count how many users have same teacher.
User table
+----------------------------------------+
| user_Id teacher_id1 teacher_id2 teacher_id3 |
+----------------------------------------+
| 1 1 1 1 |
| 2 2 1 3 |
| 3 2 3 3 |
| 4 2 2 2 |
+----------------------------------------+
Teacher table
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
Count for $id1 is: 2
Count for $id2 is: 3
Count for $id3 is: 2
I tried something like this, but it is not correct!
SELECT COUNT(*) FROM users WHERE concat_ws('',teacher_id1 OR teacher_id2
OR teacher_id3) like '{$id}' ";
You have data in three different columns. You need to combine it into one column, to get the distinct counts that you want. For this, you can use union all. Then the count is simply count(distinct):
select teacher_id, COUNT(distinct USER_ID)
from ((select user_id, teacher_id1 as teacher_id
from t
) union all
(select user_id, teacher_id2
from t
) union all
(select user_id, teacher_id3
from t
)
) s
group by teacher_id;
Try this query
select b.id, count(*)
from
tbl1 a
inner join
tbl2 b
on b.id = teacher_id1 or b.id = teacher_id2 or b.id = teacher_id3
group by b.id
SQL FIDDLE:
| ID | COUNT(*) |
-----------------
| 1 | 2 |
| 2 | 3 |
| 3 | 2 |