I have to table, contacts and groups.
Inside of contacts I have 3 columns: id first_name last_last
Inside groups I have 2 columns: id linked
I want to put contacts into groups. So I thought the best way would be that when you added a contact to a group it would add that contacts ID to a list of contact ID's separated by commas in the linked column.
So if you added contact 1, 4, 14, and 24 to a specific group the linked column would have this value 1,4,14,24
Now I want to display the contacts in that group. So I explode() the linked value and then use a foreach() to cycle through the exploded array and on each loop select through MySQL the first name and last name of that contact and display it.
All of that works fine. My problem is I realized I want to sort the contacts being displayed in that group. But they display in the order they were placed in the group.
I want to be able to sort by first name ascending or descending but I have no idea how because I'm selecting each contact in a foreach() and echoing it.
P.S. I thought maybe make a column on the contact called groups and store all the groups that contact is in the same way I stored all the contacts that were in a group. So if the contact was in groups 1, 2, 4, and 6 then that contacts groups column would have a value of 1,2,4,6. The only problem is, lets say I'm search for all contacts in group 6, how do I search though that list in a MySQL statement? I thought the best way would be SELECT first_name FROM contacts WHERE groups LIKE '%6%' but then what if a contact is in group 60? Wouldn't it select that contact too even if it isn't in the right group?
Don't store multiple values in the same field in a database! As you have observed, you will get problems when you want to handle each value separately.
In your case, insert one row in the groups table for each group the person belongs to. The join the two tables to get the information in the way you want.
E.g: to find which groups Santa Claus blongs to:
SELECT groups.id
FROM contacts
INNER JOIN groups
ON groups.linked = contacts.id
WHERE firstname = 'Santa' AND lastname = 'Claus'
Or to find who is in group 1:
SELECT firstname, lastname
FROM contacts
INNER JOIN groups
ON groups.linked = contacts.id
WHERE groups.id = 1
ORDER BY lastname, firstname
To get the results as comma separated lists, you can use the GROUP_CONCAT function:
SELECT groups.id,
GROUP_CONCAT(firstname, ' ', lastname
ORDER BY lastname SEPARATOR ', ') AS groups
FROM contacts
INNER JOIN groups
ON groups.linked = contacts.id
GROUP BY groups.id
In order to store group names, you may benefit from using 3 tables
Contact (id, firstname, lastname)
Group (id, groupname)
Group_membership (contact_id, group_id)
Related
I am trying to select the names from one table column and then ignore if any rows have the same member as the user id in a different column.
for example i would like to select all the "groupNames" from groups then check the "members" column for any members that match the user.
members groupName
mike test
andy test
eric runners
erica test
If the user was "mike", I would like the list to ignore any row that had the "groupName" test as "mike" also has that as a group name and the list should only display runners.
Is this possible? I have tried to research it but not even sure what I need to search for?
Does this do what you want?
select t.*
from groups t
where t.groupName <> (select t2.groupName from groups t2 where t2.members = 'Mike');
I have two tables, one for students and one for subjects, and I want to join these two tables, so that each student list will contain all subjects belonging to them.
Can this be done in single select query alone?
Or should I query for each table and play with array results?
Table example:
You can use group_concat to get the first option of the desired output:
SELECT student_id, name, GROUP_CONCAT(subject SEPARATOR ' ')
FROM table1
JOIN table2 ON table1.student_id = table2.student_no
GROUP BY student_id, name
I am trying to create a script where employees can place orders for customers. Due to the nature of the business, 2 different employees may place an order for the same customer. I would like to print a report so these orders can be verified.
I have a customer table, and an order table, and am attempting to create a query that will list all records where there is a duplicate last name in customers table, but only if their is an order for that last name, (it is possible for a customer to exist without an order).
Either this is an obscure thing to do, or I am not searching for it correctly, as I haven't found any query that accomplishes this.
Thank you for your assistance.
customers table -
id, first_name, last_name, address, city, state, zip, phone
orders table -
id, customer_id, quantity (there is only 1 product)
Example -
there are 4 customers with the last name Johnson, and 2 records with a last name of Johnson also have orders (only the last name needs to match and is the duplicate criteria). I would like the query to print all instances of customers with the last name Johnson, (all fields) where customers.id appears in orders.customer_id
You can use a self join in order to identify duplicate last names. Something sort of like this might suit your purposes:
select c1.* from customers c1
join customers c2 on c1.last_name = c2.last_name and c1.id <> c2.id
join orders o on o.customer_id = c1.id
I'm trying to separate the IDPosts column as a single row for each ID (attempting to create a favorite post list). The column next to it has all of the proper columns listed but are grouped, I want to obtain a row for each one grouped together in the favuserposts column. See my picture and query below. Please let me know if you need more information.
Displays everything but cannot display multiple favorite post IDs:
SELECT Users.IDUser,
Users.username,
Users.profile_picture,
Favorites.IDPosts,
GROUP_CONCAT(DISTINCT coalesce(Favorites.IDPosts,'')) as "favuserposts",
( Select body
from Posts
where Favorites.IDPosts=Posts.IDPosts
AND Users.IDUser=Favorites.IDUser)
FROM Users
LEFT OUTER JOIN Favorites ON Favorites.IDUser = Users.IDUser
GROUP BY Users.IDUser HAVING COUNT(IDPosts)>0;
You group by IDUser. So all other fields you select are aggregates in some way. Either you specify the aggregate you want (MIN, MAX, GROUP_CONCAT, etc.) or you get a random match. So let's look at what you select:
Users.username = a "random" username for the user id, but as there is just one name per userid of course, you get the one user name for the id
Users.profile_picture = same as username; you get the one picture for the user
Favorites.IDPosts = a random one of the user's post IDs
GROUP_CONCAT(DISTINCT coalesce(Favorites.IDPosts,'')) = string of all distinct IDs
( Select body from Posts ...) = a random one of the user's post bodies
So if you want a string listing all bodies, then use group_concat, just as you do with the post IDs:
GROUP_CONCAT(DISTINCT
( Select body
from Posts
where Favorites.IDPosts=Posts.IDPosts
AND Users.IDUser=Favorites.IDUser
)) as bodies
Hey guys, how the heck do I go about doing this.
I have an address book I'm making and I'm trying to figure out how to tackle my groups. I let the users rename their groups at will. But then this complicates my life ;0
I have 2 tables. groups and contacts the groups has the group names per user. the contacts has a group column that says what group that contact entry belongs to.
How can I rename a group from the groups table and have the new name reflect in the contacts table so everything matches up?
I would suggest changing your model.
Use IDs as primary keys and an intersection-table to assign your contacts to groups:
Groups
id
name
Contacts
id
name
Group_Contacts
group_id -> Groups.id
contact_id -> Contacts.id
Now you can change the group-name whenever you want, without updating the contacts.
EDIT: If you only want to get the contacts of a certain group, use a SELECT like this one:
Select c.name
From groups g
Join group_contacts gc On ( gc.group_id = g.id )
Join contacts c On ( c.id = gc.contact_id )
Where g.name = 'Your group name'
You also could use a before update trigger which first renames all entries in the contacts table to match the new name and then let the update go on