Summing multiple columns - mysql

user table
user_id
entry
user_id
points_a
points_b
SELECT user.*,
(SUM(entry.points_a) + SUM(entry.points_b)) as points_total
FROM user
LEFT JOIN entry on entry.user_id = entry.user_id
..is what I'm trying to do — get a total count of all points that a user has. The field type for points is INT. This Doesn't seem to work?

Given that you have no columns in user except the ID, the join really serves no purpose.
select userid, SUM(points_a) + SUM(points_b) as total
from entry
group by userid
This will give you what you are looking for. If you need more fields from the user table that you just didn't show, you can do the join and add those fields to the select.
I think what you were missing was the Group By clause though.

Related

MySQL find matching set of rows

I have a cross-reference table that supplies the many-to-many relationship between users and user group tables. It contains two relevant columns: group_id and user_id (surprise, surprise!). When a user wants to create a new group, I want to first check if that set of users already exists as a group.
Essentially I would define the problem as "Given a set of user ids, find any set of rows that match the set of user ids and all share the same group id".
Edit:
I'm looking for the exact set of users, not interesting in seeing in the resultset groups that include those users in addition to other users.
Sample Data
I have the hunch that a subquery is the way to go, but I can't figure out how to arrange it. Any help would be greatly appreciated!
Is this what you want?
select groupid
from usergroups ug
where userid in ($user1, $user2, . . . , $usern)
group by groupid
having count(*) = <n>;
This returns all groups that have the supplied list of users.
If you want the exact set, then:
select groupid
from usergroups ug
group by groupid
having count(*) = sum( userid in ($user1, $user2, . . . , $usern) );
This assumes that groups don't have the same user twice (it is not hard to adjust for that, but the condition becomes more complicated).

Can't make SQL query from three tables

I Can't make a SQL query for:
I have the following tables:
User which have two columns namely: user_id and user_name.
Group which has three columns namely : id, group_name and created_date.
Records which has five columns namely : id, group_id, user_id, record_content and record_type.
record_user which has three columns namely : user_id, record_id and liked
Now I want a query which could execute on all 4 tables something like:
select user_id, user_name, group_id, record_content
Also I need in this table - the liked field for each record based on user_id (which mean that this user is authenticated).
The thing that I try to get all messages(records) of definite group and information regarding like of each record by user which is currently reading this messages(records).
Please try the following...
SELECT User.user_id AS user_id,
User.user_name AS user_name,
Group.id AS group_id,
Group.group_name AS gorup_name,
Records.record_content AS record_content,
record_user.liked AS liked
FROM User
JOIN Records ON User.user_id = Records.user_id
JOIN Group ON Group.id = Records.group_id
JOIN record_user.record_id ON Records.id
GROUP BY User.user_id,
Group.id;
The AS's are not required, they just are useful for giving the output fields more convenient names. You can change them to pretty much whatever you want.
Please see https://www.w3schools.com/sql/sql_join.asp for more on JOIN's - look for the Venn diagram as well as read the explanation.
The GROUP BY clauses may not be needed, but you have not explained how you wish the output to be sorted and grouped, so I have chosen those as a suggestion.
Note : In the future it will help if you present us with sample data and desired output.
If you have any questions or comments, then please feel free to post a Comment accordingly.

How do I combine data from two MySQL tables to return a list of users sorted by the count of user entries in one table?

I am currently using this MySQL query:
$query="SELECT user, COUNT(*) AS num FROM tracks GROUP BY user ORDER BY COUNT(*) DESC";
which gives me a unique row for each user with a count of the number of entries for each user in the table 'tracks'.
Not all users have an entry in the table 'tracks' though, and I would like to select/list all users on a page. All users are however included in another MySQL table called 'users'.
Because I would like to display all users sorted by the count of entries in the 'tracks' table (with users with no entries in the 'tracks' table at the bottom), I presume that I need to use one SELECT query to achieve this, but I am not sure how to do this, and would be glad of some help.
You need to do a left join. Assuming you have a "users" table with a "user_id" column which matches the "user" column in the "tracks" table:
SELECT users.user_id, count(tracks.user) from users left join tracks on (users.user_id = tracks.user) group by tracks.user order by count(tracks.user) DESC;

A MySQL query addressing three tables: How many from A are not in B or C?

