Search Array values in comma Separated Column in Laravel - php

I have two tables (Assessments, Unit_Assigned). In Assessments table I store Multiple Unit Assigned Ids with comma-separated Format like below
id | title | assignedids
-------------------------
2 | NTitl | 15,25,6
-------------------------
3 | Ctitl | 25,6,38
Unit_Assigned Table display below
id | staffid | unit_id | batchid
---------------------------------
15 | 10 | 25 | 31
---------------------------------
38 | 12 | 18 | 42
---------------------------------
I need to get an assessment list based on staff ID (available in Unit_Assigned table)
I got assigned ids list using below query
$assignedunits=Unitassigning::Where('staffid',$staffid)->get()->pluck('id')->toArray();
try to fetch assessment using below query
$stringconverted=implode(",",$assignedunits);
$completedAssessments=Assessments::whereRaw("find_in_set('$stringconverted',assignedids)")->get();

Related

Finding inner join mysql with array [duplicate]

This question already has answers here:
How to join two tables using a comma-separated-list in the join field
(5 answers)
Closed 2 years ago.
I have two tables, First one is products where it has list of products with some specifications, in the other hand I have a table with clients and what type of product they want, they might want a product in any town of a list exactly as explained in the following tables,
Products Table like
| id | owner | userid | city | town | status | price |
| 1 | jon spee | 10 | 10 | 4 | 0 | 10500 |
| 2 | Hiss Roe | 10 | 7 | 9 | 0 | 20000 |
| 3 | John Smi | 10 | 10 | 12 | 0 | 10000 |
Clients Table like
| id | fullname | userid | city | towns | status | price |
| 1 | name 1 | 10 | 10 |4,8,6,2| 0 | 20000 |
| 2 | name 2 | 10 | 7 | 7,2,9 | 0 | 25000 |
| 3 | name 3 | 10 | 10 | 1 | 0 | 20000 |
MySQL Query :
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
clients.status = products.status
I want it to check also in towns like for each town it executs this query (dynamically),
(products.town LIKE '%4%' OR products.town LIKE '%8%' OR products.town LIKE '%6%' OR products.town LIKE '%2%')
You could go with this query
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
find_in_set(clients.town, products.town) AND
clients.status = products.status
you can also fetch it in php and create your statement based on the results fetched
Your primary effort should go into fixing your data model. Don't store multiple integer values in a string column. You should have a separate table to store the relation betwen clients and towns, which each tuple on a separate row.
That said: for your current design, you can join on find_in_set():
on
clients.userid = products.userid
and ...
and find_in_set(product.town, client.towns)

Best way to populate table from multiple MySQL database tables

