Selecting data from a table based on data from two others SQL - php

I have 3 tables: users, games and players. For simplicity's sake, I will say that the tables look like this:
users
id int AUTO_INCREMENT,
PRIMARY KEY (id)
games
id int AUTO_INCREMENT,
PRIMARY KEY (id)
players
game_id int,
user_id int,
FOREIGN KEY (game_id) REFERENCES (games.id),
FOREIGN KEY (user_id) REFERENCES (users.id)
I need to select users.id where players.game_id is 1
so far I have tried
SELECT users.id FROM users, game_users WHERE players.id = 1
and also some SELECT statements with INNER JOINs but to no avail.

if only need user_id don't need JOIN just
SELECT user_id
FROM players
WHERE game_id =1
Now if you need the names a single JOIN will work
SELECT users.name
FROM players
JOIN users
ON player.user_id = users.id
WHERE game_id =1

you must have a join key to join users and games. as
...WHERE game_users.id = 1 AND users.id=game_users.id
And you don't have a table called game_users

Related

How can i combine two selects from two tables?

This is my DB schema:
CREATE TABLE `members` (
`m_id` int NOT NULL AUTO_INCREMENT,
`m_name` varchar(355),
`m_email` varchar(20) UNIQUE,
PRIMARY KEY (`m_id`)
);
CREATE TABLE `schools` (
`s_id` int NOT NULL AUTO_INCREMENT,
`s_name` varchar(355)
);
CREATE TABLE `schools_members` (
`sm_id` int NOT NULL AUTO_INCREMENT,
`sm_school_id` int NOT NULL,
`sm_member_id` int NOT NULL,
FOREIGN KEY (sm_school_id) REFERENCES schools(s_id),
FOREIGN KEY (sm_member_id) REFERENCES members(m_id)
);
I need to display all members for a selected school by a given school id ($schoolId). So i assume that the query will touch on schools_members and members.
I believe the logic is: select all the sm_member_id where sm_school_id = $schoolId from table schools_members and then SELECT m_name and
m_email for each m_id (member id) from table members that is IN the last query result.
This is not required, but now im curious if i want to join to this result the s_name (school name) from table schools so that each member displays the name of school also?
You could just use a join between schools_members and members
select m.m_name, m.m_email
from schools_members sm
inner join members m ON m.m_id = sm.sm_member_id
where sm.sm_school_id = Your_value
and for school name
select m.m_name, m.m_email, s.s_name
from schools_members sm
inner join members m ON m.m_id = sm.sm_member_id
inner join schools s on s.s_id = sm.sm_school_id
where sm.sm_school_id = Your_value

Display posts from followers and logged-in user

