set different limit on each tables in SQL - mysql

I am trying fetch each user's info and user's number from PHP database. So, the problem is that sometimes user adds more than 1 number. HERE is tables and SQL:
users table
id user_name email
1 John john#gmail.com
2 David david#gmail.com
numbers table
id user_id number number_prefix
1 1 3144425 123
2 1 5484248 123
3 1 3144425 325
4 2 5991599 123
As you see, 1st user's have 3 number.
Here is my sql:
SELECT
u.*,
n.*
FROM
users u,
numbers n
WHERE
u.id = n.user_id AND
u.id = 1
OF course it will work. I want to set different LIMIT for each tables. I mean to set LIMIT 1 for table: users, and set LIMIT 3 for table: numbers
To do it, I used another sql, like below:
SELECT *,
(
SELECT
number
FROM
menu
WHERE
user_id = 1
ORDER BY id
LIMIT 0,3) AS number
FROM users
WHERE id = 1
ORDER BY id
LIMIT 0,1
As you know sub query can not return more than 1 row Maybe, IT should be better TO use SQL JOIN and GROUP BY... I have tried, but was not any good result...

Use the subqueries in a join, then it can return multiple rows.
SELECT *
FROM (SELECT number
FROM menu
WHERE user_id = 1
ORDER BY id
LIMIT 3) AS number,
JOIN (SELECT *
FROM users
WHERE id = 1
LIMIT 1) AS users

SELECT *
FROM (SELECT * FROM users LIMIT 1) AS us , numbers ns
WHERE us.id = '1' LIMIT 3;

Related

Get the next max(id)

I've got the following table:
booking_id
user_id
11
1
12
76
13
932
14
1
15
626
16
1
17
3232
I want to access the 2nd maximum booking_id for user 1.
The expected result is user_id = 1, booking_id = 14.
I've been working over these hellish flames for way too long, this doesn't do any good:
select booking.user_id, b1.booking_id from booking
left join(select
user_id,
booking_id
from booking
where booking_id = (select
max(booking_id)
from booking
where booking_id <> (select
max(booking_id)
from booking))
group by user_id)
as b1 on b1.user_id = booking.user_id
where booking.user_id = '1'
Please note I've managed to do it as a calculated column but that's useless, I need the derived table.
If you are using MySQL, you can avoid the (rather messy) double sub-query by using LIMIT & OFFSET
Just add order by booking_id desc LIMIT 1 OFFSET 1 and you will get the second highest booking_id. For example ...
select * from booking where user_id = 1 order by booking_id desc OFFSET 1 LIMIT 1
I tested this on one of my tables & it worked fine. If you have an index on booking_id it should be really fast.
If you want the second highest booking for the user who holds the highest booking, then this should work
SELECT * FROM booking
WHERE user_id in
(select user_id from booking order by booking_id desc limit 1)
ORDER BY booking_id DESC LIMIT 1 OFFSET 1
The sub-query finds the user_id of the user with the highest booking, then the main query finds their second highest booking
A simple way to do it is using LIMIT OFFSET:
SELECT *
FROM booking
WHERE user_id = 1
ORDER BY booking_id DESC
LIMIT 1 OFFSET 1
Demo here
By using the answer in this question What is the simplest SQL Query to find the second largest value? https://stackoverflow.com/a/7362165/14491685
you can integrate with your query to get it like this:
select * from booking
where booking_id =
(select max(booking_id) from booking
where user_id =1
and booking_id not in (SELECT MAX(booking_id ) FROM booking ))

Query to get top 2 and 3 rd Records from a Table

I have a table list of Student:
Student SECTION
student1 A
student2 A
student3 A
student4 A
student5 B
student6 B
student7 B
student8 B
I want to get total Randomly 5 Students
3 A Section Students and
2 B Section Students
Done any once a Suggest a Simple SQL Query
Example : I want to club the below queries Randomly
select * from student where SECTION='A' LIMIT 3
select * from student where SECTION='B' LIMIT 2
You are pretty close:
(select * from student where SECTION = 'A' order by rand() LIMIT 3
) union all
(select * from student where SECTION = 'B' order by rand() LIMIT 2
)
order by rand();
The subqueries use order by rand() to get random students with each grade. The outer order by rand() randomizes the five students.
Note: This is the simplest way to accomplish what you want. If the students table is even moderately large and performance is an issue, there are alternative solutions.
You can use UNION along order by like
(select * from student where SECTION='A' ORDER BY RAND() LIMIT 3)
UNION
(select * from student where SECTION='B' ORDER BY RAND() LIMIT 2)

