check if comma separated values exist in table - php

I have a table: users_group
id | group_id | user_ids
---|----------|---------
1 | 1 | 3
2 | 1 | 2
3 | 3 | 2
4 | 2 | 3
5 | 2 | 4
6 | 2 | 2
condition is that user_ids can be inserted only once. But in above case it is inserted for more than one group_id.
I am using this query to insert users_id field within foreach loop:
INSERT INTO users_group (group_id, user_ids) VALUES(2,3)
how can I prevent to insert duplicate user_ids
Is there any better query?

Yes, there is a better way to solve this problem, but the solution doesn't imply the query.
Instead of user_id column you should create a new column called user_id and add data like this:
id | group_id | user_id
1 | 1 | 3
2 | 1 | 4
3 | 2 | 3
4 | 2 | 4
5 | 2 | 2
6 | 3 | 2
7 | 3 | 3
8 | 3 | 4
This is called Many to Many relation and makes everything easier. After that you need to only JOIN the tables;

I think you want to start by creating unique index on the column that you want to have only unique values . In this case that it would be the user_ids column.

Related

MySQL query to return unique values in one column and sorted by id to get a PHP array

I have the following simplified table: (Note we skipped 2nd exam in the exam_id)
+----+---------+-------+
| id | exam_id | score |
+----+---------+-------+
| 1 | 1 | 15 |
| 2 | 1 | 20 |
| 3 | 1 | 68 |
| 4 | 3 | 92 |
| 5 | 3 | 10 |
+----+---------+-------+
I want to write an $sql and some php (I'm using Wordpress, and can use $wpdb) to be able to get the following:
$exam[3]=10
$exam[1]=68
Not that when there are multiple exams, we take the score entry which corresponds to the largest id
And $exam[2] is empty. In words, I'd like to save the last ever exam that the user attempted and show their score.
I've tried using Group By and
Try this
SELECT
*
FROM exams
WHERE exams.id IN (
SELECT
MAX(id)
FROM exams
GROUP BY exam_id
);

php, mysql join table columns with another table rows

I have issue getting results from two database table. here is what i have:
table A: 'courses'
math | history | geography | computer
1 | 2 | 3 | 4
and Table B
user_id | classroom_id | course
1 | 5 | 3
1 | 5 | 4
1 | 6 | 2
I returned the table A on a for each loop but I would like to check what courses the user 1 has to return true or false on any Table a columns.
Any help appreciated.
I need help not negative votes :(
You have your database set up wrong I believe. What you want is something like
Table_A:
PKEY | Course
1 | Math
2 | History
3 | Geography
4 | Computer
Table_B:
user_id | classroom_id | course
1 | 5 | 3
1 | 5 | 4
1 | 6 | 2
Then you could do something like
SELECT
TableA.PKEY,
TableA.Course,
TableB.user_id,
TableB.classroom_id,
TableB.course,
FROM TableA
LEFT JOIN TableB
ON TableA.PKEY = TableB.course
^^This will return the data from BOTH tables.
you see this line
ON TableA.PKEY = TableB.course
^^This is called the foreign key.
BIG GOTCHA: Make SURE that the columns for both of those ^^^ are set up EXACTLY the same. For instance, IF TableA.PKEY is an UNSIGNED INT(10), then TableB.course MUST also be UNSIGNED INT(10). They have to be identical for the join to work correctly.

Combining duplicate rows with different values in columns

I have a script written to import a CSV of my client's product inventory. The problem is there's a bug in the software they use to track their inventory that will duplicate a product with different values for their inventory.
So when I import the CSV they send me there are duplicate rows of the same product with different inventories. Example:
id | product | cases | unit
--------------------------------
1 | MF003 | 3 | 7
2 | MF004 | 5 | 6
3 | MF005 | 1 | 9
4 | MF005 | 7 | 2
5 | MF006 | 2 | 1
The MF005 product has two rows. What I need is this:
id | product | cases | unit
--------------------------------
1 | MF003 | 3 | 7
2 | MF004 | 5 | 6
3 | MF005 | 8 | 11
5 | MF006 | 2 | 1
You'll notice that MF005 is now one row with both cases and units added up correctly.
I suppose the better approach here would be to do this using a SELECT query instead of dealing with it beforehand via INSERT, but if there's a smarter way to do this by INSERTing, I'm definitely open to it.
You can insert and update at once:
CREATE TABLE importdata(
id INT,
product VARCHAR(200) DEFAULT "" PRIMARY KEY,
cases INT,
unit INT
);
INSERT INTO importdata(id,product,cases,unit) VALUES (3,"MF005",1,9) ON
DUPLICATE KEY UPDATE cases=cases+1, unit=unit+9;
Results in:
3 | MF005 | 1 | 9
Executing the second insert:
INSERT INTO importdata(id,product,cases,unit) VALUES (4,"MF005",7,2) ON
DUPLICATE KEY UPDATE cases=cases+7, unit=unit+2;
Results in:
3 | MF005 | 8 | 11

Assigned multiple users to a 'task'

Okay so I'm creating a task manager for my company. A user can assign assign a task to multiple other users. So I've though of 2 ways of implementing this.
This is my tasks table for option one (at least the columns that are important in this discussion ):
----------------------------------------------
| id | assigned_to | assigned_from |
---------------------------------------------
| 1 | 1,3,6 | 4 |
--------------------------------------------
| 2 | 1,4 | 2 |
---------------------------------------------
So here I pretty much just comma separate each user_id that is assigned to this particular task
Option 2:
----------------------------------------------------------
| id | task_id | assigned_to | assigned_from |
------------------------------------------------------------
| 1 | 335901 | 1 | 4 |
-----------------------------------------------------------
| 2 | 335901 | 3 | 4 |
-----------------------------------------------------------
| 3 | 335901 | 6 | 4 |
-----------------------------------------------------------
| 4 | 564520 | 1 | 2 |
-----------------------------------------------------------
| 4 | 564520 | 4 | 2 |
-----------------------------------------------------------
So as you can see here instead of putting the assiged_to is's here I just create a task id which is a random number and then I can groupBy 'task_id'. This is currently they way I have built it but for some reason it feels like it might screw me over in the future (not that option one doesn't give me the same feeling). So my question is which way do you guys recommend or is there maybe a different better way that I could be doing this?
Option 2 ist the better solution since you can acutally work with the table. You may e.g. create another table Tasks with
Task_id | Task_name | Budget | ...
Or a table with user-IDs for assigned_to and assigned_from. All these tables can be joined together if you use 2nd Option.
btw it is the correct normalization form
You can use Option 2 and normalize further if tasks are always assigned by/from the same person.
Tasks table:
task_id | assigned_from
1 | 4
2 | 2
The Assignees table then doesn't need to have the assigned_from since it's always the same for that task_id:
id | task_id | assigned_to
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 2 | 1
5 | 2 | 4

MySQL mylty sorting a table

I have a MySQL table users:
# | name | parent|
________________________
1 | USER 1 |
2 | USER 2 |
3 | user 12 | 1
4 | user 22 | 2
5 | user 11 | 1
6 | USER 3 |
7 | user 21 | 2
8 | user 31 | 6
Here the parent record is the primary key of the same table. What i need is to sort the table both parent-wise and name-wise.
This is the result that I need to get:
# | name | parent|
________________________
1 | USER 1 |
5 | user 11 | 1
3 | user 12 | 1
2 | USER 2 |
7 | user 21 | 2
4 | user 22 | 2
6 | USER 3 |
8 | user 31 | 6
If you only have one level of parents you can do:
select u.*
from users u
order by coalesce(parent, #), #;
(This assumes that the id of the parent is smaller than the id of the children, as is the case with the sample data in the question.)
If you have multiple levels of parents (grandparents and so on), then a single MySQL query is problematic. MySQL doesn't directly support hierarchical or recursive queries.
Although I do not know your use case, I think what you are doing is a symptom of poor design.
If possible, a rethink might be in order.
Nevertheless, I think this works
SELECT * FROM users
ORDER BY
CASE `parent`
WHEN NOT NULL THEN `parent`
ELSE SUBSTRING_INDEX(`users`.`name`, ' ', -1) END
ASC
Simple explanation:
Sorts by parent field if not null.
Otherwise use the number found in the name field (extracted by separating by the space).
Assumes number will always be separated by a space, and as with Gordon's answer, only works with a single parent.

Categories