I want to display posts from the users being followed and the logged in user using a single PHP mysql query.
I have three tables:
- Users (id, name, password)
- Posts (id, body, date, user_id)
- Followers (id, user_id, follower_id)
followers.follower_id = person who does the following
followers.user_id = person who is being followed
$_SESSION['id'] = id of the logged in user
DB::query('
SELECT users.name, posts.body
FROM users, posts, followers
WHERE posts.user_id = followers.user_id
AND users.id = posts.user_id
AND followers.follower_id = :userid',
array(':userid'=>$_SESSION['id'])
);
But the query only shows posts from the users being followed, not from the logged in user. How do I fix this?
I have already created a relation between the posts table and the users table.
CREATE TABLE `posts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`body` varchar(160) NOT NULL DEFAULT '',
`user_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `posts_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
You need to include 2 criteria in your WHERE clause: Either the creator of the post matches your :userid variable, or the follower matches your :userid.
Please use current join syntax: This makes your query a lot easier to read.
Your final query should be something like this (I'm excluding the PHP part):
SELECT users.name, posts.body
FROM posts
INNER JOIN users ON
users.id = Posts.user_id
-- use left join to handle when a
-- user has no followers
LEFT JOIN Followers ON
Followers.user_id = users.user_id
WHERE
users.id = :userid
OR followers.follower_id = :userid

Set random values from an array into database

I'm working on a PHP project with MYSQL database. I have a table of groups of students. Each group has an examiner. What i want to do is that i want to set two examiners for each group randomly. How to do it?
MySQL Code:
create table groups (
groupID int(10) not null,
nbStudents int not null,
avgGPA DOUBLE NOT NULL,
projectName varchar(50) not null,
advisorID int,
examiner1ID int,
examiner2ID int,
adminID int not null,
primary key (groupID)
);
create table faculty (
name varchar(30) not null,
facultyID int(10) not null,
email varchar(30) not null,
mobile int(15) not null,
primary key (facultyID)
);
examiner1ID and examiner2ID are foreign keys from the table faculty.
Here is a very convoluted way to do it. It uses 2 subqueries to pick faculty members, and insert .. on duplicate key to update the examiners IDs.
insert into groups
(groupID, examiner1ID, examiner2ID)
select groupID,
#x:=(select facultyID from faculty order by rand() limit 1),
(select facultyID from faculty where facultyID <> #x order by rand() limit 1)
from groups
on duplicate key update examiner1ID=values(examiner1ID), examiner2ID=values(examiner2ID);
#x is a user-defined-variable. In this case, it is used to store the first random faculty member. <> #x makes sure we don't pick the same faculty member in both slots.
Since groupID is a unique key, when we try to insert a row with an existing unique key, it will update the existing row instead of inserting it. That's what on duplicate key update clause is used for.
set different examiners for each group:
insert into groups
(groupID, examier1ID, examier2ID)
select a.groupID, max(if(b.id%2, b.facultyID, 0)), max(if(b.id%2, 0, b.facultyID))
from (
select #row:=#row+1 id, groupID
from groups a
join (select #row:=0) b) a
join (
select #row:=#row+1 id, facultyID
from (
select facultyID
from faculty a
order by rand()) a
join (select #row:=0) b) b on a.id = ceil(b.id/2)
group by a.groupID
on duplicate key update examiner1ID=values(examiner1ID), examiner2ID=values(examiner2ID);

Joining 2 tables with foreign key id

i have a 2 category system, basically what i want to do is i have 2 tables, top_category and bottom_category, i have created my sidebar which will list all the products using sql query. is there a way i can pull the top_category and bottom_category data in one sql query and have the bottom_category sorted by the foreign key id of top_category so when i loop them in a list they end up in the right nest?
Here are my tables,
CREATE TABLE top_category (
id INT PRIMARY KEY,
NAME VARCHAR(100)
);
CREATE TABLE bottom_category (
id INT PRIMARY KEY,
NAME VARCHAR(100) ,
top_category_id INT REFERENCES top_category
);
And here is my products table, so when i click on a bottom_category link i want it to list the products linked to the bottom_category_id's:
create table product (
id int primary key,
name varchar(100) ,
bottom_category_id int references bottom_category
);
You could write something like
SELECT product.*, bottom_category.name, top_category.name
FROM product
LEFT JOIN bottom_category ON bottom_category.id = product.bottom_category_id
LEFT JOIN top_category ON top_category.id = bottom_category.top_category_id
ORDER BY top_category.id,bottom_category.id
But if you have really big tables then just forget about 3nd normal form and add names for categories into product table. But only if you have really big tables with categories.
UPD
Add ORDER BY
select p.*,
bc.name bc_name,
tc.name tc_name
from product p
left join bottom_category bc on p.bottom_category_id=bc.id
left join top_category tc on bc.top_category_id=tc.id
order by tc.id,bc.id

How can I join in data from a key : value meta table in mysql?

Say I have three tables in my database:
CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR(16) NOT NULL
);
CREATE TABLE `users_meta` (
`meta_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`key` VARCHAR(200) NOT NULL ,
`value` TEXT NOT NULL
);
CREATE TABLE `posts` (
`post_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`content` TEXT NOT NULL
);
The table users_meta is just a key-value store of information about users, such that we can add any piece of information we want.
Say I added a key => value pair to the users_meta table for each user where the key was "age", and the value was a number representing their age.
Given this set of circumstances, what's the best way to select the first 10 posts ordered by user age?
I like putting the condition of the join in the join itself to be clear that I want a limited join:
SELECT p.post_id, p.content
FROM users u
INNER JOIN users_meta um
ON (u.user_id = um.user_id) AND um.key = 'age'
INNER JOIN posts p
ON (p.user_id = u.user_id)
ORDER BY um.value
limit 10
If you order by user age only, you will select 10 posts of the same user (the youngest one).
I would suggest to denormalize and store age in users table directly.
Agree with #KOHb, but if that's exactly what you want, here is the query:
SELECT TOP 10 p.id, p.content
FROM users u JOIN users_meta um ON (u.user_id = um.user_id)
JOIN posts p ON (p.user_id = u.user_id)
WHERE um.key = 'age'
ORDER BY um.value

Categories