Get missing id from table - mysql

I have tbl_profilecategory table structure like this:
Id col1
1 50
3 30
4 40
5 50
8 80
9 90
Now I want the missing IDs from table, so the result here should be like this:
Id= 2,6,7

You can use
SELECT t1.id - 1 AS missing_id
FROM mytable t1
LEFT JOIN mytable t2 ON t2.id = t1.id - 1
WHERE t2.id IS NULL

This answer is based here
SELECT a.id+1 AS start, MIN(b.id) - 1 AS end
FROM testtable AS a, testtable AS b
WHERE a.id < b.id
GROUP BY a.id
HAVING start < MIN(b.id)

Related

Using a nested query to get details of two tables

TABLE 1 TABLE 2
id name mob id course mark
1 joe 0000 1 English 77
2 john 0000 2 maths 89
I need to show the name of the person from table 1 who has the MAX(grade) in table 2 using a nested query.
SELECT t1.name
FROM t1
WHERE t1.id = t2.id = (
SELECT id
FROM t2
WHERE mark =
(
SELECT MAX(mark)
FROM t2
)
);
Well, this satisfies the brief ;-):
SELECT a.*
FROM table_a a
JOIN (SELECT * FROM table_b) b
ON b.id = a.id
ORDER
BY mark DESC
LIMIT 1;

Joining two tables on interval basis

In SQL, suppose that I have table A
ID
--
1
3
5
and table B
ID2
---
1
2
3
4
5
6
To get the result similar to:
ID | ID2
----------
1 | 1
1 | 2
3 | 3
3 | 4
5 | 5
5 | 6
For an explanation, an element in column ID2 will be mapped to the highest value in the column ID that is less than or equal to the said element in ID2.
For example, 4 in column ID2 is mapped to 3 from column ID, because 3 is the largest value in column ID which is less than or equal to 4.
Is it possible at all to do this in sql?
What I would do is start by joining the two tables on the condition that the id in the first table is less than or equal to that in the second table, like this:
SELECT t1.id, t2.id AS id2
FROM t1
JOIN t2 ON t2.id >= t1.id;
Once you have that, you can select the maximum id from the first table, and group by the id from the second table to get the largest pairs:
SELECT MAX(t1.id) AS id, t2.id AS id2
FROM t1
JOIN t2 ON t2.id >= t1.id
GROUP BY t2.id;
SQL Fiddle seems to be down but I will update with a link as soon as I can.
SELECT MAX(A.ID) ID, B.ID2
FROM A
INNER JOIN B ON B.ID2 >= A.ID
GROUP BY B.ID2
If you only need the matching ID column:
select b.*,
(select max(ID) from a where a.ID <= b.ID2) as a_Id
from b
If you need more columns:
select *
from a
join
(
select b.*,
(select max(ID) from a where a.ID <= b.ID2) as a_Id
from b
) as b
on a.Id = b.a_Id

How to join same table to check if a>b with 10

Table mytable
id numbers whereonly
1 2 1
2 35 1
3 22 1
4 20 1
5 3 1
6 70 1
7 80.15925 1
8 60 7
9 50 7
I need to order by numbers and to take id 1 to search until I found an id that have numbers row bigger with 10.
Desired result: 2, 20, 35, 70, 80.15925
Only where column whereonly is 1
Is there a way to do this?
You can give this a try:
SELECT DISTINCT t1.id AS id, t1.numbers AS numbers
FROM table AS t1
INNER JOIN table AS t2 ON t1.numbers > t2.numbers - 10
WHERE t1.whereonly = 1
GROUP BY t2.numbers
ORDER BY t1.numbers;
Here is the sqlfiddle.
Edit 1: As strawberry suggested
SELECT DISTINCT x.*
FROM mytable x
JOIN
( SELECT t2.numbers t2n
, MIN(t1.id) id
FROM mytable t1
JOIN mytable t2
ON t1.numbers > t2.numbers - 10
GROUP
BY t2.numbers
) y
ON y.id = x.id
ORDER BY x.numbers
WHERE x.whereonly = 1;
Here is the sqlfiddle.

Select rows from a table based on max value in different table

