php script to move data between columns with mysql - mysql

What I want to achieve is to move the data between 2 rows within one table.
Column A
--------
FN2
1 200x310mm
2 400x260mm[+0.84]
3 500x500mm[+11.34]
Column B
--------
0.0000
0.0000
0.0000
0.0000
This is how it should look like after the data move:
Column A
--------
FN2
1 200x310mm
2 400x260mm
3 500x500mm
Column B
--------
0.0000
0.0000
+0.84
+11.34
What I want is that the query between the [ ] is moved to column B and replaces the 0.0000
How can I achieve this?
Kind Regards

just to illustrate what Yadav said
$query = "SELECT columnID, columnA FROM table";
$result = mysql_query($query,$conn);
while ($row = mysql_fetch_array($result)){
$id = $row['columnID'];
$a = $row['columnA'];
$pos1 = strpos($a,"[")+1;
$pos2 = strpos($a,"]");
$b = substr($a,$pos1,$pos2-$pos1);
$query = "UPDATE table SET columnB = $b WHERE columnID = $id";
mysql_query($query,$conn);
}//end while
edit: Yadav obviously proposed a better answer while I was typing mine...

try this it works for you here i used id as unique key ... and test is my database
<?php
$con=mysql_connect("localhost","root","");
$db=mysql_select_db("test");
$query=mysql_query("SELECT * FROM test where columnA LIKE '%[%]'");
while($row=mysql_fetch_assoc($query))
{
if(preg_match_all('/\[(.*?)\]/',$row['columnA'],$match))
{
mysql_query("UPDATE test SET columnB='".$match[1][0]."' WHERE id=".$row['id']."");
}
}
?>

Related

How do I count multiple columns with a vertical value?

I'm new to programing. I have table
check_1,check_2,check_3 ..etc
------------------------------
1 1 1
0 0 1
1 0 1
And I want this output :
column_name, count_true
-----------------------
check_1 2
check_2 1
check_3 3
I've tried it with mysql using the union function, but when I try to apply it in laravel I have trouble with union. Is there a unionless query that can produce such output?
Thanks in advance
You can do this way. One query in db
$records = DB::table('your_table')->get();
$check1Count = $records->where('check_1', 1)->count();
$check2Count = $records->where('check_2', 1)->count();
$check3Count = $records->where('check_3', 1)->count();
......
Or
$records = DB::table('your_table')->get();
$columns = ['check_1', 'check_2', 'check_3', ...];
$data = [];
foreach($columns as $column) {
$data[] = [
'column_name' => $column,
'count_true' => $records->where($column, 1)->count();
];
}
Also you can do this way but it is many query
$check1Count = DB::table('your_table')
->selectRaw('COUNT(check_1) as count')
->where('check_1', 1)
->first()
->count;
$check2Count = DB::table('your_table')
->selectRaw('COUNT(check_2) as count')
->where('check_2', 1)
->first()
->count;
.....
A normalised approach might look like this:
response_id checkbox
1 1
1 2
1 3
2 3
3 1
3 3
You don't need union, just query all the data and process it on Laravel. Let say you query all the data using eloquent to $data variable, then you should do it like this:
//preparing a variable to hold all 24 database field value
$total = [];
foreach ($data as $d) {
//do this for all 24 database field
if ($d->check_1) {
$total[1]++;
}
if ($d->check_2) {
$total[2]++;
}
...
}
By using that way you can't check the resutl on $total[index] variable. And yes, there is a better way to store your data instead of saving all the field for each user. You can just store all checked value in database that look like this :
user_id checkbox_id
1 3
1 5
1 9
1 24
2 23
3 2
3 3
It more efficient since you don't need to save the unchecked checkbox value, if they more likely not to checked most of the checkbox.

Getting an empty result for newQuery

