mysql - selecting groups and users all in same query - mysql

I have following two tables 'USERS' and 'GROUPS':
USERS
-id
-name
-groupid
GROUP
-id
-name
I'd like to return all users along with their group's name and group id. It should be an outer join on group id field correct?

A simple INNER JOIN should be enough:
SELECT `USERS`.*, `GROUP`.name AS group_name
FROM `USERS`, `GROUP`
WHERE `USERS`.groupid = `GROUP`.id

You're going to want to look at the JOIN statement
Doing this from my phone, so pardon any moderately incorrect syntax, but something a long the lines of
Edit: other guy's syntax is better. It's too early here

You can use a LEFT JOIN between users and groups so that users who are not in a group still show up in the result set, but with group name and id NULL:
SELECT
a.*,
b.name AS group_name
FROM
users a
LEFT JOIN
`group` b ON a.group_id = b.id
Side note: Ensure that you're encasing the table name group in backticks because it is a reserved keyword.
The result-set should look something like:
id | name | group_id | group_name
-----------------------------------------------------------------------------
1 | John | 5 | ThisIsGroup5
3 | Tim | 3 | ThisIsGroup3
6 | NotInGroup | NULL | NULL
Changing LEFT to INNER in the above query would INNER JOIN the two tables and exclude the user "NotInGroup" from the result-set.

Related

MySQL select row with two matching joined rows from another table

Hey I try to select a row from a table with two matching entries on another one.
The structure is as following:
----------------- ---------------------
| messagegroups | | user_messagegroup |
| | | |
| - id | | - id |
| - status | | - user_id |
| | | - messagegroup_id |
----------------- | |
---------------------
There exist two rows in user_messagegroup with the ids of two users and both times the same messagegroup_id.
I would like to select the messagegroup where this two users are inside.
I dont get it.. so I would appreciate some help ;)
The specification you provide isn't very clear.
You say "with the ids of two users"... if we take that to mean you have two user_id values you want to supply in the query, then one way to to find the messagegroups that contain these two specific users:
SELECT g.id
, g.status
FROM messagegroups g
JOIN ( SELECT u.messagegroup_id
FROM user_messagegroup u
WHERE u.user_id IN (42, 11)
GROUP BY u.messagegroup_id
HAVING COUNT(DISTINCT u.user_id) = 2
) c
ON c.messagegroup_id = g.id
The returned messagegroups could also contain other users, besides the two that were specified.
If you want to return messagegroups that contain ONLY these two users, and no other users...
SELECT g.id
, g.status
FROM messagegroups g
JOIN ( SELECT u.messagegroup_id
FROM user_messagegroup u
WHERE u.user_id IS NOT NULL
GROUP BY u.messagegroup_id
HAVING COUNT(DISTINCT IF(u.user_id IN (42,11),u.user_id,NULL)) = 2
AND COUNT(DISTINCT u.user_id) = 2
) c
ON c.messagegroup_id = g.id
For improved performance, you'll want suitable indexes on the tables, and it may be possible to rewrite these to eliminate the inline view.
Also, if you only need the messagegroup_id value, you could get that from just the inline view query, without the need for the outer query and the join operation to the messagegroups table.

Mysql select between two table without limiting if record appear on the joined table

I have been trying to figure out how to select data related to one id between to tables without limit it to the joined table. I tried using UNION, Inner join, JOIN, but it limit me to show records that are only in both tables. By example:
Table 1 (users)
id | name | register
1 | John | 2014-03-01
2 | Kate | 2014-03-02
etc..
Table 2 (birthdays by example)
id | user | birthday
1 | 1 | 1989-09-09
Note that kate dont have a record on the birthdays table, if i do:
SELECT U.id, name, register, B.birthday FROM users as U INNER JOIN birthday as B ON B.user = U.id
it will only shows JOHN data, i would like to select all my users and if the record do not exist on the joined table, still be able to select all my users, sort of:
id | name | register | birthday
1 | John | 2014-03-01 | 1989-09-09
2 | kate | 2014-03-02 | null or ''
3
4
etc.
Sorry if its a stupid question but i dont find the light on this one. I would appreciate the help.
Regards
You need a LEFT OUTER JOIN instead of the plain JOIN (also known as INNER JOIN), like this:
SELECT U.id, name, register, B.birthday
FROM users as U
LEFT JOIN birthday as B
ON B.user = U.id
A LEFT JOIN between users and birthday tables will contain all records of the "left" table (users), even if the join-condition does not find any matching record in the "right" table (birthday).
This excellent article on The Code Project will help you a lot: Visual Representation of SQL Joins.
Summary of all JOIN types:
Note: Mysql does not support FULL OUTER JOIN but it can be emulated. Useful articles:
https://stackoverflow.com/a/4796911
http://www.sql-tutorial.ru/en/book_full_join_and_mysql.html
http://www.xaprb.com/blog/2006/05/26/how-to-write-full-outer-join-in-mysql/
Use left outer join instead of inner join..
SELECT U.id, name, register, B.birthday
FROM users as U left join birthday as B ON B.user = U.id

MySQL select distinct across multiple tables

