SQL query to find out the number of tickets - sql

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.

Related

select id not exist in other table, additional condition

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%'
)

Getting data having only same values in all rows in DB2

I have 2 tables in DB2:
1) users ==> basic user details
2) details ==> more user details
The "details" table has columns named ssn, company and super_company. The company and super_company column can have multiple values for the same SSN.
Problem: I am trying to fetch only the users which has same super_company for the ssn.
I need username,ssn and company_id in output.
I tried grouping but not sure how to proceed as I am new to DB2.
SQL Fiddle: http://www.sqlfiddle.com/#!2/6d378/1/0
Please note that sql fiddle does not support DB2. I have provided just for providing the table structure.
You can use this query
select U.account_id, U.username from users U
join details D
on U.account_id = D.account_id
group by U.account_id, U.username
having count(distinct super_company) = 1
SQL FIDDLE
You say that you want company in the output, but you do not say what to do when there are multiple companies. Here is one method that outputs one row per user with an arbitrary company:
select u.username, u.accound_id, d.ssn as ssn,
min(d.company) as company, min(d.super_company)
from users u join
details d
on u.accound_id = d.accound_id
group by u.username, u.accound_id
having min(d.super_company) = max(d.super_company);
Actually aggregating multiple company values into a string is harder than it should be in DB2. You can get the individual records for matching users as well. I would do this using window functions:
select username, accound_id, ssn, company, super_company
from (select u.username, d.*,
min(super_company) over (partition by ssn) as minsc,
max(super_company) over (partition by ssn) as maxsc
from users u join
details d
on u.accound_id = d.accound_id
) t
where minsc = maxsc;
This is closer to your specific question, which is about duplicates by ssn, because it does not include username and accound_id when looking for duplicates.
select d.*, u.*
from details d
join users u
on u.accound_id = d.accound_id
join (
select accound_id
from details
group by accound_id
having count(distinct super_company) = 1
) x
on x.accound_id = u.accound_id

SQL to gather data from one table while counting records in another

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)

How to make a nested query?

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;

SQL Query without nested queries

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)