Selecting from Different Tables, Sub queries or Joins - php

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'

Related

Joined two tables & get results

I'm having some trouble with joining two mysql tables & getting the result as I want.
I have two tables , users table & times table. Users table is having id & name . time table is having user_id & minutesSpent. I want to get the times for all the users with name & times column as the result set. But for some specific dates all user ids are not in the times table. So I need null value as for such users.
I have tried several queries, but every time I'm getting times only for user_ids available in the times table. Not getting other user_id's times as null :(
SELECT `users`.`name`,SUM(`times`.`minutesSpent`) AS `Total`
FROM `users`
LEFT OUTER JOIN `times` ON `users`.`id` = `times`.`user_id`
WHERE DATE(`date`) = '2015-06-03'
GROUP BY `users`.`name`
& I have tried this query as well
SELECT `users`.`name`,SUM(`times`.`minutesSpent`) AS `Total` ,CASE WHEN times.user_id IS NULL THEN 0 ELSE 1 END
FROM `users`
INNER JOIN `times` ON `users`.`id` = `times`.`user_id` AND `users`.`isTimeEnable` = 0
WHERE DATE(`date`) = '2015-06-03'
GROUP BY `users`.`name`
if any one help me with this, it would be great .
Thanks
Your WHERE clause is turning your left join into an inner join. Try this:
SELECT `users`.`name`,SUM(`times`.`minutesSpent`) AS `Total`
FROM `users`
LEFT OUTER JOIN `times` ON `users`.`id` = `times`.`user_id`
AND DATE(`date`) = '2015-06-03'
GROUP BY `users`.`name`
Incidentally, if less typing (well 20 characters) and better performance is your thing then consider the following:
SELECT u.name
, SUM(t.minutesSpent) Total
FROM users u
LEFT
JOIN times t
ON u.id = t.user_id
AND t.date BETWEEN '2015-06-03 00:00:00' AND '2015-06-03 23:59:59'
GROUP
BY u.name;

Count occurrences of distinct values with multiple tables

I have 3 tables in a database that have similar values and the same table structure. I am trying to get the number of occurrences of each value by unique user.
DB Structure
View on SQLFiddle
TABLE_1
user | value | id
TABLE_2
user | value | id
TABLE_3
user | value | id
I can run the following MySQL command to retrieve the desired results on 1 table at a time.
SELECT value,COUNT(*) as count FROM TABLE_1 GROUP BY value ORDER BY count DESC;
I need to run this command across the three tables at once in order to retrieve the unique occurrences of "value" among a list of "users" that contains numerous duplicates.
Given your comments, since you want to remove duplicates, use UNION to combine the data from the tables together:
SELECT value, COUNT(*) as count
FROM (
SELECT user, value, id
FROM TABLE_1
UNION
SELECT user, value, id
FROM TABLE_2
UNION
SELECT user, value, id
FROM TABLE_3 ) t
GROUP BY value
ORDER BY count DESC;
Updated Fiddle
You need to use UNION -
SELECT value, COUNT(*) as count
FROM (
SELECT user, value, id
FROM TABLE_1
UNION
SELECT user, value, id
FROM TABLE_2
UNION
SELECT user, value, id
FROM TABLE_3 ) tables
GROUP BY value
ORDER BY count DESC;
Output -
+-------+-----+
|car |8 |
|boat |4 |
|truck |3 |
|house |2 |
|skates |1 |
|bike |1 |
+-------+-----+
to go along with the comments this is what I would recommend you do.
setup:
CREATE TABLE members (
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
username varchar(255),
);
INSERT INTO members (username)
SELECT DISTINCT user FROM table1
UNION SELECT DISTINCT user FROM table2
UNION SELECT DISTINCT user FROM table3;
altering:
ALTER table1
ADD COLUMN user_id INT(10)
ADD INDEX `user_id` (`user_id`);
ALTER table2
ADD COLUMN user_id INT(10)
ADD INDEX `user_id` (`user_id`);
ALTER table3
ADD COLUMN user_id INT(10)
ADD INDEX `user_id` (`user_id`);
updating:
UPDATE table1 t,
JOIN members m ON m.username = t.username
SET t.user_id = m.id;
UPDATE table2 t,
JOIN members m ON m.username = t.username
SET t.user_id = m.id;
UPDATE table3 t,
JOIN members m ON m.username = t.username
SET t.user_id = m.id;
removing non normalized data
ALTER table1
DROP user;
ALTER table2
DROP user;
ALTER table3
DROP user;
now you can also set up foreign key contstraints on the user_id and id columns if you would like.
but to query a total count you can just join the tables.. make sure you add an index on each of the id fields so it will join properly.
SELECT your_stuff
FROM members m
LEFT JOIN table1 t1 ON t1.user_id = m.id
LEFT JOIN table2 t2 ON t2.user_id = m.id
LEFT JOIN table3 t3 ON t3.user_id = m.id

mysql: linking 2 tables with 2 different fields

I have a user table, e.g.
userId
userName
and I have a message table, e.g.
messageId
messageToId
messageFromId
messageContent
I am trying to make a query to pull a message, but also get the user names from the user table based on the messageToId and messageFromId.
I have done this before with only 1 field between tables, e.g.
SELECT message.*, user.userName
FROM message, user
WHERE user.userId = message.messageToId
AND messageId = (whatever)
But I am having trouble with 2 links.
I want the result as follows:
messageId
messageToId
toUserName
messageFromId
fromUserName
messageContent
Any help would be much appreciated, or if someone had another way of attempting a private message system with PHP/MySQL.
You just have to use joins and different table aliases:
SELECT m.*, u1.userName AS toUserName, u2.username AS fromUserName
FROM message m INNER JOIN user u1 ON m.messageToId = u1.userId
INNER JOIN user u2 ON m.messageFromId = u2.userId
WHERE messageId = "XXX";
You need to use a join from to achieve this:
SELECT `m`.*,
`to`.`userName` AS `to`,
`from`.`userName` AS `from`,
FROM `message` `m`
JOIN `user` `to` ON `m`.`messageToId` = `to`.`userId`
JOIN `user` `from` ON `m`.`messageFromId` = `from`.`userId`
WHERE `m`.`messageId` = 1
So you join against the user table twice to get both users for a particular message. To do this you need to use table aliases as I have done with to and from so that you distinguish between them.
I have also used a field alias to get their usernames separately eg:
`to`.`username` AS `from`
Will this work?
SELECT b.userName AS author, c.userName AS reciever, a.messageId, a.messageContent FROM message a JOIN user b ON a.messageFromId = b.userId JOIN user c ON a.messageToId = c.userId

contactlist mysql query

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.

MySQL how to display data from two tables

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

Categories