Advanced mysql query which sort down specific records on result set irrespective of its default sorting?

I have a query which actually have a sorting using order by clause. i have a table like following...
user_id user_name user_age user_state user_points
1 Rakul 30 CA 56
2 Naydee 29 NY 144
3 Jeet 40 NJ 43
.....
i have following query...
select * from users where user_state = 'NY' order by user_points desc limit 50;
This gives me the list of 50 people with most points. I wanted to give least preference to few people who's id's were known. Incase if i do not have enough 50 records then those id's should come in the last in the list. I do not want the users 2 and 3 to come on top of the list even though they have higher points... those people should come on the last of the list from the query. Is there any way to push specific records to last on result set irrespective of query sorting ?
If you want to move specific records (like user_id = 2 and 3) down to the list; Then you can run below Query:
mysql> select *,IF(user_id=2 or user_id=3,0,1) as list_order from users where user_state = 'NY' order by list_order desc, user_points desc limit 50;
select * from (
select *
from users
where user_state = 'NY'
-- this order by ensures that 2 and 3 are included
order by case when user_id in (2,3) then 1 else 2 end, user_points desc
limit 50
) as top48plus2n3
-- this order by ensures that 2 and 3 are last
order by case when user_id in (2,3) then 2 else 1 end, user_points desc
Edit: changed id by user_id and corrected outside order by (sorry about that)
On the inner select:
By using this case calculation, what you do is ensuring that records with ids equal to 2 and 3 are "important" (firstly ordered in the order by). Those receive 1 while the others receive 2 as order value, only after that points are relevant.
On the outer select:
Records with ids 2 and 3 recieve 2 as order value, while the rest recieve 1. So they go last irrespective of its "default"
Here you have a reduced fiddle http://sqlfiddle.com/#!9/377c1/1

MYSQL query to select from multiple tables, order by date, different table structures

I'm making a newsfeed type of thing and I want to select from multiple tables. The two tables I'll focus on for this question are "posts" and "photos".
Here's my query for just posts:
mysql_query("
SELECT * FROM posts
WHERE toID='$id' AND state='0'
ORDER BY id DESC LIMIT 10");
My posts table has the following column names:
Table: posts
id toID fromID post state date
1 1 1 Aloha 0 1
2 1 1 Hello 0 3
My photos table has the following:
Table: photos
id userID photo state date
1 1 2 0 2
2 1 6 0 4
Expected result:
Aloha
2
Hello
6
Maybe something like:
SELECT *
(SELECT * FROM posts WHERE toID=$id AND state=0) AND
(SELECT * FROM photos WHERE userID=$id AND state=0)
ORDER BY date
When it selects these from the database it should select from where toID and userID are the same. state should equal 0 for both, (0 means visible) and they should be ordered by date. Also I need to create a new variable to pass to my query, so I can then in my php determine which table the information is coming from. Lastly I would like it to group the photos by date, so let's say a user uploaded 20 photos within a 30 minute period, they will only return one row. I use php time() to store my date.
If you want to get all posts and photos together you could use:
SELECT po.*, ph.* FROM posts po
LEFT JOIN photos ph
ON po.toID = ph.userID
WHERE po.state = 0
AND ph.state = 0
ORDER BY po.id DESC, ph.date DESC

mysql query to select one specific row and another random row

I want to display two records.
For eg
select * FROM users WHERE user_id = 5.
Now i want another row randomly selected from users table but with user_id != 5
Is it possible to do in a single query. I tried using union all but i dnt get two distinct rows.
Thanks
This works fine for me. The first result is always the record with ID 5, the second row is a random one. Note that if no record with the ID 5 exists, both rows will be random.
SELECT * FROM users ORDER BY (user_id = 5) DESC, RAND() LIMIT 0,2
Try this
SELECT * FROM users WHERE user_id = 5 || user_id != 5 ORDER BY RAND() LIMIT 2
Union should do the trick. You probably forgot LIMIT.
(SELECT * FROM users WHERE user_id = 5 LIMIT 1)
UNION
(SELECT * FROM users WHERE user_id != 5 LIMIT 1)
Try this:
SELECT * FROM users WHERE user_id=5
union all (
SELECT * FROM users WHERE user_id!=5
ORDER BY RAND() LIMIT 0,1)