I'm looking for a MySQL query to extract values like in the following example:
TABLE1:
ID name
25 ab
24 abc
23 abcd
22 abcde
21 abcdef
TABLE2:
ID ID_TABLE1 total
1 25 0
2 25 1
3 25 2
4 25 3
5 23 1
6 22 0
7 22 1
8 21 0
9 21 2
10 24 10
11 24 7
I want to return all TABLE1 rows where max value of total column (in TABLE2) is < 3.
So the results should be:
ID name
23 abcd
22 abcde
21 abcdef
I tried this:
SELECT t1.*
FROM TABLE1 t1
INNER JOIN (
SELECT MAX( total ) AS max_total, ID_TABLE1
FROM TABLE2
GROUP BY total, ID_TABLE1
) t2
ON t1.ID = t2.ID_TABLE1
WHERE t2.max_total < 3
but it's not the result I want.
Try this:
SELECT t1.ID, t1.name
FROM TABLE1 t1
INNER JOIN (SELECT ID_TABLE1, MAX(total) AS max_total
FROM TABLE2
GROUP BY ID_TABLE1
) t2 ON t1.ID = t2.ID_TABLE1
WHERE t2.max_total < 3;
Your inner query groups the results by id_table and by total. Since the maximum of total per total is the value itself, it makes the inner query somewhat meaningless. Just remove the total from the group by clause and you should be OK:
SELECT t1.*
FROM TABLE1 t1
INNER JOIN (
SELECT MAX( total ) AS max_total, ID_TABLE1
FROM TABLE2
GROUP BY ID_TABLE1
) t2
ON t1.ID = t2.ID_TABLE1
WHERE t2.max_total < 3
SELECT t1.*
FROM TABLE1 t1
INNER JOIN (
SELECT MAX( total ) AS max_total, ID_TABLE1
FROM TABLE2
GROUP BY ID_TABLE1
having t2.max_total < 3
) t2
ON t1.ID = t2.ID_TABLE1
Here is a way to do using left join without using any subquery and group by clauses.
select t1.* from table1 t1
join table2 t2
on t1.id = t2.id_table1
left join table2 t3 on
t2.id_table1 = t3.id_table1
and t2.total < t3.total
where t3.id is null
and t2.total < 3
Another way is
select t1.* from table1 t1
join table2 t2 on t1.id = t2.id_table1
where not exists(
select 1 from table2 t3
where t2.id_table1 = t3.id_table1
and t2.total < t3.total
)
and t2.total < 3;
SELECT t1.*
FROM TABLE1 t1
INNER JOIN (
SELECT MAX( total ) AS max_total, ID_TABLE1
FROM TABLE2
where total > 3 GROUP BY total, ID_TABLE1
) t2
ON t1.ID != t2.ID_TABLE1
There's a simpler way without using GROUP or MAX:
SELECT * FROM table1
WHERE id NOT IN (
SELECT id_table1 FROM table2 WHERE total >= 3
);
The subquery selects all rows in table2 that have a total >= 3. Then we select those rows from table1 that are not in the subquery result.

how is this query done in mysql?

Given the following table ...
ID USER NUM
1 1 69
2 2 75
3 3 7
4 1 31
5 2 18
6 3 70
7 1 12
8 2 23
9 3 42
... which query would return rows with the lowest NUM for each USER?
The result should look like ...
ID USER NUM
7 1 12
5 2 18
3 3 7
Can't wrap my head around this one! Assuming it has a GROUP BY, but everything I try fails... Any pointers?
SELECT t.*
FROM tablename t
INNER JOIN (SELECT user, MIN(num) num
FROM tablename
GROUP BY user) x ON t.user = x.user AND t.num = x.num
or
SELECT t1.*
FROM tablename t1
LEFT JOIN tablename t2 ON t1.user = t2.user AND t1.num > t2.num
WHERE t2.id IS NULL
SELECT ID , MIN(NUM) as MIN_NUM , USER FROM usertable GROUP BY USER
Have a look at demo http://sqlfiddle.com/#!2/ce2fd/1
HEre is another method. UPDATED WITH THE CORRECT REREFERENCE
SQLFIDDLE
Query
select b.id, a.user, a.minnum from
mytable as b
join
(select user, min(num) as minnum
from mytable
group by user
) as a
on b.user = a.user
where b.num = a.minnum
order by a.minnum asc
limit 3
;
Results:
ID USER MINNUM
3 3 7
7 1 12
5 2 18