Laravel - update multiple records with different values - php

I have a table , similar to this:
| key | value |
|----------|-------|
| limit | 15 |
| viplimit | 25 |
| .. | |
And i have an array :
Array
(
[0] => Array
(
[key] => limit
[value] => 10
)
[1] => Array
(
[key] => viplimit
[value] => 99
)
...
Now , saying we have 100 rows. What would be the best way to update the table corresponding to the array ?
There would be the option of a query for each 100 row, but that is just bad performance.

This should work:
$statement = "UPDATE mytable
SET key = CASE id
WHEN 1 THEN 'key'
WHEN 2 THEN 'another_key'
WHEN 3 THEN 'some_key'
END,
value = CASE id
WHEN 1 THEN 15
WHEN 2 THEN 25
WHEN 3 THEN 45
END
WHERE id IN (1, 2, 3)
");
DB::statement($statement);
Just think how to create correct query. If it's admin panel or something that will be run not very often, I'd just use iteration to keep things simple.

Related

Providing the Custom Name to both Key and Value Pairs of an Array

I have a table named questions in the following form:
Table Name: questions
qn_id | question |
---------------------------------------------------------------
19 | What is your rating on your Team Work?
20 | What is your rating on your Skills?
21 | What is your rating on your Personal Quality?
I have another table named rating as shown below:
Table Name: rating
id | employee_id | question_id | self_score | supervisor_score
-----------------------------------------------------------------
1 | 205 | 19 | 4 | 3
2 | 205 | 20 | 5 | 4
3 | 205 | 21 | 4 | 5
Note: There are two people involved in providing the score. One is supervisee and another is supervisor.
The score provided by the supervisee is kept in the column named self_score. In the table, employee_id is the id of the supervisee. Supervisor also gives the rating to the supervisee for the same question as shown aboove in the table.
I have generated the data from the database as an Array which is shown below:
$params = Array
(
[selfscore_19] => 4
[supervisorscore_19] => 3
[selfscore_20] => 5
[supervisorscore_20] => 4
[selfscore_21] => 4
[supervisorscore_21] => 5
)
Note: In the key named [selfscore_19] , selfscore_ is the string and 19 is the question id.
Questions are same for both - 'self' and 'supervisor'.
So I have appended the strings named 'selfscore' and 'supervisorscore' with the question_id.
In the array shown below, key is: [selfscore_19] which has been appended with the question_id i.e 19 and
the value is score provided by 'self' which is 4.
And other data follows similar pattern.
Attempt:
The code below shows the attempt done by me so far:
Note: I have only shown the main part of the method.
foreach($params as $key => $value){
$exp_key = explode('_', $key);
if($exp_key[0]=='selfscore'){
$arr_result[] = $value;
}
}
foreach($params as $key => $value){
$exp_key = explode('_', $key);
if($exp_key[0]=='supervisorscore'){
$arr_result[] = $value;
}
}
if(isset($arr_result)){
echo '<pre>';
print_r($arr_result);
echo '<pre>';
}
This is the output of the above code:
Current Output:
Array
(
[0] => 4
[1] => 5
[2] => 4
[3] => 3
[4] => 4
[5] => 5
)
Now I want to tranform the Current Output in the form of following Output.
Although I have already researched about this case, but I am finding it a bit tricky.
What modification should I do to achieve the required output?
Suggestions are highly appreciated.
Required Output:
$score['self_score']=array(
array('question_id'=>19,'score'=>4)
array('question_id'=>20,'score'=>5)
array('question_id'=>21,'score'=>4)
);
$score['supervisor_score']=array(
array('question_id'=>19,'score'=>3),
array('question_id'=>20,'score'=>4)
array('question_id'=>21,'score'=>5)
);
Do it with a single loop. Use the first part of $exp_key as the key of the resulting array, and the second part as the value of the question_id key of the sub-array.
foreach ($arr_result as $key => $value) {
$exp_key = explode("_", $key);
$score[$exp_key[0]][] = array("question_id" => $exp_key[1], "score" => $value);
}
I think I'll recommend that you use a UNION to join two simple queries so that your initial resultset is very close to what you want (close enough to simply iterate and/or modify it).
SQL: (Demo)
(SELECT 'group' AS 'self_score', question_id, self_score
FROM rating
WHERE employee_id = 205
ORDER BY id)
UNION
(SELECT 'supervisor_score', question_id, supervisor_score
FROM rating
WHERE employee_id = 205
ORDER BY id)
Resultset:
group | question_id | self_score
------------------|---------------|------------
self_score | 19 | 4
self_score | 20 | 4
self_score | 21 | 5
supervisor_score | 19 | 3
supervisor_score | 20 | 4
supervisor_score | 21 | 5
If you are open to a PDO solution, fetchAll(PDO::FETCH_GROUP) will come in pretty handy.

Unserialize wordpress database to query data

I have a mysql database that looks like this
+----+----------+---------+----------------------------------+---------------------+
| id | field_id | user_id | value | last_updated |
+----+----------+---------+----------------------------------+---------------------+
| 1 | 1 | 1 | admin | yyyy-mm-dd hh:mm:ss |
| 3 | 5 | 1 | a:1:{i:0;s:2:"18";} | yyyy-mm-dd hh:mm:ss |
| 4 | 1 | 2 | testuser1 | yyyy-mm-dd hh:mm:ss |
| 5 | 5 | 2 | a:2:{i:0;s:2:"19";i:1;s:2:"18";} | yyyy-mm-dd hh:mm:ss |
+----+----------+---------+----------------------------------+---------------------+
I understand that a normal sql query will not be suitable so instead I need to pull all the data into php to then sort through it.
What I want is to get any user_id that has a number, lets say "19" in field_id 5. In that example, the array should read "2". Or I could search for "18" in field_id 5 and the array would return "1,2".
To get the database, I am using the following
<?php
global $wpdb;
$table_name = $wpdb->prefix . "bp_xprofile_data";
$retrieve_data = $wpdb->get_results( "SELECT * FROM $table_name" );
$strDB = maybe_unserialize( $retrieve_data);
echo print_r($strDB, true);
?>
Which returns:
Array ( [0] => stdClass Object ( [id] => 1 [field_id] => 1 [user_id] => 1 [value] => admin [last_updated] => 2017-09-21 12:38:20 ) [1] => stdClass Object ( [id] => 3 [field_id] => 5 [user_id] => 1 [value] => a:1:{i:0;s:2:"18";} [last_updated] => 2017-09-21 12:38:20 ) [2] => stdClass Object ( [id] => 4 [field_id] => 1 [user_id] => 2 [value] => testuser1 [last_updated] => 2017-09-23 01:43:50 ) [3] => stdClass Object ( [id] => 5 [field_id] => 5 [user_id] => 2 [value] => a:2:{i:0;s:2:"19";i:1;s:2:"18";} [last_updated] => 2017-09-23 01:43:50 ) )
I can't work out how I can then sort through this data. I tried to find sections of string but this was not working.
You should be able to use the LIKE comparison on the 'value' field, e.g.
SELECT * FROM $table_name AND value LIKE '%9%'
The difficulty with searching for a number is that LIKE will also return partial matches, so a query for 9 would also return 19, 91, 192 etc.
However, based on the values getting surrounded by double quoted in the serialised string, you should be able to search for the exact value by including the double quotes in the search string, e.g. "9".
Adding that into the code in your question, we get:
global $wpdb;
$num_to_find = 19; /* or change to whatever number you need */
$field_id_to_check = 5; /* or change to whatever number you need */
$table_name = $wpdb->prefix . "bp_xprofile_data";
$user_ids = $wpdb->get_results(
$wpdb->prepare(
"SELECT user_id FROM $table_name
WHERE field_id = %d AND value LIKE '%%\"%d\"%%'",
$field_id_to_check, /*this param replaces the 1st %d in the query */
$num_to_find /*this param replaces the 2nd %d in the query */
)
);
print_r($user_ids);
Note: because the query includes a variable and I don't know where its coming from, I've used $wpdb->prepare to sanitise the variable.
That's not tested, but I believe it should work!
Well, first rule – you should not do this. But if there is good reason, consider using such query for searching in index-based arrays
SELECT * FROM $table_name WHERE value REGEXP '.*;s:[0-9]+:"19".*'
Here we search on the column value the value "19" as you did on the example with a regex.
Regards.

Instead of php while loop and multiple connections to mysql want to connect only once

Example of mysql is here http://sqlfiddle.com/#!9/68653/2
Mysql table (named topics)
TopicId | TopicName | ClosestUpperLevelId
--------------------------------------------
1 | Books | 0
2 | BooksAboutCss | 1
3 | BooksAboutHtml | 1
4 | BooksAboutCss1 | 2
5 | BooksAboutCss2 | 2
6 | BooksAboutHtml1 | 3
7 | BooksAboutHtml2 | 3
8 | E-Books | 0
9 | Magazines | 0
For top level topics ClosestUpperLevelId is 0. For subtopics ClosestUpperLevelId is TopicId of closest upper level topic
(TopicId - ClosestUpperLevelId)
Books (1-0)
BooksAboutCss (2-1)
BooksAboutCss1 (4-2)
BooksAboutCss2 (5-2)
BooksAboutHtml (3-1)
BooksAboutHtml1 (6-3)
BooksAboutHtml2 (7-3)
E-Books (8-0)
Magazines (9-0)
For example, i have created one page and location of the page is domain.com/Books/BooksAboutCss/BooksAboutCss2
Now i decided to edit the page. For example i want to edit location (topic or category) of the page and set it to domain.com/Magazines. So i need to fetch all topics, related with existing (saved) page. Then will create select boxes for each group (level) of topics.
At the moment tried to use php while and multiple times to connect to mysql and get data. Like below code. How can i get the same result without php while? How connect to mysql only once and fetch all necessary data? Do i need to use mysql while https://dev.mysql.com/doc/refman/5.1/en/while.html?
$topic_names_1[0]['UpperLevelNumberRenamed'] = 5;//just set some value to start to fetch
while ( trim($topic_names_1[0]['ClosestUpperLevelId']) != 0 ){
try {
$stmt_1 = $db->prepare('
SELECT `TopicId`, `TopicName`, `ClosestUpperLevelId`
FROM `topics`
WHERE `ClosestUpperLevelId` =
(
SELECT `ClosestUpperLevelId`
FROM `topics`
WHERE `TopicId` = ?
)
;');
$stmt_1->execute( array( trim($topic_names_1[0]['UpperLevelNumberRenamed']) ) );
$topic_names_1 = $stmt_1->fetchAll(PDO::FETCH_ASSOC);
echo '<pre>', print_r($topic_names_1), ' topic_names_1 __</pre>';
}//try {
catch (PDOException $e){
echo "<br> stmt_1 DataBase Error: " .htmlspecialchars( $e->getMessage() , ENT_QUOTES, "UTF-8").'<br>';
}
catch (Exception $e) {
echo " stmt_1 General Error: ".htmlspecialchars( $e->getMessage() ).'<br>';
}
}//while ( trim($topic_names[0]['UpperLevelNumberRenamed']) != 0 )
As result get arrays like this
Array
(
[0] => Array
(
[TopicId] => 4
[TopicName] => BooksAboutCss1
[ClosestUpperLevelId] => 2
)
[1] => Array
(
[TopicId] => 5
[TopicName] => BooksAboutCss2
[ClosestUpperLevelId] => 2
)
)
1 topic_names_1 __
Array
(
[0] => Array
(
[TopicId] => 2
[TopicName] => BooksAboutCss
[ClosestUpperLevelId] => 1
)
[1] => Array
(
[TopicId] => 3
[TopicName] => BooksAboutHtml
[ClosestUpperLevelId] => 1
)
)
1 topic_names_1 __
Array
(
[0] => Array
(
[TopicId] => 1
[TopicName] => Books
[ClosestUpperLevelId] => 0
)
[1] => Array
(
[TopicId] => 8
[TopicName] => E-Books
[ClosestUpperLevelId] => 0
)
[2] => Array
(
[TopicId] => 9
[TopicName] => Magazines
[ClosestUpperLevelId] => 0
)
)
1 topic_names_1 __
Update
Found one example with mysql while. Trying to create own code
Created this
SET `ClosestUpperLevelId` := 2;
WHILE `ClosestUpperLevelId` > 0
DO
SELECT `TopicId`, `TopicName`, `ClosestUpperLevelId`;
END WHILE;
and this (http://sqlfiddle.com/#!9/68653/7)
CREATE PROCEDURE dowhile()
BEGIN
DECLARE `ClosestUpperLevelId` INT DEFAULT 2;
WHILE `ClosestUpperLevelId` > 0 DO
SELECT `TopicId`, `TopicName`, `ClosestUpperLevelId`;
END WHILE;
END;
Got error...
You could just move your select statement before the while loop and take out the topic_id from the where clause. Then in your loop retrieve from the complete record set using an array search function or similar. By running same query once your dB will be able to cache results
Relational databases like MySQL aren't naturally good at storing hierarchical data, but there are ways of doing it. The two ways I know of are "adjacency lists" and "nested sets".
For an adjacency list, you'd simply store a "parent_id" field for each row. Root rows (that have no parent) can just have NULL for their parent_id field. Adjacency lists are easy to manage, but not very flexible and require recursive queries to find a path from root to leaf (unless you're only going 2 levels deep, then you can simply JOIN).
Here's an example:
id | parent_id | name
0 NULL grandfather
1 0 father
2 1 grandson
3 1 granddaughter
This query would help assemble the data:
SELECT * FROM
`people` AS p1
JOIN `people` p2
ON p1.id = p2.parent_id
Any more than those two levels and you need recursion. Alternatively, you could just query the entire table and assemble it in code.
Nested sets are a little more complicated, but allow you to easily query all the way up the tree for a given leaf node. It's much easier to understand nested sets at first by seeing a visual, check this out:
https://en.wikipedia.org/wiki/Nested_set_model
And here's what your schema would look like:
left | right | name
0 7 grandfather
1 6 father
2 3 grandson
4 5 granddaughter
And here's an example to fetch father and children:
SELECT *
FROM `people`
WHERE `left` >= 1 AND `right` <= 6
Nested sets have the downside that the entire table's left and right values need to be updated when the hierarchy changes.
Google "managing hierarchical data in mysql" for more information. I hope this helps.

mysql select where in array (php, mysql)

Lets say i have an array in my mysql row:
a:3:{i:1;a:3:{i:0;s:1:"1";i:1;s:1:"3";i:2;s:1:"5";}i:4;a:3:{i:0;s:2:"21";i:1;s:2:"25";i:2;s:2:"29";}i:5;a:1:{i:0;s:2:"33";}}
It looks like this:
Array
(
[1] => Array
(
[0] => 1
[1] => 3
[2] => 5
)
[4] => Array
(
[0] => 21
[1] => 25
[2] => 29
)
[5] => Array
(
[0] => 33
)
)
Now, i am passing an array through _GET and i want to print out all rows that contain same values both in my mysql and passed array. For example, if i pass this array:
Array
(
[1] => Array
(
[0] => 5
)
)
A result should be shown, because my passed array contains option 5. I tried to do it like this:
$pecul = serialize($array);
$q=mysql_query("SELECT id from table WHERE options like '%$pecul%'")or die(mysql_error());
but it only prints out results with identical arrays.
You probably want to unserialize the data that's in your database first. Once it's in a PHP array you can perform a check for those options, so say:
if(in_array("5",$array)) {
$q=mysql_query("SELECT id from table WHERE options=5")or die(mysql_error());
}
If you need to do a query for all of the options, you can do a loop like so:
foreach($array as $option) {
$q=mysql_query("SELECT id from table WHERE options='$option'")or die(mysql_error());
}
But like mario said, you may want to think the options mechanism over and perhaps serialized data isn't what you need. This should hopefully work for you the way it is though.
the like operator match only match same it does not understand for example you have dem in like than it will also show the demolish so
i think for that you need first unserlize and than find by php by either loop or in_array() function
what %like% do suppose this is table Persons and you used the query
SELECT * FROM Persons WHERE City LIKE '%tav%'
+-------------+-------------+
| id | city |
+-------------+-------------+
| 1 | Sandnes |
+-------------+-------------+
| 2 | Stavanger |
+-------------+-------------+
so the result will be
+-------------+-------------+
| id | city |
+-------------+-------------+
| 2 | Stavanger | <----it has tav (s-tav-anger)
+-------------+-------------+
IN() Check whether a value is within a set of values
mysql> SELECT 2 IN (0,3,5,7);
-> 0
mysql> SELECT 'wefwf' IN ('wee','wefwf','weg');
-> 1
SELECT val1 FROM tbl1 WHERE val1 IN (1,2,'a');
View: IN MySql

how to get value in array from individual query

i have a
Book ID Array
Array
(
[0] => 61
[1] => 72
[2] => 78
[3] => 100
[4] => 102
)
now from another table table_bookPrice where price filed is given
i want that select all price from table_bookPrice where book id is in given array (book ID Array) and if price is not mentioned in table_bookPrice field then it would be automatic 500
what will be exact query
so the array i got is like this
Book Price Array
Array
(
[0] => 150
[1] => 100
[2] => 500 ( not mentioned in table, so it is 500)
[3] => 300
[4] => 200
)
I am at work so could not test or compile it, but I hope my logic is understandable.
Not sure if this will work but something along these lines
$book_price_array = array(); //contents to be added.
// loop through the array an examine its price by querying your table.
foreach ($book_id_array as $key => $value) {
$price = mysql_query("SELECT price FROM table_bookPrice
WHERE book_id = {$value}");
// there is a price, set the price.
if ($price > 0 && $price != NULL) $book_price_array[$key] = $price;
// there is no price, set the default price
else $book_price_array[$key] = 500;
}
Here's the test database I built for your problem:
mysql> select * from table_bookPrice;
+----+-------+--------+
| id | price | bookid |
+----+-------+--------+
| 1 | 150 | 61 |
| 2 | 100 | 72 |
| 3 | 300 | 100 |
| 4 | 200 | 102 |
+----+-------+--------+
4 rows in set (0.00 sec)
Here's the PHP code:
<?php
$books=array(61,72,78,100,102);
// establish an assoc array of bookid => default_price
$prices=array();
foreach($books as $bookid){
$prices["$bookid"]=500;
}
// build query to select all prices stored in database
$bookids=implode(', ',$books);
mysql_connect('localhost','aj','nothing') or die('unable to connect!');
mysql_select_db('books') or die('unable to select db!');
$stmt="SELECT bp.bookid, bp.price FROM table_bookPrice bp WHERE bp.bookid IN ($bookids)";
$res=mysql_query($stmt);
while( ($rec= mysql_fetch_assoc($res)) ){
$idstr=(string)$rec['bookid'];
$prices[$idstr]=$rec['price'];
}
print_r($prices);
?>
This outputs:
Array
(
[61] => 150
[72] => 100
[78] => 500
[100] => 300
[102] => 200
)

Categories