I've a problem in getting the value of the query $scholars for $lt = $scholars->lat.The result is empty array for dd($lt);
.Any help would be helpful to my school project.
database of Scholar
id lat lng scholar_birthday scholar_GPA
1 10.275667 123.8569163 1995-12-12 89
2 10.2572114 123.839243 2000-05-05 88
3 9.9545909 124.1368558 2002-05-05 89
4 10.1208564 124.8495005 2010-05-05 85
$scholars = (new Scholar)->newQuery()->select('*');
$scholars->whereBetween(DB::raw('TIMESTAMPDIFF(YEAR,scholars.scholar_birthday,CURDATE())'),array($ship_age_from,$ship_age_to));
$scholars->whereBetween(DB::raw('scholar_GPA'),array($ship_gpa_from,$ship_gpa_to));
$lt = $scholars->lat;
$lg = $scholars->lng;
$str = $lt.','.$lg;
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.trim($lt).','.trim($lg).'&sensor=false';
$json = #file_get_contents($url);
$data=json_decode($json);
$status = $data->status;
$data->results[0]->formatted_address;
dd($lt);
$scholars = $scholars->get();
dd Result
Undefined property: Illuminate\Database\Eloquent\Builder::$lat
Two things,
when you use the newQuery() you will still need to get() the result like such
$scholars = (new Scholar)->newQuery()->select('*')->get();
This however will retrieve a collection and not a single result so you will need to loop over this.
foreach($scholars as $scholar){
$lt = $scholars->lat;
dd($lt);
}

Friends of a user + mutual friend test with another user

