Consider a group table and member-group relationship table as
CREATE TABLE group (
group_id int(11) not null auto_increment,
title varchar(50),
status ENUM('private', 'public'),
PRIMARY KEY(group_id)
);
CREATE TABLE group_map (
group_map_id int(11) not null auto_increment,
group_id int(11) REFERENCES group(group_id),
user_id int(11) REFERENCES user(user_id),
PRIMARY KEY(group_map_id)
);
Now in the group page, how can I show the content if
1. Group is public
OR
2. user is member of that group (user_id comes from $_SESSION login,
and we check if the current group_id && user_id exists in group_map table).
Here's how to retrieve a list of all groups that user 1 can access, complete with group name:
SELECT g.group_id, g.name
FROM `group` g
LEFT JOIN group_map gm
ON gm.group_id = g.group_id
WHERE g.status = 'public'
OR gm.user_id = 1
Here's an alternative, using UNION.
(SELECT g.group_id, g.name
FROM `group` g
WHERE g.status = 'public')
UNION
(SELECT g.group_id, g.name
FROM `group` g
JOIN group_map gm
ON gm.group_id = g.group_id
WHERE gm.user_id = 1)
They them both out for size.
Notice the backticks around the group tablename because GROUP is a reserved word in MySQL.
You should try this...
SELECT g.*,gm.* FROM group g INNER JOIN group_map gm ON g.`group_id` = gm.`group_id`
First, if I understand right what you want, you don't need 2-nd table. You can use Users table.
If group is private I was doin it that way
SELECT tblGroups.*, tblUsers.*
FROM `tblGroups`, `tblUsers`
WHERE tblGroups.id=tblUsers.group AND // here you put what you need to open //
otherwise group is public just this
SELECT tblGroups.*
FROM `tblGroups`
WHERE // here you put what you need to open //
Related
So I am very bad at this anyway right now I have this code
$test = "SELECT `status`,`pubdate` FROM `status` ORDER BY `pubdate` DESC";
$stmt = $db->prepare($test);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
echo "<section class='statusar'>"."<article>";
echo $row['status'];
echo $row['pubdate'];
echo "</article></section>";
}
and it shows the post but now I want to take users first name from another table and display it with the post. How do I do it?
The two tables I have look like this
This is the table with the post
Status_id int unsigned auto_increment primary
user_id int unsigned index
status varchar(600)
pubdate datetime
This is the other table
user_id int unsigned auto_increment primary index
firstname varchar(30)
surname varchar(30)
username varchar(30) unique
password varchar(90)
I have done so they have a relation between the user_ids
EDIT
I think I figured it out because now it works :D
So now when I use
SELECT status, pubdate,firstname,surname FROM status INNER JOIN user ON status.user_id = user.user_id ORDER BY status.pubdate DESC
It displays all the things I want and I also tried
SELECT * FROM status INNER JOIN user ON status.user_id = user.user_id ORDER BY status.pubdate DESC";
Which also works thanks for the help guys :D
Just use an inner join:
SELECT s.status, s.pubdate, u.firstname
FROM status s
INNER JOIN usertable u ON s.user_id = u.user_id
ORDER BY s.pubdate DESC
A Visual Explanation of SQL Joins
This assumes the user_id exists in the usertable. If that might not be the case, you'd want to use an outer join instead.
I have two tables; What I need to do is select comments of a given user. I need cid and heading as results
posts
pid | heading | body | username
1 smth.... smth.. u1
2 smth.... smth.. u2
posts
cid | body | username
1 smth.. u1
2 smth.. u2
I have tried to use JOINS, mostly INNER . But the answer was wrong. Then I tried with a sub query again answers are wrong, but this time its a different answer than before. Now I'm trying to use INNER JOINS with a sub query together. I don't know if thats possible or not.
Some SQL that I have tried; I won't post all since there are too many things I tried.
SELECT `comment_id`, `post`.`post_id`, `friendly_url`, `heading` FROM `post`,`comments` WHERE `post`.`post_id` IN (SELECT `comments`.`post_id` FROM `comments` WHERE `username` = ?)
SELECT `post`.`post_id`, `friendly_url`, `heading` FROM `post`INNER JOIN `comments` ON `post`.`post_id`= `comments`.`post_id` WHERE `post`.`post_id` IN (SELECT `comments`.`post_id` FROM `comments` WHERE `username` = 'chichi')
Per your posted query it looks like there is a relation exists b/w the tables
`post`.`post_id` = `comments`.`post_id`
So you can try using a INNER JOIN like
SELECT c.`comment_id`, p.`post_id`, c.`friendly_url`, c.`heading`
FROM `post` p JOIN `comments` c ON p.`post_id` = c.`post_id`
WHERE `username` = 'u1'
Im making a codeigniter webapp where users can add each other in a contactslist.
The table looks like this:
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_1` int(11) NOT NULL,
`user_2` int(11) NOT NULL,
`accepted` tinyint(2) NOT NULL,
PRIMARY KEY (`id`)
The userid for the user that makes the request to add the contact is always stored in user_1 column. The other users userid is stored in user_2. user_2 then has to accept the request and the 'accepted' column gets updated to 1.
I want to list all contacts that are accepted (WHERE accepted = 1) in a html table, and the contact requests (accepted = 0) in another.
My question is: How can i make a mysql query that selects all the rows and just get the userid from the contact? Its a problem since they can be in either user_1 or user_2 (Depending on if they requested or accepted).
Should i change the db table in some way to achieve this. Or could i make a query (active rcords preferably) that accomplish this?
Any help is appreciated
Thanks in advance
George
Update:
So the final query looks like this:
SELECT DISTINCT users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_1
WHERE contacts.user_2 = ' . $this->session->userdata('user_id') . '
UNION DISTINCT
SELECT DISTINCT users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_2
WHERE user_1 = ' . $this->session->userdata('user_id')
And works exactly as i described :)
Use a UNION query. See the documentation.
SELECT DISTINCT user_1 userid FROM user WHERE accepted = 1
UNION DISTINCT
SELECT DISTINCT user_2 userid FROM user WHERE accepted = 1
About the join, you'd use something like below for each part of the UNION
SELECT DISTINCT users.userid, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.userid = contacts.user_1
WHERE contacts.user_2 = ?
Shouldn't the contactlist be owned by the user?
create table Contactlist (
OwnerID int, -- ID of the owning User
ContactID int, -- ID of the contact User
Accepted bool)
-- With composite primary key on OwnerID, ContactID
This way the query would be
select * from User
left outer join Contactlist on User.ID = Contactlist.OwnerID
left outer join User as Contact on Contactlist.ContactID = Contact.ID
Sorry... Overthunk the select ;)
select * from Contactlist
inner join User on Contactlist.ContactID = User.ID
where Contactlist.OwnerID = <the querying users ID>
(MSSQL syntax)
You can use queries but it will create problems later on I guess as I have also faced this problem before. You can insert new entries in the same table when a user accepts the request and mark the new record as accepted but this time the user_1 becomes user_2 and vice versa.
Alias with joins is waht I think you are asking.
Something like.
Select c.id, uRequest.UserName, uRequested.UserName From Contacts c
inner join Users As uRequest On c.User_1 = uRequest.id
inner join Users As uRequested On c.User_2 = URequested.id
Where accepted = 1
will give you all contacts where the request has been accepted.
Assuming I have table "Department" (200 row) & "Employees" (300,000 row) each has their own details
And the vector table combining both is "dep_emp"
CREATE TABLE IF NOT EXISTS `dep_emp` (
`id` int(11) NOT NULL DEFAULT '0',
`dep_id` int(11) NOT NULL DEFAULT '0',
`emp_id` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
My question is how to make a query to get two of employees (any two employees) for every Department?
My solution so far is this:
(SELECT * FROM `dep_emp` WHERE dep_id=1 LIMIT 2) UNION ALL
(SELECT * FROM `dep_emp` WHERE dep_id=2 LIMIT 2) UNION ALL
(SELECT * FROM `dep_emp` WHERE dep_id=3 LIMIT 2) ........etc
of course this is done {n} times for each Dept so if I wanted to display two Employees for all dept then I will have to write 199 UNION ALL, this is very ugly
Any other solutions
PS. there are a lot of details that I have moved out of the problem to make things a lot simpler
This may work:
SELECT *
FROM Department
JOIN dep_emp USING (dep_id)
JOIN Employees USING (emp_id)
WHERE emp_id IN
(SELECT emp_id
FROM Employees
JOIN dep_emp USING (emp_id)
WHERE dep_emp.dep_id = Department.dep_id LIMIT 2)
I didn't test it though.
OK, that didn't work. Try this instead:
SELECT *
FROM Department
JOIN dep_emp USING (dep_id)
JOIN Employees USING (emp_id)
JOIN (SELECT emp_id, dep_id
FROM dep_emp
GROUP BY dep_id
LIMIT 2) emp_2
USING (emp_id, dep_id)
BTW don't forget to put some indexes on the tables. On dep_emp put a primary key on both columns AND a unique key on the columns in the reverse order! (That way the index works either way.) (You don't need the ID column in dep_emp BTW, at least not in the structure you showed.)
SELECT d.*, e.*
FROM Department AS d
JOIN Employees AS e
ON e.id IN
( SELECT de.emp_id
FROM dep_emp AS de
WHERE de.dep_id = d.id
LIMIT 2
)
Another, very different way to get two emp_id for every department:
SELECT dep_id
, MIN(emp_id) AS emp_id_1
, MAX(emp_id) AS emp_id_2
FROM dep_emp
GROUP BY dep_id
or (to have in separate rows, so this can be joined to the other 2 tables):
SELECT dep_id
, MIN(emp_id) AS emp_id
FROM dep_emp
GROUP BY dep_id
UNION ALL
SELECT dep_id
, MAX(emp_id)
FROM dep_emp
GROUP BY dep_id
The first query does not work in MySQL, because LIMIT is not allowed inside IN subqueries. Here's another approach:
SELECT e.*
FROM
( SELECT DISTINCT dep_id
FROM dep_emp
) AS d
JOIN
dep_emp AS e
ON d.dep_id = e.dep_id
AND e.emp_id <=
COALESCE( ( SELECT de.emp_id
FROM dep_emp AS de
WHERE de.dep_id = d.dep_id
ORDER BY de.emp_id --- OFFSET 1
LIMIT 1 OFFSET 1 --- to get 2 employess
) --- per department
, 9999999 )
ORDER BY e.dep_id
, e.emp_id
Use OFFSET x to get x+1 employees per department.
I'm trying to display the username of the person who has submitted the most articles but I don't know how to do it using MySQL & PHP, can someone help me?
Here is the MySQL code.
CREATE TABLE users (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(255) DEFAULT NULL,
pass CHAR(40) NOT NULL,
PRIMARY KEY (user_id)
);
CREATE TABLE users_articles (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT UNSIGNED mNOT NULL,
title TEXT NOT NULL,
acontent LONGTEXT NOT NULL,
PRIMARY KEY (id)
);
Here is the code I have so far.
$mysqli = mysqli_connect("localhost", "root", "", "sitename");
$dbc = mysqli_query($mysqli,"SELECT COUNT(*) as coun, user_id
FROM users_articles
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1");
If you want to get the user's name, you should use the next query:
SELECT users.name, COUNT(users_articles.id) AS coun
FROM users_articles
LEFT JOIN users_articles ON users.id=users_articles.user_id
GROUP BY users_articles.user_id
ORDER BY coun DESC
LIMIT 1
select u.user_id, count(ua.id) as num_articles
from users u
left outer join users_articles ua
on u.user_id = ua.user_id
group by u.user_id
order by num_articles desc
The left outer join (as opposed to an inner join) ensures that all users are represented in the result, no matter if they have a record in users_articles or not.
EDIT: Since you only want the person who has submitted the most articles, you do not necessarily need the left outer join (as long as there is at least one user who has written any articles). For a complete list, it would be useful, however.
Whichever above queries given by geeks u use just DO NOT FORGET TO INCLUDE "username" field in select query as none of them has included the username field
What you want to do is a join.
The SQL query you need is this:
SELECT COUNT(*) as coun, users.user_id, username
FROM users_articles
INNER JOIN users
ON users_articles.user_id = users.user_id
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1
I tested this and it works.
The result table contains the number of articles of the user, its user id and its username.
use like this,
SELECT COUNT(users_articles.*) as coun, users_articles.user_id, users.username
FROM users_articles, users
WHERE users_articles.user_id = users.user_id
GROUP BY users.user_id
ORDER BY coun DESC
SELECT COUNT(*) as coun, user_id, users.username
FROM users_articles, users
WHERE users_articles.user_id = users.user_id
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1