I have a query that selects all columns from multiple tables, but it's returning multiples of the same values (I only want distinct values).
How can I incorporate something like this? When I try this, it still
Select Distinct A.*, B.*, C.*....
Does distinct only work when selecting the column names and not all (*) ? In this reference it says distinct in reference to column names, not across all of the tables. Is there any way that I can do this?
edit - I added more info below
Sorry guys, I just got back onto my computer. Also, I just realized that my query itself is the issue, and Distinct has nothing to do with it.
So, the overall goal of my Query is to do the following
Generate a list of friends that a user has
Go through the friends and check their activities (posting, adding friends, etc..)
Display a list of friends and their activities sorted by date (I guess like a facebook wall kind of deal).
Here are my tables
update_id | update | userid | timestamp //updates table
post_id | post | userid | timestamp //posts table
user_1 | user_2 | status | timestamp //friends table
Here is my query
SELECT U.* , P.* ,F.* FROM posts AS P
JOIN updates AS U ON P.userid = U.userid
JOIN friends AS F ON P.userid = F.user_2 or F.user_1
WHERE P.userid IN (
select user_1 from friends where user_2 = '1'
union
select user_2 from friends where user_1 = '1'
union
select userid from org_members where org_id = '1'
union
select org_id from org_members where userid = '1'
)
ORDER BY P.timestamp, U.timestamp, F.timestamp limit 30
The issue I'm having with this (that I thought was related to distinct), is that if values are found to meet the requirements in, say table Friends, a value for the Posts table will appear too. This means when I'm displaying the output of the SQL statement, it appears as if the Posts value is shown multiple times, when the actual values I'm looking for are also displayed
The output will appear something like this (notice difference between post value in the rows)
update_id | update | userid | timestamp | post_id | post | userid | timestamp | user_1 | user_2 | status | timestamp
1 | update1 | 1 | 02/01/2013 | 1 | post1| 1 | 2/02/2013| 1 | 2 | 1 | 01/30/2013
1 | update1 | 1 | 02/01/2013 | 2 | post2| 1 | 2/03/2013| 1 | 2 | 1 | 01/30/2013
So, as you can see, I thought I was having a distinct issue (because update1 appeared both times), but the query actually just selects all the values regardless. I get the results I'm looking for in the Post table, but all the other values are returned. So, when I display the table in PHP/HTML, the Post value will display, but I also get duplicates of the updates (just for this example)
When you select distinct *, you select every row, including the one that makes the record unique. If you want something better than what you are getting, you have to type the individual column names in your select clause.
It would be easy if you explain a little more what is the connection between the tables you'r querying, because you can use joins, unions (as mentioned above) or even group by's ...
Your updated post shows one of the JOIN conditions as:
JOIN friends AS F ON P.userid = F.user_2 OR F.user_1
This is equivalent to:
JOIN friends AS F ON (P.userid = F.user_2 OR F.user_1 != 0)
and will include many rows that you did not intend to include.
You probably intended:
JOIN friends AS F ON (P.userid = F.user_2 OR P.userid = F.user_1)
I think you want this:
select *
from tableA
union
select *
from tableB
union
select *
from tableC
This assumes that HHS tables all have the same number of columns and they are of the same data type. This not, you'll have to select specific columns to make it so.

MySQL - select 3 tables with correct left join syntax

Hope you can help me with correct syntax of a SQL query (using MySQL 5.5.25).
I have 3 tables:
data
data_tmp
users
data table is empty - has it's own structure but no rows
data:
id | name | who
----------------
data_tmp:
id | cars | who
---------------
1 | lambo| 2
users
who | name |
------------
2 | john
My query is:
SELECT DISTINCT
users.name,
(SELECT count(id) FROM data WHERE who = 1) as number,
data_tmp.cars
FROM
users, data, data_tmp
WHERE
users.who = 2
AND data_tmp.who = 2
AND data.who = 2
This of course returns an empty result (there is no row that suits to all parameters because data is empty).
What I would like to achieve is:
users.name | number | data_tmp.cars |
-------------------------------------
john | 0 | lambo |
I am sure I have to - in some way - use LEFT JOIN but can't find correct syntax. Hope you can help me.
Kalreg
give this a try (without using subquery)
SELECT a.name, b.cars, count(c.id) as number
FROM users a
INNER JOIN data_tmp b
on a.who = b.who
LEFT JOIN data c
on a.who = c.who AND
a.name = c.name
WHERE a.who = 2
GROUP BY a.name, b.cars
this works on different servers:
MSSQL SERVER # SQLFIDDLE
MYSQL # SQLFIDDLE
Your assumption is right: you have to use left JOIN, in this way :
SELECT DISTINCT users.name, (SELECT count(id) FROM data WHERE who = 1) as number, data_tmp.cars
FROM users
JOIN data_tmp USING (who)
LEFT JOIN data USING(who)
WHERE users.who = 2

MySQL Count Items In Category

I don't understand MySQL very well, here are the table structures I am using.
users
id | first_name | last_name | username
| password
categories
id | user_id | name | description
links
id | user_id | category_id | name |
url | description | date_added |
hit_counter
I am trying to return a result set like this, to give information about the category for a user that includes how many links are in it.
id | user_id | name | description | link_count
At the moment I have this query, but it only returns rows for categories that have links. It should return rows for categories that do not have any links (empty categories).
SELECT categories.*, COUNT(links.id)
FROM categories LEFT JOIN links ON
categories.id=links.category_id;
How to do this query? Thanks.
we can't do select table dot "star" with an aggregate.
what you wanna do is something like (pseudocode):
select
categories.field1,
categories.field2,
{etc.}
count(links.id)
from categories
left join links
on categories.id = links.category_id
group by
categories.field1,
categories.field2,
{etc.}
iow: you're missing the group by code-block to get the right aggregate in your query result set.
To mold alien052002's answer to fit your specific question, the following (untested) should work:
select c.id,
c.user_id,
c.name,
c.description,
count(l.link_count)
from categories c
left join links l on l.category_id = c.id
group by c.id, c.user_id, c.name, c.description
try this
SELECT categories.*, COUNT(links.id) FROM categories LEFT JOIN links ON categories.id=links.category_id group by categories.id;