Have a table users and there is a field invited_by_id showing user id of the person who invited this user. Need to make a MySQL query returning rows with all the fields from users plus a invites_count field showing how many people were invited by each user.
Something like this:
SELECT
User.*, Count.count
FROM
users AS User,
(
SELECT COUNT(*) AS count FROM users WHERE users.invited_by_id=User.id
) AS Count;
This one is not working so I need a working one.
SELECT u.*,
(
SELECT COUNT(*)
FROM users ui
WHERE ui.invited_by_id = u.id
) AS cnt
FROM users u
Ok, first of all, count is a reserved word in sql so you can't use it as a table alias (unless you quote it in some way but don't do that). Secondly, the real way to solve this problem is to introduce a GROUP BY clause in your subquery.
Try this:
SELECT user3.*, subquery.theCount FROM
users AS user3
INNER JOIN (
SELECT
user1.id, count(user2.id) AS theCount
FROM
users AS user1
LEFT OUTER JOIN
users AS user2 ON user2.invited_by_id=user1.id
GROUP BY user1.id
) AS subquery ON subquery.id=user3.id;
Here is a dirty little secret about MySQL: It lets you cheat with the GROUP BY statement and select columns that are not in the GROUP BY list and also not in aggregate functions. Other RMDMSes don't let you do this.
SELECT
user1.*, count(user2.id) AS theCount
FROM
users AS user1
LEFT OUTER JOIN
users AS user2 ON user2.invited_by_id=user1.id
GROUP BY user1.id;
Related
im intend to return i.e an id where it doesn't exist in other table.(e.g. transactions), with additional condition
users table
transactions table
aim was return id and name from users table which do not exist in transactions table, with join in users.id to transactions.investor_id (23xx) and join in users.id to transactions.borrower_id (100xx), which i a set the result should be (2331,2332,10011,10012), While i also want to give an additional condition which the id want to return both in investor and borrower was using gmail email address and phone number i.e 0811xx,0812xx,0813xx.
the following still returns wrong result and also contains id where iam not intended to related to the additional where condition, while still not join to the borrower_id.
SELECT
users.id, users.name
FROM
users
WHERE
users.id NOT IN (SELECT transactions.investor_id FROM transactions)
AND email LIKE '%#gmail%'
AND phone LIKE '0811%' OR phone LIKE '0812%' OR phone LIKE '0813%'
Your problem is the lack of parentheses around the or clauses.
But, you can simplify your query. Most databases support some form of regular expressions. If so, you can simplify the query to:
SELECT u.id, u.name
FROM users u
WHERE u.id NOT IN (SELECT t.investor_id FROM transactions t) AND
u.email LIKE '%#gmail%' AND
u.phone ~ '^081[123]';
The above happens to be Postgres syntax, but there is similar functionality in most databases.
I should point out that SQL Server does this with like:
SELECT u.id, u.name
FROM users u
WHERE u.id NOT IN (SELECT t.investor_id FROM transactions t) AND
u.email LIKE '%#gmail%' AND
u.phone LIKE '081[123]%';
Or you can even do:
SELECT u.id, u.name
FROM users u
WHERE u.id NOT IN (SELECT t.investor_id FROM transactions t) AND
u.email LIKE '%#gmail%' AND
LEFT(u.phone, 4) IN ('0811', '0812', '0813');
You are almost there. Put the OR conditions in brackets...
SELECT users.id,
users.name
FROM users
WHERE users.id NOT IN (
SELECT transactions.investor_id
FROM transactions
)
AND email LIKE '%#gmail%'
AND (
phone LIKE '0811%'
OR phone LIKE '0812%'
OR phone LIKE '0813%'
)
I have two tables in MS Access.
Table 1: users
ID (auto int)
Name
Table 2: tickets
ID (auto int)
userName (int) (refers to ID in users table)
How can I list the user names and the number of tickets submitted?
This should give you the results that you want. You will want to use an aggregate function COUNT() and a GROUP BY
SELECT u.name, count(t.username) TicketsSubmitted
FROM Users u
INNER JOIN tickets t
ON u.id = t.username
GROUP BY u.name
Count the tickets per user in a subquery, then list all the info per user.
SELECT u.Name AS UserName, t.ticketCount AS TicketsSubmitted
FROM users AS u
INNER JOIN ( SELECT COUNT(ID), userName AS ticketCount FROM tickets GROUP BY userName ) AS t
ON u.ID = t.userName
Should do it.
A make table query should allow you to query those two tables and create a third with the data you want.
The following link from the Microsoft Office website should give you the information you need.
http://office.microsoft.com/en-us/access-help/create-a-make-table-query-HA010108505.aspx
The two answers above give solid advice for the query to get the data you want.
If I have to find all uses that viewed the same video more than once, then I'm using the following query.
SELECT userid AS users,video_id
FROM watching_list GROUP BY userid , video_id HAVING COUNT(*) > 1;
^^It does give you that, right? If watching_list contains userid and videoid that the user watched and datetime stamp.
What I would like to do is join it to user table, based on userid, to look up user's name etc too and not just the userid.
I tried doing simple join, and of course it broke over me.
SELECT Users.Name, Users.userid AS users,video_id
FROM watching_list
JOIN Users
ON Users.UserID = watching_list.UserID
GROUP BY Users.userid , video_id, Users.Name
HAVING COUNT(*) > 1;
Why would this break? It should be the same user, so adding additional info of the same person to the group by should not cause a change
Here is a crude, quick SQLFiddle to prove this
A somewhat inelegant way to do it is like so:
Select USERS.LAST_NAME,
USERS.FIRST_NAME,
double_watchers.VIDEO_ID
FROM USERS,
(SELECT userid AS users,
video_id
FROM watching_list
GROUP BY userid , video_id
HAVING COUNT(*) > 1) double_watchers
Where double_watchers.userid = users.id;
I'm creating an inline table (not sure about terminology) with your original query and then joining it to the USERS table. There's probably a much more efficient way to do it, but I don't have a test instance in front of me to experiment right now.
I have a users table and a songs table, I want to select all the users in the users table while counting how many songs they have in the songs table. I have this SQL but it doesn't work, can someone spot what i'm doing wrong?
SELECT jos_mfs_users.*, COUNT(jos_mfs_songs.id) as song_count
FROM jos_mfs_users
INNER JOIN jos_mfs_songs
ON jos_mfs_songs.artist=jos_mfs_users.id
Help is much appreciated. Thanks!
The inner join won't work, because it joins every matching row in the songs table with the users table.
SELECT jos_mfs_users.*,
(SELECT COUNT(jos_mfs_songs.id)
FROM jos_mfs_songs
WHERE jos_mfs_songs.artist=jos_mfs_users.id) as song_count
FROM jos_mfs_users
WHERE (SELECT COUNT(jos_mfs_songs.id)
FROM jos_mfs_songs
WHERE jos_mfs_songs.artist=jos_mfs_users.id) > 10
There's a GROUP BY clause missing, e.g.
SELECT jos_mfs_users.id, COUNT(jos_mfs_songs.id) as song_count
FROM jos_mfs_users
INNER JOIN jos_mfs_songs
ON jos_mfs_songs.artist=jos_mfs_users.id
GROUP BY jos_mfs_users.id
If you want to add more columns from jos_mfs_users in the select list you should add them in the GROUP BYclause as well.
Changes:
Don't do SELECT *...specify your fields. I included ID and NAME, you can add more as needed but put them in the GROUP BY as well
Changed to a LEFT JOIN - INNER JOIN won't list any users that have no songs
Added the GROUP BY so it gives a valid count and is valid syntax
SELECT u.id, u.name COUNT(s.id) as song_count
FROM jos_mfs_users AS u
LEFT JOIN jos_mfs_songs AS S
ON s.artist = u.id
GROUP BY U.id, u.name
Try
SELECT
*,
(SELECT COUNT(*) FROM jos_mfs_songs as songs WHERE songs.artist=users.id) as song_count
FROM
jos_mfs_users as users
This seems like a many to many relationship. By that I mean it looks like there can be several records in the users table for each user, one of each song they have.
I would have three tables.
Users, which has one record for each user
Songs, which has one record for each song
USER_SONGS, which has one record for each user/song combination
Now, you can do a count of the songs each user has by doing a query on the intermediate table. You can also find out how many users have a particular song.
This will tell you how many songs each user has
select id, count(*) from USER_SONGS
GROUP BY id;
This will tell you how many users each song has
select artist, count(*) from USER_SONGS
GROUP BY artist;
I'm sure you will need to tweak this for your needs, but it may give you the type of results you are looking for.
You can also join either of these queries to the other two tables to find the user name, and/or artist name.
HTH
Harv Sather
ps I am not sure if you are looking for song counts or artist counts.
You need a GROUP BY clause to use aggregate functions (like COUNT(), for example)
So, assuming that jos_mfs_users.id is a primary key, something like this will work:
SELECT jos_mfs_users.*, COUNT( jos_mfs_users.id ) as song_count
FROM jos_mfs_users
INNER JOIN jos_mfs_songs
ON jos_mfs_songs.artist = jos_mfs_users.id
GROUP BY jos_mfs_users.id
Notice that
since you are grouping by user id, you will get one result per distinct user id in the results
the thing you need to COUNT() is the number of rows that are being grouped (in this case the number of results per user)
Let's say we have these tables;
table user:
- id
- username
- email
table user2group:
- userid
- groupid
table group:
- id
- groupname
How do I make one query that returns all users, and the groups they belong to (as an array in the resultset or something..)
select u.id, u.username, u.email, g.groupid, g.groupname
from user u
join user2group ug on u.userid=ug.userid
join group g on g.groupid=ug.groupid
order by u.userid
As you are looping through the result set, each time you see a new userid make a new user object (or whatever) and add the groups to it.
Eric's answer is great, but I would use a LEFT JOIN instead of an INNER to get users that do not belong to any group as well.
SELECT
u.id,
u.username,
u.email,
g.groupid,
g.groupname
FROM
user u
LEFT JOIN user2group ug ON u.userid = ug.userid
LEFT JOIN group g ON g.groupid = ug.groupid
ORDER BY
u.userid
Both of the above are more or less correct (deepends if each user has a group or not). But they will also both give a result set with several entries for each user.
There are ways of concatenating every group member into one comma separated string, I'd suggest you read about it here:
http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/
Another method I personally like is to use bit values instead of the relational table user2group
table user then gets a int (or bigint) field group, and each group ID is assigned one bit value (ie: 1,2,4,8,16 and so on) The value of the user table's group field is then the sum of the groupID it's assigned to. To query if its got a group you do:
where (group AND groupID = groupID)