I'm building a student score viewing table using MySQL in the backend. So far, I have two tables for this feature. activities contains the class code it belongs into, it's own unique activity code, a name, the max score of the activity, and when it was added as a UNIX timestamp. outputs refers to students' outputs per activity, containing the activity code, the student code, and the score.
TABLE activities
+----+------------+---------------+---------------+-----------+------------+
| id | class_code | activity_code | activity_name | max_score | time_added |
+----+------------+---------------+---------------+-----------+------------+
| 1 | Pq5H | xJDM | Seatwork 1 | 10 | 1578632389 |
+----+------------+---------------+---------------+-----------+------------+
| 2 | Pq5H | JXrA | Seatowrk 2 | 15 | 1578952035 |
+----+------------+---------------+---------------+-----------+------------+
| 3 | JXrA | b5Ud | Seatwork 1 | 10 | 1578975406 |
+----+------------+---------------+---------------+-----------+------------+
TABLE outputs
outputs.activity_code references activities.activity_code
+----+---------------+--------------+-------+
| id | activity_code | student_code | score |
+----+---------------+--------------+-------+
| 1 | xJDM | FAb1 | 10 |
+----+---------------+--------------+-------+
| 2 | JXrA | FAb1 | 14 |
+----+---------------+--------------+-------+
| 3 | xJDM | jIPA | 8 |
+----+---------------+--------------+-------+
| 4 | JXrA | jIPA | 12 |
+----+---------------+--------------+-------+
| 5 | Pq5H | FAb1 | 9 |
+----+---------------+--------------+-------+
| 6 | Pq5H | jIPA | 7 |
+----+---------------+--------------+-------+
On the frontend, I also have an editable table where users edit the score like so:
FOR CLASS Pq5H
+---------+------------+------------+
| Student | Seatwork 1 | Seatwork 2 |
+---------+------------+------------+
| FAb1 | 10 | 14 |
+---------+------------+------------+
| jIPA | 8 | 12 |
+---------+------------+------------+
In short, the column headers contain the activities for a specific class, the first row contains the students in that class, and the cells are the scores of the students in the corresponding columns.
The users would also be able to dynamically add columns which creates new activities, and when they save, the new scores would be added to the outputs table.
What would be the best way to go around (1) populating the HTML table and (2) saving output data from new HTML columns into the database? So far, all I found regarding this are populating HTML table rows with rows directly lifted from the database, which is not what I need in this case.
I'm using HTML, JS (with jQuery), PHP, and MySQL.
Get the data using
SELECT student_code,
activity_name,
score
FROM activities
[LEFT] JOIN outputs USING (activity_code)
WHERE class_code = ?
[ORDER BY 1,2]
and PIVOT it on the client side.
Alternatively get
SELECT student_code,
CONCAT('{', GROUP_CONCAT(CONCAT('"', activity_name, '":"', score, '"') SEPARATOR ',') , '}') scores_in_json
FROM activities
JOIN outputs USING (activity_code)
GROUP BY student_code
WHERE class_code = ?
[ORDER BY 1,2]
and convert JSON to PIVOT on the client side.

PHP, MYSQL, select results based on all values from 3 dropdowns being true

I have 2 drop-down lists and one select box, Country (dropdown), region (dropdown), gender (select box x 2).
my database looks like this (i have cut down the number of values)
| id | england | usa | west | north | male | female | name | age |
| 1 | 1 | 0 | 1 | 0 | 0 | 1 | John | 33 |
| 2 | 0 | 1 | 0 | 1 | 0 | 1 | John | 56 |
Apart from the ID and additional values each value i need to query will be 1 or 0 (true or false)
the result i need is if someone selects england, west, male it brings back every row which has those values as true (their is extra information on these rows i need to display)
I just need some pointers on how to achive this i was thinking of using a lookup table but am struggling to use lookup table with multiple values, or do i just use php and set each value to its correct row name and do a query like that
First of all
I suspect you are mixing the schema (column names) and the values up in your database.
Your table should be more like
|id | country |region | gender |
--------------------------------
| 1 | usa | north | male |
| 1 | england | south | female |
Think about what properties the thing has that you're trying to model.
You already kind of have this in your drop-downs. Each drop-down has a list of possible values for that property.
While you're at it, you should probably go further and split your data into more tables.
countries
|id | name | other | columns | about | countries | eg. iso_code|
------------------------------------------------------------------
| 1 | USA | .... | ..... | ..... | ...... | us |
| 2 | England| .... | ..... | ..... | ...... | uk |
regions
| id | name |
------------------
| 1 | north |
| 2 | south |
| 3 | east |
| 4 | west |
| 5 | south-west|
| .. | ....
users
|id | name | country_id |region_id | gender |
---------------------------------------------
| 1 | John | 1 | 1 | m |
| 2 | Mary | 2 | 4 | f |
You would then have to come up with ways of converting your data form the old system into the new.
First take over some of the data from the original table
INSERT INTO new_users (id,name) SELECT id, name FROM old_users;
This will insert the names with the same IDs as the original table in the new table.
Create the data for the lookup tables (country and region in this case)
INSERT INTO countries (name,iso_code) VALUES
('USA','us'),
('United Kingdom','uk'),
....
Then update your fields
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.country_id = 1 WHERE old_users.usa =1;
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.country_id = 2 WHERE old_users.england =1;
...
etc...
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.region_id = 1 WHERE old_users.north =1;
UPDATE new_users
FROM new_users INNER JOIN old_users ON old_users.id = new_users.id
SET new_users.region_id = 2 WHERE old_users.west =1;
...
Once you have that sorted...
Your drop-downs should be something like.. (you can generate the dropdowns automatically from your lookup tables (e.g. countries) by listing all the values with their names)
When you add new countries to the table, they will automatically appear in the drop-down from now on.
<?php
....
while ($resultrow = $result->fetch_assoc()){ ?>
<option value="<?php echo $resultrow['id'] ?>">
<?php echo $resultrow['name']; ?></option>
}
You should end up with something like the following in your html output.
<select>
<option value="1">USA</option>
<option value="2">UK</option>
</select>
Then your search query should look something like this:
$sql ="SELECT * FROM table
WHERE `country_id`= '$country_id'
AND `region_id`= '$region_id'
AND `gender`= '$gender'";

