I am trying to do a SELECT to get the offers a certain user have earned. However, I cannot figure how to do it.
I have three tables
user: id | name
offer: id | name
user_offer: id | user_id | offer_id
How do I select all offer the user 1 has?
This should work:
SELECT offer.name
FROM offer INNER JOIN user_offer
ON user_offer.offer_id=offer.id
WHERE user_offer.user_id='1'
Related
I'm joining 3 tables in SQL Server for the purpose of mapping users to their managers. The purpose of the junction table is to map their full usernames to their network ID. Here's the query:
select
dbo.Employee_Records.EMPLOYEE_NAME as AD_NAME,
dbo.Employee_Records.NAME as NAME,
dbo.Employee_Records_MANAGER_S_.KEYWORD as SUPERVISOR_FULLNAME,
dbo.employee_records.EMPLOYEE_NAME as SUPERVISOR_ADNAME
from
dbo.Employee_Records
left outer join dbo.Employee_Records_MANAGER_S_ on
dbo.Employee_Records.ID = dbo.Employee_Records_MANAGER_S_.ID
left join dbo.Employee_Records_MANAGER_S_ as ManagersList on
ManagersList.KEYWORD = dbo.employee_records.name
The first 3 columns appear as I'd expect, showing the Network ID, Full User Name and the Manager's Full Name. However, the 4th column is the issue. It's showing the network ID of the user, not the manager.
It appears like this:
AD_NAME | NAME | SUPERVISOR_FULLNAME | SUPERVISOR_ADNAME
USER1 | User, Test | Supervisor, Test | USER1
USER1 | User, Test | Supervisor2, Test | USER1
It should appear like this:
AD_NAME | NAME | SUPERVISOR_FULLNAME | SUPERVISOR_ADNAME
USER1 | User, Test | Supervisor, Test | SUPERVISOR1
USER1 | User, Test | Supervisor2, Test | SUPERVISOR2
The Employee.Records table contains all full usernames and full supervisor names. The Employee.Records_MANAGER_S_ table is used to tie the Supervisors to the users, since each user could have multiple supervisors. All of the mappings for Network Names and Full Names are also in the Employee.Records table, so technically I'm trying to join the Employee.Records table to the Employee_Records_MANAGER_S_ and then do another join of the Employee_Recors_MANAGER_S_ back to the Employee.Records table again, but this time joining on the SUPERVISOR_FULLNAME instead of the Employee's name.
If I understand correctly you need to join your dbo.Employee_Records table on a second time to get the supervisor details.
select
ER.EMPLOYEE_NAME as AD_NAME,
ER.[NAME] as [NAME],
M.KEYWORD as SUPERVISOR_FULLNAME,
MR.EMPLOYEE_NAME as SUPERVISOR_ADNAME
from dbo.Employee_Records as ER
left outer join dbo.Employee_Records_MANAGER_S_ as M on ER.ID = S.ID
left join dbo.Employee_Records as MR on MR.[NAME] = M.KEYWORD;
Note: As shown I highly recommend short table aliases as they make the query much clearer.
I have a User table that has a many to many relation with itself, and I would like to get all the pairs of users with this specific relation. The problem is, in the relation table I store users like that:
+------+---------------+
| User | relation |
+------+---------------+
| id | left_user_id |
| name | right_user_id |
| ... | ... |
+------+---------------+
So when I do a basic
SELECT count(*)
FROM relation LEFT OUTER JOIN user AS user_1 ON user_1.id = relation.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = relation.right_user_id
GROUP BY left_user_id, right_user_id;
I sometimes get two results for the same pair (for example sometimes (Adam, Eva) and (Eva, Adam) which are the same pair). What I would like to achieve is just one pair: (Adam, Eva).
How can this be achieved?
You can use the functions least() and greatest():
SELECT count(*)
FROM relation r
LEFT OUTER JOIN user AS user_1 ON user_1.id = r.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = r.right_user_id
GROUP BY LEAST(r.left_user_id, r.right_user_id), GREATEST(r.left_user_id, r.right_user_id);
Or in this case where you don't need the joins:
SELECT count(*)
FROM relation
GROUP BY LEAST(left_user_id, right_user_id), GREATEST(left_user_id, right_user_id);
The left joins should not be necessary. The key is simply using least() and greatest(). That would be:
SELECT LEAST(r.left_user_id, r.right_user_id) as user_id_1,
GREATEST(r.left_user_id, r.right_user_id) as user_id_2,
COUNT(*)
FROM relation
GROUP BY user_id_1, user_id_2;
The one caveat with this approach is that the pair in the result set may not be in the original data -- in that order. So, if you had "Eve"/"Adam" once in the data, then it would return: "Adam"/"Eve"/1. That can be addressed, if necessary.
I've a table like this one:
Column | Type | Modifiers
username | character varying(12) | not null
electioncode | integer | not null
votes | integer | default 0
PRIMARY KEY (username, electioncode)
i need to create a view with username, electioncode, max(votes)
if i use this query it works fine but without username:
SELECT electioncode, max(votes) from table group by electioncode;
if i add username it asks me to add it into the group by but if i do that it gives me the entire table instead of just the username-electioncode-maxvotes
Do you want to get username associated with this number of votes? Or any username in given election code?
If the first:
SELECT
DISTINCT ON ( electioncode )
*
FROM table
ORDER BY electioncode, votes desc;
if the other:
SELECT
electioncode,
min(username),
max(votes)
FROM
table
GROUP BY electioncode;
Your username field seems to be unique. Every record has different username (I am assuming) thus when you group by username it will give you all the records. What you are trying to do has a logic issue not syntax issue.
A suggestion: You want to write on a piece of paper the output you would like to see and then construct the query... If you want Username, Electioncode and max (votes) then imagine how you would display the data where two usernames - user1 and user 2 who have electioncode 001 and voted 1 each? How would you display this?
Take for example an application which has users, each of which can be in exactly one group. If we want to SELECT the list of groups which have no members, what would be the correct SQL? I keep feeling like I'm just about to grasp the query, and then it disappears again.
Bonus points - given the alternative senario, where it's a many to many pairing, what is the SQL to identify unused groups?
(if you want concrete field names:)
One-To-Many:
Table 'users': | user_id | group_id |
Table 'groups': | group_id |
Many-To-Many:
Table 'users': | user_id |
Table 'groups': | group_id |
Table 'user-group': | user_id | group_id |
Groups that have no members (for the many-many pairing):
SELECT *
FROM groups g
WHERE NOT EXISTS
(
SELECT 1
FROM users_groups ug
WHERE g.groupid = ug.groupid
);
This Sql will also work in your "first" example as you can substitute "users" for "users_groups" in the sub-query =)
As far as performance is concerned, I know that this query can be quite performant on Sql Server, but I'm not so sure how well MySql likes it..
For the first one, try this:
SELECT * FROM groups
LEFT JOIN users ON (groups.group_id=users.group_id)
WHERE users.user_id IS NULL;
For the second one, try this:
SELECT * FROM groups
LEFT JOIN user-group ON (groups.group_id=user-group.group_id)
WHERE user-group.user_id IS NULL;
SELECT *
FROM groups
WHERE groups.id NOT IN (
SELECT user.group_id
FROM user
)
It will return all group id which not present in user
I feel like an idiot asking this...
Table 1: users
id serial
person integer
username char(32)
Table 2:persons
id serial
name char(16)
Can I run a query that returns the name field in persons by providing the username in users?
users
1 | 1 | larry123
persons
1 | larry
2 | curly
SQL?
select name from persons where users.person=persons.id and users.username='larry123';
with the desired return of
larry
I have been doing it with two passes until now and think maybe a nested select using a join is what I need
1 | larry
It sounds like you're asking how to do a join in SQL:
SELECT
name
FROM
users JOIN persons ON (users.person = persons.id)
WHERE
users.username = 'larry123';
that is almost the query you wrote. All you were missing was the join clause. You could also do that join like this:
SELECT name
FROM users, persons
WHERE
users.person = persons.id
AND users.username = 'larry123';
I suggest finding a well-written introduction to SQL.