I have this table that I use (but not only) for storing friends in a database :
user_1 | user_2 | status
where 'status' can be -1,0 or 1. Here, we will consider only cases where status are '0' (pending for user_1) or '1' (approved by user_2). I have the following query to look for pending/approved friends for a given $user :
SELECT user_1,user_2,status
FROM Friends
WHERE (user_2 = '$user' OR user_1 = '$user') AND status >= 0;
The goal here is to modify the query to also tell if a given $user2 is a common (approved) friend of $user1 and each (approved) friend of $user1.
After some researches, I figured out that the left join would do the trick, by setting another field to either NULL (if no mutual) or $user2. I would want to do it efficiently. I tried several shots, but no success around it.
Thanks by advance for your help
EDIT : For example, let's say we have the following entries :
a | b | 1
c | a | 1
c | b | 1
a | d | 1
I want to list the friends of 'a' and for each friend f of 'a', verify if 'b' is a common friend of f and 'a'. Also, f =/= b for the mutual test. The result of such a query would be :
a | b | 1 | NULL
c | a | 1 | b
a | d | 1 | NULL
Let me know if you need more clarification
As in MySQL query would be so complicated and slow, that I wouldn't use it myself, here's a solution in PHP, with only one query:
<?php
// $db = mysqli_connect(...);
function findMutualFriends($of,$mutual_with){
global $db;
$user_friends = array();
$mutual_friends = array();
$results = array();
$res = mysqli_query($db,"SELECT user_1,user_2,status FROM Friends WHERE ((user_2 = '$of' OR user_1 = '$of') OR (user_2 = '$mutual_with' OR user_1 = '$mutual_with')) AND status >= 0;";
while($row = mysqli_fetch_assoc($res)){
if($row['user_1'] == $of || $row['user_2'] == $of){
$user_friends[] = (($row['user_1'] == $of) ? $row['user_2'] : $row['user_1']);
}
if($row['user_1'] == $mutual_with || $row['user_2'] == $mutual_with){
$mutual_friends[(($row['user_1'] == $mutual_with) ? $row['user_2'] : $row['user_1'])] = 1;
}
}
foreach($user_friends as $friend){
if($mutual_firends[$friend]){
$results[] = $friend;
}
}
return $results;
}
?>
Please notice that it haven't been tested. May contain some minor syntax error, but should return an array of mutual friends.
I modified a bit the Flash Thunder's function post. Just tested with some modifications and it works ! Thanks again.
function findMutualFriends($pdo, $of,$mutual_with){
$user_friends = array();
$mutual_friends = array();
$results = array();
$query = "SELECT user_1,user_2,status FROM Friends WHERE ((user_2 = '$of' OR user_1 = '$of') OR (user_2 = '$mutual_with' OR user_1 = '$mutual_with')) AND status = 1;";
$prep = $pdo->prepare($query);
$res = $prep->execute();
$rows = $prep->fetchAll();
foreach ($rows as $row) {
if($row['user_1'] == $of || $row['user_2'] == $of) {
$user_friends[] = ($row['user_1'] == $of ? $row['user_2'] :$row['user_1']);
}
if($row['user_1'] == $mutual_with || $row['user_2'] == $mutual_with) {
$mutual_friends[($row['user_1'] == $mutual_with ? $row['user_2'] :$row['user_1'])] = true;
}
}
foreach($user_friends as $friend) {
$results[$friend] = $mutual_friends[$friend] == true ? true : false;
}
return $results;
}

Binary search in a MySQL table with deleted rows PHP

I have a large MySQL table with sorted data. When I need to find a starting point, I perform a binary search to find the lower bound ID (auto increment). The only problem is once some data is deleted, I need to look at the first existing row with a lower ID if the ID given by the algorithm doesn't exist. How should I modify this code to achieve that?
$l = 1;
$h = $max; //SELECT MAX(id)
while ($h - $l > 1){
$m = ($h + $l) / 2;
$q = mysqli_query($db, "SELECT col FROM tab WHERE id=". floor($m));
$result = array();
while($result[] = mysqli_fetch_row($q)){;}
if ($result[0][0] < $val) $l = $m;
else $h = $m;
}
echo round($m);
For example I want to find which rows have the value of col greater than 12345 and the table has max ID 10000. I start by looking at row 5000, where the col = 9000, then 7500 (col = 13000), then 6250 has been deleted, so I start looking for the 1st existing row with ID < 6250 and I find that 6245 has col = 10500. Now I'm looking between IDs 6873 and 7500 etc.
The right way to do this
So you have a table like this:
| ID | col |
---------------
| 1 | 15 |
| 3 | 155 |
| 18 | 9231|
| 190 |14343|
| 500 |16888|
You can get find 14343 with the following query:
SELECT ID, col FROM the_table WHERE col>12345 LIMIT 1;
To make it faster, you'd need to add an index (index word is worth googling)
ALTER TABLE `the_table` ADD INDEX `col` (`col`);
After that mysql will create a tree structure internally and will be doing binary searches on it for you.
This will be working much faster as you'll avoid multiple network roundtrips + other per request expenses (query parsing, optimization, all the locks & mutexes, ...)
Answer to your question
I need to look at the first existing row with a lower ID
E.g. you'd like to get first row with an ID < than 300, you do this (limit is what makes the query return only 1 result):
SELECT col FROM the_table WHERE ID < 300 LIMIT 1;

Symfony combinate 2 queries

I would like to get max date from other query insert to current query. Look at my codes pls.
Data:
inv_id inv_date inv_export inv_code
1 2016-03-14 0 a2
2 2016-03-13 0 a1
3 2016-04-13 1 a1
4 2016-03-14 0 a1
Result:
for inv_export = 0 return a2 & a1
for inv_export = 1 return a1
mysql (working fine):
SELECT ..., i.inv_date, i.inv_export
FROM Sp.inventory AS i
...
WHERE i.inv_date IN (
SELECT max(i.inv_date) from Sp.inventory WHERE i.inv_export = 1
);
I have tried convert it to symfony:
$qb = $this
->createQueryBuilder('i')
->select('..., i.invDate')
...
->where('i.invExport = :export AND i.invDate = MAX(i.invDate)')
->setParameter('export', $export);
You can use a subquery as follow:
$sub = $this->createQueryBuilder('i2');
$sub->select("max(i2.inv_date)");
$sub->where("i.invExport= i2.invExport");
$qb = $this
->createQueryBuilder('i')
->select('..., i.invDate')
...
->where('i.invDate = ( '.$sub->getDQL().' )');
->andWhere('i.invExport = :export')
->setParameter('export', $export);
hope this help