INSERT statement in joined table

I have 3 table:
tblNames:
| id | firstname | lastname |
+------+---------------+--------------+
| 1 | John | Smith |
tblJosbs (this table accepts multiple checkbox value at the same time):
| id | jobs |
+------+-----------------------+
| 1 | Nurse |
+------+-----------------------+
| 2 | Call Center Agent |
+------+-----------------------+
| 3 | Police |
tblNamesJobs (this table is used to JOIN the other 2 tables):
| id | name_id | jobs_id |
+------+-------------+-------------+
| 1 | 1 | 1 |
+------+-------------+-------------+
| 2 | 1 | 2 |
+------+-------------+-------------+
| 3 | 1 | 3 |
All is fine but can someone show me the INSERT statement for the 3rd table I should use to when I will add new information?
For example add record that John Smith is a Call Center Agent
insert into tblNamesJobs (name_id,jobs_id )
values (
select id from tblNames where
firstname='John'
and lastname='Smith' limit 1
,
select id from tblJosbs where jobs='Call Center Agent' limit 1
);
If you are already depending on tauto increment..you can get the lastinserid, depending on your adapter.
eg. mysql_insert_id
for PDO we can use --PDO::lastInsertId.
so you will have id's of earlier inserted tables, that you can save in the new one.
INSERT INTO tblNamesJobs (name_id, jobs_id) VALUES (XXXX,YYYY)
That is assuming the table's id is auto-incrementing.
It should be noted that both the name_id and jobs_id columns in the "joiner" table should be foreign keys to the respective columns in the other table.
Edit - Valex's answer goes into more detail about what to do if you don't already have the id values.
If possible, I would recommend using some sort of framework that would handle the "joiner" table for you.

how to find the highest value in mysql table

i have a mysql table i.e
st_id | name | email | maths | chemistry | bio | social_study
1 | john |#a.com | 20 | 23 | 10 | 15
my question is how can i find the highest subject score, the second last and so on
Note that all the subject fields have int(11) values
Break your database into 3 tables like:
Students:
st_id | name | email
1 | john |#a.com
Courses:
cr_id | name
1 | maths
2 | chemistry
3 | bio
4 | social_studies
StudentCourses:
st_id | cr_id | score
1 | 1 | 20
1 | 2 | 23
1 | 3 | 10
1 | 4 | 15
Now you can do:
SELECT s.name, MAX(sc.score) FROM Students s INNER JOIN StudentCourses sc ON s.st_id = sc.st_id;
SELECT * FROM <table>
ORDER BY <field> DESC
LIMIT <needed number of rows>
Example:
SELECT * FROM <table>
ORDER BY maths+chemistry+bio+social_study DESC
LIMIT 3
Strictly PHP method: I assume you want to maintain association with field names. In that case, just use asort($row); on each row in your query result, assuming you fetched the row as an array. asort will sort the array from lowest value to highest (with additional flags to tweak the results if needed), while maintaining keys. A foreach loop will then allow you to work with each key/value pair in the sorted order.
st_id | name | email | maths | chemistry | bio | social_study
1 | john |#a.com | 20 | 23 | 10 | 15
The query can be for top marks
SELECT id,GREATEST(mark,mark1,mark2) AS `top` FROM `students`

Categories