I want to create a limit of 6 rows with this logic:
Select user_id's that are in the friends list (and also in the same table)
if there are less that 6, select then another RANDOM users,but not in friends list (until limit of 6)
if there are not 6 user_id's, add some "dummy" users id (with id 0)
all "real" users must be distinct (with id > 0)
id | friends_list | name
1 2,3,5 John
2 1,7,9 Michael
3 1,2,5 Tom
4 3,2,6 Larry
The expected result must be something like this (for a given user e.g. id=1):
2, 3, 4, 0, 0, 0
You should probably store your data differently and use joins to select the data out of multiple tables. There are also other ways you might think about storing data also depending on your use cases.
PEOPLE TABLE
id | name
1 | John
2 | Michael
3 | Tom
4 | Larry
PEOPLE_FRIENDS TABLE
id | person_id | friend_id
1 | 1 | 2 //In this case John is friends with Michael
2 | 3 | 1 //In this case Tom is friends with John.
The following select would pull id's for John's friends.
SELECT * FROM PEOPLE `P` INNER JOIN PEOPLE_FRIENDS `PF` ON P.id = P.person_id WHERE P.id = 1
Again a million different ways to go about writing that query as well, but this will get you pointed in the right direction I think.
Related
I want to check rows where uid equal both 1 and 2 and if they do, return cid. In this example there will only ever be 2, but if you know a way to return the CID for more than 2, that would be great too.
How can I most easily get the value where cid = 5 when I know both uid values? (1,2).
cid | uid |
------------
5 | 1 |
5 | 2 |
6 | 1 |
6 | 3 |
7 | 1 |
7 | 4 |
For pseudo sql, I am thinking something like SELECT cid WHERE uid = 1 or uid = 2
This returns all rows where uid has a 1 or a 2. How can I limit to an OR statement and an AND?
SELECT cid WHERE uid = 1 AND uid = 2 (but in multiple rows)
Any ideas?
As far as i understand you're looking for a way to apply a condition to multiple rows, a way to do that is through agrupation functions. try this:
Select CID
from YourTable where uid IN (1,2)
group by cid
having count(uid) = 2
in this example i'm using IN instead of two OR and i'm grouping the rows by CID, and after that i'm limiting the results to those rows that match with UID equals to 1 and 2.
There are many tricky ways of achieve the same result, for example you can also do something like:
Select CID
from YourTable where uid IN (1,2)
group by cid
having sum(uid) = 3
in this example i'm suming the UID column, if UID is 1 and 2 the sum of both will result on 3, I assume that you can't have 3 rows with the UID 1 and the same CID
According to given details, Try this. Let's say you have a table called docs;
SELECT d1.cid
FROM docs AS d1
LEFT JOIN docs AS d2 ON d1.cid = d2.cid
WHERE d1.uid = 1
AND d2.uid = 2
I am not very good at sql but I am getting there. I have searched stackoverflow but I can't seem to find the solution and I hope someone out there can help me. I have a table (users) with data like the following. The book_id column is a key to another table that contains a book the user is subscribed to.
|--------|---------------------|------------------|
| id | book_id | name |
|--------|---------------------|------------------|
| 1 | 1 | jim |
| 2 | 1 | joyce |
| 3 | 1 | mike |
| 4 | 1 | eleven |
| 5 | 2 | max |
| 6 | 2 | dustin |
| 7 | 2 | lucas |
|--------|---------------------|------------------|
I have a function in my PHP code that returns two random users from a specific book id (either 1 or 2). Query one returns the result in column 1 and result two returns the results in column 2 like:
|---------------------|------------------|
| 1 | 2 |
|---------------------|------------------|
| jim | max |
| joyce | dustin |
|---------------------|------------------|
I have achieved this by running two separate queries as seen below. I want to know if it's possible to achieve this functionality with one query and how.
$random_users_with_book_id_1 = SELECT name FROM users WHERE book_id=1 LIMIT 2
$random_users_with_book_id_2 = SELECT name FROM users WHERE book_id=2 LIMIT 2
Again, I apologise if it's too specific. The query below has been closest to what I was trying to achieve.:
SELECT a.name AS book_id_1, b.name AS book_id_2
FROM users a, users b
WHERE a.book_id=1 AND b.book_id = 2
LIMIT 2
EDIT: I have created a fiddle to play around with his. I appreciate any help! Thank you!! http://sqlfiddle.com/#!9/7fcbca/1
It is easy actually :)
you can use UNION like this:
SELECT * FROM (
(SELECT * FROM user WHERE n_id=1 LIMIT 2)
UNION
(SELECT * FROM user WHERE n_id=2 LIMIT 2))
collection;
if you read this article about the documentation you can use the () to group the individual queries and the apply the union in the middle. Without the parenthesis it would still LIMIT 2 and show only the two first. Ref. "To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:"
If you want to combine the queries in MySQL, you can just use parentheses:
(SELECT name
FROM users
WHERE n_id = 1
LIMIT 2
) UNION ALL
(SELECT name
FROM users
WHERE n_id = 2
LIMIT 2
);
First, only use UNION if you specifically want to incur the overhead of removing duplicates. Otherwise, use UNION ALL.
Second, this does not return random rows. This returns arbitrary rows. In many cases, this might be two rows near the beginning of the data. If you want random rows, then use ORDER BY rand():
(SELECT name
FROM users
WHERE n_id = 1
ORDER by rand()
LIMIT 2
) UNION ALL
(SELECT name
FROM users
WHERE n_id = 2
ORDER BY rand()
LIMIT 2
);
There are other methods that are more efficient, but this should be fine for up to a few thousand rows.
Sorry if my question sounds misleading, I'm not fully sure how to formulate it.
Consider the following tables: Fruit which has an ID and Name, Person which also has an ID and Name, and Person_has_Fruit (many to many linking table) which has a Person_ID and a Fruit_ID.
What transaction can retrieve the people which have two or more specific fruits? Basically how can I intersect the results?
Example:
Fruit table
ID | Name
-----------------
1 | Apple
2 | Pineapple
3 | Banana
4 | Lemon
Person table
ID | Name
-----------------
1 | Tom
2 | Bill
3 | John
Many to many table
PersonID | FruitID
-----------------
3 | 1
1 | 2
3 | 2
2 | 3
3 | 3
I want a query to retrieve me John when I ask for the person which has Apple, Pineapple and Banana. Any suggestions?
I've tried 'SELECT * FROM Person_has_Fruit WHERE FruitID in ('1', '2', '3')' but that is incorrect as it retrieves all the person IDs which have one of them, so basically it implies an or relationship between the values.
You are looking to perform a relational division between the some tuples of Fruit table and the Person table.
So:
Select * From Person p
Where Not Exists ( Select * from Fruit f
Where (Name = 'Apple' Or Name = 'Pinneapple' or Name = 'Banana')
And Not Exists ( Select * from Person_has_Fruit pf
Where pf.PersonId = p.ID and pf.FruitId=f.ID))
Try create a view first.
CREATE VIEW fruitowners AS
( SELECT personfruit.personID, fruittable.id, persontable.person, fruittable.fruit
FROM persontable, fruittable, personfruit
WHERE personfruit.personID=persontable.id AND personfruit.fruitID=fruittable.id )
Then:
SELECT fruit FROM fruitowners
WHERE person='John'
returns all the fruit types John owns
And:
SELECT person FROM fruitowners
WHERE fruit='Banana'
returns all the banana owners.
And:
SELECT COUNT(*) FROM fruitowners WHERE person='John'
returns the number of fruits John owns
And:
SELECT COUNT('fruit') FROM fruitowners WHERE person='John' and fruit='Banana'
returns how many bananas John owns
I have these 2 tables: users and friendship. i would like find the friends in common between two user, i tried to do some query with alias but doesn't show my results.
Table users
user_id | name | surname
1 Luca Jhon
2 Paul Red
3 Jin Blue
4 Diana Lars
Table friendship
id_friendship | id_user_sender | id_user_receive | confirm
1 1 2 2
2 2 3 2
3 1 3 2
4 1 5 2
Should be show this one if i am the user called Luca (id 1 ) and search the realtion with Paul (id 2)
name | surname | id_user |
Jin Blue 3
Any idea? Thank you
Friendship is, presumably, reciprocal. Your friendship table only has one-way relationships.
So, the idea is to create all possible friendships in both directions. Then to aggregate by the first and test the second for each of the users you are interested in:
select u.*
from (select id_user_sender as id1, id_user_receive as id2
from frienship f
union all
select id_user_receive as id1, id_user_send as id2
from frienship f
) f join
users u
on f.id1 = u.user_id
group by id1
having max(id2 = 1) > 0 and
max(id2 = 2) > 0;
given the following table (describing a many-to-many relation):
ID | PageID | TagID
--------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
4 | 2 | 3
how do i select 'all PageIDs having all of a list of TagIDs'?
in other words: i want all pages tagged with TagIDs 1 and 2 (so it's only PageID 1 in this example)
after some googling i found the term 'relational division' which might be relevant here, but i didn't quite get it. anyone having a simple query for my problem?
If you have the list of tagids in a table, then it is a simple join and group by:
select pageId
from t join
list l
on t.tagId = l.tagId cross join
(select count(*) cnt from list l) as const
group by pageId
having count(*) = max(cnt)
The having clause checks that all tags are present. If there might be duplicates, then you would want to replace the "count(*)" with "count(distinct tagid)" in both cases.