I have a problem formulating a MySQL query to do the following task, although I have seen similar queries discussed here, they are sufficiently different from this one to snooker my attempts to transpose them. The problem is (fairly) simple to state. I have three tables, 'members', 'dog_shareoffered' and 'dog_sharewanted'. Members may have zero, one or more adverts for things they want to sell or want to buy, and the details are stored in the corresponding offered or wanted table, together with the id of the member who placed the ad. The column 'id' is unique to the member, and common to all three tables. The query I want is to ask how many members have NOT placed an ad in either table.
I have tried several ways of asking this. The closest I can get is a query that doesn't crash! (I am not a MySQL expert by any means). The following I have put together from what I gleaned from other examples, but it returns zero rows, where I know the result should be greater than zero.
SELECT id
FROM members
WHERE id IN (SELECT id
FROM dog_sharewanted
WHERE id IS NULL)
AND id IN (SELECT id
FROM dog_shareoffered
WHERE id IS NULL)
THis query looks pleasingly simple to understand, unlike the 'JOIN's' I've seen but I am guessing that maybe I need some sort of Join, but how would that look in this case?
If you want no ads in either table, then the sort of query you are after is:
SELECT id
FROM members
WHERE id NOT IN ( any id from any other table )
To select ids from other tables:
SELECT id
FROM <othertable>
Hence:
SELECT id
FROM members
WHERE id NOT IN (SELECT id FROM dog_shareoffered)
AND id NOT IN (SELECT id FROM dog_sharewanted)
I added the 'SELECT DISTINCT' because one member may put in many ads, but there's only one id. I used to have a SELECT DISTINCT in the subqueries above but as comments below mention, this is not necessary.
If you wanted to avoid a sub-query (a possible performance increase, depending..) you could use some LEFT JOINs:
SELECT members.id
FROM members
LEFT JOIN dog_shareoffered
ON dog_shareoffered.id = members.id
LEFT JOIN dog_sharewanted
ON dog_sharewanted.id = members.id
WHERE dog_shareoffered.id IS NULL
AND dog_sharewanted.id IS NULL
Why this works:
It takes the table members and joins it to the other two tables on the id column.
The LEFT JOIN means that if a member exists in the members table but not the table we're joining to (e.g. dog_shareoffered), then the corresponding dog_shareoffered columns will have NULL in them.
So, the WHERE condition picks out rows where there's a NULL id in both dog_shareoffered and dog_sharewanted, meaning we've found ids in members with no corresponding id in the other two tables.

How do I select a record from one table in a mySQL database, based on the existence of data in a second?

Please forgive my ignorance here. SQL is decidedly one of the biggest "gaps" in my education that I'm working on correcting, come October. Here's the scenario:
I have two tables in a DB that I need to access certain data from. One is users, and the other is conversation_log. The basic structure is outlined below:
users:
id (INT)
name (TXT)
conversation_log
userid (INT) // same value as id in users - actually the only field in this table I want to check
input (TXT)
response (TXT)
(note that I'm only listing the structure for the fields that are {or could be} relevant to the current challenge)
What I want to do is return a list of names from the users table that have at least one record in the conversation_log table. Currently, I'm doing this with two separate SQL statements, with the one that checks for records in conversation_log being called hundreds, if not thousands of times, once for each userid, just to see if records exist for that id.
Currently, the two SQL statements are as follows:
select id from users where 1; (gets the list of userid values for the next query)
select id from conversation_log where userid = $userId limit 1; (checks for existing records)
Right now I have 4,000+ users listed in the users table. I'm sure that you can imagine just how long this method takes. I know there's an easier, more efficient way to do this, but being self-taught, this is something that I have yet to learn. Any help would be greatly appreciated.
You have to do what is called a 'Join'. This, um, joins the rows of two tables together based on values they have in common.
See if this makes sense to you:
SELECT DISTINCT users.name
FROM users JOIN conversation_log ON users.id = converation_log.userid
Now JOIN by itself is an "inner join", which means that it will only return rows that both tables have in common. In other words, if a specific conversation_log.userid doesn't exist, it won't return any part of the row, user or conversation log, for that userid.
Also, +1 for having a clearly worded question : )
EDIT: I added a "DISTINCT", which means to filter out all of the duplicates. If a user appeared in more than one conversation_log row, and you didn't have DISTINCT, you would get the user's name more than once. This is because JOIN does a cartesian product, or does every possible combination of rows from each table that match your JOIN ON criteria.
Something like this:
SELECT *
FROM users
WHERE EXISTS (
SELECT *
FROM conversation_log
WHERE users.id = conversation_log.userid
)
In plain English: select every row from users, such that there is at least one row from conversation_log with the matching userid.
What you need to read is JOIN syntax.
SELECT count(*), users.name
FROM users left join conversion_log on users.id = conversation_log.userid
Group by users.name
You could add at the end if you wanted
HAVING count(*) > 0