I have a table named 'traffic' and two columns 'line' (there are over 50 lines) and 'vehicle' (over 300). This table contains a list of all of the lines and the vehicle they depend on. Each line has several vehicles and I need to group them (vehicles) in columns by line.
line | vehicle
______________________
line_a | veh1
line_a | veh12
line_a | veh123
line_b | veh14
line_b | veh15
line_b | veh16
line_c | veh17
line_c | veh18
Expected Output
line_a | line_b | line_c | .... to line 50
______________________________________
veh1 veh14 veh17
veh12 veh15 veh18
veh123 veh16
Any way to do this?
load all to php arrays
iterate once and collect unique lines via $helparr[$line]=array(), but also collect values per line array_push($helparr[$line],$vehicle)
iterate again: for all $helparr (output $line, for all $helparr[$line] (output $vehicle))
...guess, half of your coding work is done now...
first of all you need to fetch all the records from your database,
here i'm using a demo array $input just for example, you do not need this array when you are fetching from database, you can start from foreach
<?php
$input = array(0=>array('line'=>'line_a','vehicle'=>'veh1'),
1=>array('line'=>'line_b','vehicle'=>'veh2'),
2=>array('line'=>'line_c','vehicle'=>'veh6'),
3=>array('line'=>'line_a','vehicle'=>'veh5'),
4=>array('line'=>'line_c','vehicle'=>'veh9')
);
$newArr =array();
foreach($input as $key =>$val)
{
$newArr[$val['line']][] = $val['vehicle'];
}
echo "<pre>"; print_r($newArr);
?>
your $newArr looks like this
Array
(
[line_a] => Array
(
[0] => veh1
[1] => veh5
)
[line_b] => Array
(
[0] => veh2
)
[line_c] => Array
(
[0] => veh6
[1] => veh9
)
)
your vehicles are sorted according to their respective lines and you can use $newArray to print according to your need.
I hope this will work for you!
Related
Hello This may looks to be simple task but I am getting struck... In my application i am getting an array which would be like
Array
(
[0] => Array
(
[home_id] => 1
[distance] => 12
)
[1] => Array
(
[home_id] => 3
[distance] => 14
)
[2] => Array
(
[home_id] => 94
[distance] => 1.679713069
)
.
.
.
.
)
And my table looks like
home_id | home_name
1 | My home 1
2 | My home 2
3 | My home 3
From this array i will get the home_id which is in database table. So How can i get the result details which includes the home_name and the distance from the first array which might be like
home_name | distance
___________________________
My home 1 | 0.562620830044
My home 3 | 14
Thank you in advance
Loop through your array and get the home_name from database using codeigniter active record query -
foreach($yourArray as $row)
{
$id = $row['home_id'];
$distance = $row['distance'];
$db_result = $this->db->get_where('yourtable', array('home_id' => $id));
if($db_result && $db_result->num_rows() > 0){
$result = $db_result->row();
$home_name = $result->home_name;
}
}
If you cannot JOIN the two tables in one query and have to use that array then you can do:
foreach($yourArray as $home)
{
$id=$home["home_id"];
$distance=$home["distance"];
$id=intval($id);
$sql="SELECT home_name FROM yourTable WHERE home_id=$id"; // execute this query to get name
}
From this array i will get the home_id which is in database table. So How can i get the result details which includes the home_name and the distance from the first array which might be like
If you want to get home details from table home_details_table using the id you get from the main array, so replace the field home_namein home_details_table by home_id and link both tables as a One to Many relation.
home_table:
home_id | home_name
1 | My home 1
2 | My home 2
3 | My home 3
home_detail_table:
home_id | distance
1 | 0.562620830044
3 | 14
Then with a JOIN, you will be able to do :
foreach($mainArray as $home)
{
$id = $home["home_id"];
$sql="SELECT h.home_id, h.home_name, d.home_distance FROM home_table h JOIN home_details_table d ON h.home_id = d.home_id WHERE h.home_id = ".$id;
// with this query you will have the name and distance of the given home id.
}
Questions
How should I do the query(ies) to get this results?
Should I use a different structure for database tables?
Details
I want to get results from 3 tables:
+------------------------------+-------------------+
| courses | id | <-------+
| | name | |
| | | |
+------------------------------+-------------------+ |
| sections | id | <-------|----------+
| | course_id | <- FK(courses.id) |
| | name | |
+------------------------------+-------------------| |
| resources | id | |
| | section_id | <- FK(sections.id)-+
| | name |
+------------------------------+-------------------+
I want to store results in a PHP Array like this:
Array
(
[courses] => Array
(
[id] => 1
[name] => course 1
[sections] => Array
(
[0] => Array
(
[id] => 1
[course_id] => 1
[name] => course 1 section 1
[resources] => Array
(
[0] => Array
(
[id] => 1
[section_id] => 1
[name] => resource 1
)
)
)
)
)
)
EDIT
What I did:
$cources = DB::query(Database::SELECT,
'select * from courses')->execute($db,false)[0]; // Get all courses as array
foreach($courses as &$course) {
$sections = DB::query(Database::SELECT,
'select * from sections where course_id = '.$courses['id']);
$course['sections'] = $sections;
foreach($course['sections'] as &§ion) {
$resources = DB::query(...); // Get array of resources
$section['resources'] = $resources;
}
}
The database structure is normalized - this is correct and should not be changed.
However, SQL returns de-normalized or "flattened" data for an N+ join: only a set of homogenous records can be returned in a single result-set. (Some databases, like SQL Server, allow returning structure by supporting XML generation.)
To get the desired array structure in PHP will require:
Separate queries/result-sets (as shown in the post): ick!
There will about one query/object. While the theoretical bounds might be similar, the practical implementation will be much less efficient and the overhead will be much more than for single query. Remember that every query incurs (at the very least) a round-trip penalty - as such, this is not scalable although it will likely work just fine for smaller sets of data or for "time insensitive" operations.
Re-normalize the resulting structure:
This is very trivial to do with support of a "Group By" operation, as found in C#/LINQ. I am not sure how this would be approached [easily] in PHP1. This isn't perfect either, but assuming that hashing is used for the grouping, this should be able to scale fairly well - it will definitely be better than #1.
Instead of the above, consider writing the query in such a way that the "flat" result can be used within the current problem/scope, if possible. That is, analyze how the array is to be used - then write the queries around that problem. This is often a better approach that can scale very well.
1 Related to re-normalizing the data, YMMV:
SQL result to PHP multidimensional array
PHP array to multidimensional array
Group a multidimensional array by a particular value?
You can try something like this
SELECT * FROM (
select c.id, c.name from courses c
union
select s.id, r.name,s.course_ID from sections s
union
select r.id, r.name,r.section_ID from resources r
)
You cant get multi dimensional result from mysql. The query for getting the elements should be like this:
select courses.id as coursesId,courses.name as coursesName,sections.id as sectionsId,sections.name as sectionsName,resources.id as resourcesId, resources.name as resourcesName
from courses
left join sections on courses.id=sections.course_id
left join resources on sections.id=resources.section_id;
But ofcourse it will not give you the array as you like.
if you are familiar with php then you can use this code i am writing only 2nd level you can write same way with third label
$final=array();
$c=-1;
$cid=false;
$cname=false;
$query = "SELECT c.*,s.*,r.* FROM courses AS c LEFT JOIN sections AS s ON c.id=s.course_id LEFT JOIN resources AS r ON r.section_id =s.id";
$result=mysql_query($query, $this->con) or die(mysql_error());
while($row= mysql_fetch_array($result)){
if($cid!=$row[2]){
$final['cources'][++$c]['id']=$cid=$row[0];
$final['cources'][$c]['name']=$cname=$row[1];
$s=-1;
}
$final['cources'][$c]['sections'][++$s]['id']=$row[2];
$final['cources'][$c]['sections'][$s]['course_id']=$row[3];
$final['cources'][$c]['sections'][$s]['name']=$row[4];
}
echo "<pre>";
print_r($final);
echo "</pre>";
//Outpur
Array
(
[cources] => Array
(
[0] => Array
(
[id] => 1
[name] => c1
[sections] => Array
(
[0] => Array
(
[id] => 1
[course_id] => 1
[name] => s1-1
)
[1] => Array
(
[id] => 1
[course_id] => 1
[name] => s1-1
)
)
)
[1] => Array
(
[id] => 2
[name] => c2
[sections] => Array
(
[0] => Array
(
[id] => 2
[course_id] => 2
[name] => s1-2
)
)
)
)
)
In a text file, I have the folowing strings :
ID | LABEL | A | B | C
--------------------------------------
9999 | Oxygen Isotopes | | 0.15 | 1
8733 | Enriched Uranium | | 1 | 1
I would like to extract the fields ID and LABEL of each line using regular expression.
How I can achieve it ?
I am not certain why you insisted on regex.
As the column appear to be separated by | symbol, it seems like using PHP function explode would be an easier solution.
You would be able loop through the lines, and refer to each column using typical array index notation, for example: $line[0] and $line[1] for ID and LABEL respectively.
I doubt regex is the best solution here.
Try this to separate the text file into an array of lines (this might or might not work, depending on the OS of the machine you created the txt file on)
$lines = explode($text, "\n");
$final_lines = array();
foreach ($lines as $line) {
$parts = explode($line, " | ");
$final_lines[] = $parts;
}
Now you can access all of the data through the line number then the column, like
$final_lines[2][0]
Will contain 8733.
You could use preg_split on every line:
$array = preg_split(`/\s*\|\s*/`, $inputLine, 2);
Then as in djdy's answer, the ID will be in $array[0] and the label in $array[1].
No regex needed:
<?php
$file = file('file.txt');
$ret = array();
foreach($file as $k=>$line){
if($k<2){continue;}
list($ret['ID'][],
$ret['LABEL'][],
$ret['A'][],
$ret['B'][],
$ret['C'][]) = explode('|',$line);
}
print_r($ret);
//Label: Oxygen Isotopes ID:9999
echo 'Label: '.$ret['LABEL'][0].' ID:'.$ret['ID'][0];
/*
Array
(
[C] => Array
(
[0] => 1
[1] => 1
)
[B] => Array
(
[0] => 0.15
[1] => 1
)
[A] => Array
(
[0] =>
[1] =>
)
[LABEL] => Array
(
[0] => Oxygen Isotopes
[1] => Enriched Uranium
)
[ID] => Array
(
[0] => 9999
[1] => 8733
)
)
*/
?>
Regular expressions might not be the best approach here. I'd read in each line as a string, and use String.explode("|", input) to make an array of strings. The 0 index is your ID, the 1 index is your label, and so on for A, B, and C if you want. That's a more robust solution than using regex.
A regular expression that gets the ID might be something like
\d{4} |
You could do something similar for the label field, bug again, this isn't as robust as just using explode.
Though its not a best approach to use regular expression here but one may be like this
preg_match_all("/(\d{4}.?)\|(.*?)\|/s", $data, $matchs)
2nd and 3rd index of $matches will carry the required data
Try
$str = file_get_contents($filename);
preg_match_all('/^\s*(\d*)\s*\|\s*(.*?)\s*\|/m', $str, $matches);
// $matches[1] will have ids
// $matches[2] will have labels
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
Original data looks like this: banners/ad_1.png | Banner ad 1 | 1
Here is an array using the print_r function on it:
Array ( [0] => banners/ad_1.png Banner ad 1 1
[1] => banners/ad_2.png Banner ad 2 2
[2] => banners/ad_3.png Banner ad 3 3 )
This is after exploding it with a | delimiter, so it's separated by img src, alt text, num times viewed.
Is there a way I can return the banner information by num times viewed, max or min?
I have been playing with min, max, array_values, array_keys, array_multisort.. I can't figure it out.
Thanks!
This should work, provided this array doesn't get so big that it eats up significant chunks of memory:
<?php
$array = array(
'banners/ad_1.png | Banner ad 1 | 1',
'banners/ad_2.png | Banner ad 2 | 2',
'banners/ad_3.png | Banner ad 3 | 3'
);
$sort = array();
foreach ($array as $row)
{
$row = explode(" | ", $row); // split up string into a format we can deal with
// use a unique index so we can keep track of association
$idx = trim($row[0]);
$sort[$idx] = trim($row[2]);
}
arsort($sort); // sorts by value in descending order, keeps index association
print_r($sort);
/*
Should be:
Array(
'banners/ad_3.png' => 3,
'banners/ad_2.png' => 2,
'banners/ad_1.png' => 1
)
*/
Here's some documentation on the arsort function I used.