Get the data which in two dimensional array - php

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.
}

Related

Pagination from two SQL Tables with one query. Fastest Way

I have a simple Database:
Table 1: Object Table 2: Data
id | type | added object_id | key | value
------------------------ -----------------------------
1 | app | 2017 1 | name | ...
2 | app | 2017 2 | name | ...
3 | win | 2017 2 | version | ...
2 | dev_name | ...
2 | lang | ...
i created a simple pagination to show only 5 object from type apps with their infomation from the data table:
example code:
$sth = $dbh->prepare("SELECT * FROM object WHERE type = 'app' LIMIT 5");
$sth->execute;
$object = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($object as $rows) {
$sth = $dbh->prepare("SELECT * FROM data WHERE id = $rows['id']");
$sth->execute;
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
echo $data['name'];
echo $data['version'];
echo $object['added'];
...
Is there a better way? because this is a very bad solution, i want to query only one time where i get an fetch array like this:
array(
// app with id = 1 in object table
[1] => array(
// data from the app with id = 1 in data table
[name] => ...
[version] => ...
[dev_name] => ...
[lang] => ...
// app with id = 2 in object table
[2] => array(
// data from the app with id = 2 in data table
[name] => ...
[version] => ...
[dev_name] => ...
[lang] => ...
...
one query:
SELECT * FROM object inner join data on data.id_object=object.id WHERE object.type = 'app' LIMIT 5
This query return information from two table with associate data.
I think that's what you want
If you want to group by id of the first table you can also execute this query
SELECT * FROM object inner join data on data.id_object=object.id WHERE object.type = 'app' group by object.id LIMIT 5
or
SELECT Distinct(object.id), object.type, .... FROM object inner join data on data.id_object=object.id WHERE object.type = 'app' LIMIT 5
Consider for string comparison use LIKE instead of =

Laravel - update multiple records with different values

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.

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.

Sum php array (created from mysql results) depending on mysql values in another mysql column

One table called 18_7_ChartOfAccounts looks like this:
ID | AccountNumber
-------------
1 | 2310
2 | 2380
3 | 2610
Another table called 2_1_journal looks like this:
ID | Amount | DebitAccount
--------------------------
1 | 26.03 | 2310
2 | 200.00 | 2310
3 | 3.63 | 2380
4 | 119.83 | 2380
5 | 33.86 | 2610
6 | 428.25 | 2610
Aim is to get results that looks like this:
DebitAccount 2310 total is: 226.03
DebitAccount 2380 total is: 123.46
DebitAccount 2310 total is: 462.11
226.03 in this example is total of 26.03 + 200.00
At first mysql code
$query = "SELECT j.Amount, j.DebitAccount FROM 18_7_ChartOfAccounts AS c LEFT JOIN 2_1_journal AS j ON (c.AccountNumber = j.DebitAccount)";
$sql = $db->prepare($query);
$sql->execute();
$data = $sql->fetchAll(PDO::FETCH_ASSOC);
With print_r($data); get long list of arrays like
[31] => Array
(
[Amount] => 26.03
[DebitAccount] => 2310
[32] => Array
(
[Amount] => 200.00
[DebitAccount] => 2310
If in mysql query use SUM(j.Amount) then get only one total amount (suppose total amount of Column Amount).
With
foreach($data as $result){
if(strlen($result['Amount']) > 0 ) {
echo "Amount ". $result['Amount']. "Account name ". $result['DebitAccount']. "<br>";
print_r (array_sum($result));
}
}
Get something like this
Amount 123.97Account name 2310
2433.97Amount 26.03Account name 2310
2336.03Amount 200.00Account name 2310
Any ideas how to get necessary results (marked bold)?
Update
Changed $query to
$query = "SELECT SUM(j.Amount), j.DebitAccount FROM 18_7_ChartOfAccounts AS c LEFT JOIN 2_1_journal AS j ON (c.AccountNumber = j.DebitAccount) group by j.DebitAccount";
with print_r($data); get array like this
Array
(
[0] => Array
(
[SUM(j.Amount)] =>
[DebitAccount] =>
)
[1] => Array
(
[SUM(j.Amount)] => 110900.16
[DebitAccount] => 2310
)
[2] => Array
(
[SUM(j.Amount)] => 3660.86
[DebitAccount] => 2380
)
With array seems all works. Now with foreach changed to
echo "Amount ". $result['SUM(j.Amount)']. " Account name ". $result['DebitAccount']. "<br>";
Get
Amount 110900.16 Account name 2310
Amount 3660.86 Account name 2380
Amount 85247.40 Account name 2610
Seems also ok. Thanks
You are going about it wrong. You can get the sum through MySql statement itself.
Use the aggrgate function sum along with group by clause.
Like this,
SELECT DebitAccount,sum(Account) from 2_1_journal group by DebitAccount
Your full code:
$query = " SELECT DebitAccount,sum(Account) as Total from 2_1_journal group by DebitAccount";
$sql = $db->prepare($query);
$sql->execute();
$data = $sql->fetchAll(PDO::FETCH_ASSOC);
foreach($data as $result){
if(strlen($result['Total']) > 0 ) {
echo "DebitAccount ". $result['DebitAccount']. "Total is: ". $result['Total']. "<br>";
print_r (array_sum($result));
}
}
SELECT DebitAccount, SUM(Amount)
FROM 2_1_journal
GROUP BY DebitAccount
You have to use the GROUP BY in the query
SELECT DebitAccount, SUM(Amount) AS Amount FROM 2_1_journal GROUP BY DebitAccount

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

Categories