Pseudo code for retrieving MySQL data with PHP associative arrays - php

I have two MySQL tables, products and prodGroups. I need to retrieve the following data in this format of an associative array:
Array ( [0] => Product Group 1 => Item 1
=> Item 2
=> Item 3
[1] => Product Group 2 => Item 4
=> Item 5
=> Item 6
[2] => Product Group 3 => Item 7
=> Item 8
=> Item 9 )
The above was freely written so obviously that's not correct format of print_r for an assoc array, but hopefully you get the idea.
I'm having trouble comprehending to retrieve Items from a MySQL table where their prodGroup value matches the name of Product Group 1/2/3. I want the items belonging to a particular product group to be apart of its rightful parent array.
I'm not the best at explaining, hope what I've written is enough to point my question across. However, in summary if you're still lost, I need Item 1&2&3 to be apart of Product Group 1 in the array.
Pseudo code would be great, I have a feeling a while and foreach loop is required, I'm just totally lost for its structure.

You can solve this in one of two ways:
1) With nested queries. For small amounts of data, why not:
while($row = getNextProductGroup())
$row->items = getItemsForGroup($row->ProductGroupId);
2) If you have lots of data this will be costly in performance, so you'll need a smarter way. Just join them together and pick it apart in PHP:
$productGroups = [];
while($row = getNextProductGroupAndItem()) {
if(!isset($productGroups[$row->ProductGroupId])) {
$row->items = [];
$productGroups[$row->ProductGroupId] = $row;
}
$productGroups[$row->ProductGroupId]->items[] = $row;
}

Related

Using values in an PHP array

I have an array split in half, but now i want to use the values in the array.
The array is split like this
$teams = array_chunk($lista, count($lista)/2);
Output
Array ( [0] => Array ( [0] => 4 [1] => 3 ) [1] => Array ( [0] => 4 [1] => 4 ) )
the numbers represent user id's.
How can i use these numbers?
Let's say that i want to select all id's in the first array (The idea is for these two arrays to act like teams) and then assign these values to a team column in my database.
Let me explain a bit more
I want the id's in the array to be assigned to a team.
In array one the team will be, uhm. Blue! and in the other array the team will be red.
I will be using these randomised arrays to update my database table which contains a column called "team".
Basically my question is how i can use these arrays to assign the specific id's in each array to a team. example, Can i select everything in array one and update all those values to team blue?
For this question i'm sorry because i really don't know what i should include to make this question answerable, it might already be! but i'm not sure, so i if i have missed something just comment and i will clarify.
Update
This is what my database table looks like
https://gyazo.com/ed3c681575b26f31b77246436b43439a
As you can see, i have a column called "team", i want to update this to something depending on what team the user got selected into using the array splitter.
Everyone in Array one will have this updated to "team blue", and team red for array2.
You could use a For Loop to construct a query that does this for you.
An array inside of an array is called a Multidimensional Array.
You can access the elements of an array inside an array by just simply indexing twice:
$array = [ [1,2], [3,4] ];
echo $array[0][0]; // echo's 1
So you could loop over the first array for each team and loop into the second array to get each user id:
$array = [ [1,2], [3,4] ];
foreach($array as $team_id => $player_ids){
foreach($player_ids as $player_id){
echo "Player $player_id is in team $team_id";
}
}
This example uses a Foreach Loop.
In this for loop you can construct a query that updates the rows for the players in the database.
If you are new to arrays in PHP I suggest you read this article: http://php.net/manual/en/language.types.array.php

PHP Array length

So this may be a bit long winded to explain, but I'll try to make it concise.
I have a db query that pulls in 3 different Tag IDs, 2 of them are associated to 4 Hub IDs, while 1 is associated with only 3.
I return all tags, and sort the results by ID (so all 4 results for tag 1 are grouped, all 4 of 2, and all 3 of 3) Like so:
Array
(
[0] => 40BD32751DF1
[1] => 40BD32751DF1
[2] => 40BD32751DF1
[3] => 40BD32751DF1
[4] => 10CEA9FD173A
[5] => 10CEA9FD173A
[6] => 10CEA9FD173A
[7] => 10CEA9FD173A
[8] => 10CEA9FCFE26
[9] => 10CEA9FCFE26
[10] => 10CEA9FCFE26
)
Then I do a while loop and loop it for each Tag ID (3x). Inside that, I use array_keys on an array_column search to find the array indexes of each Tag ID, count how many results I have (4, 4, 3) I then take that row's data using the array key, and loop number to push that row of data into an array for later sorting:
while($currentTag = pg_fetch_assoc($tagList)) {
$tkeys = array_keys(array_column($tagDataArray, 'devmac'), $currentTag['devmac']);
$tempArray = array();
for($k=0; $k < count($tkeys); $k++){
array_push($tempArray, $tagDataArray[$tkeys[$k]]);
}
//Then I sort that temporary array so one of the values in the row is the highest:
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}
array_multisort($sigsort, SORT_DESC, $tempArray);
updateArticles($tempArray[0]);
}
Now the problem comes from that temporary array. I have 4 results for the first ID, 4 for the second, then 3 for the third, yet for the third ID, somehow I still get 4 items in the array even though I reinitialize it with each while loop pass (each ID). The fourth result from the second ID, ends up as the fourth result for the third ID.
How is this possible? I've been trying to figure this out for hours and I'm not making any headway. The $tkeys gives me 3 on the third ID, so the for loop runs 3 times, everything makes sense, till the array push where something just decides to stick around. I've even added a print_r to the tempArray and before it runs the third time, it's empty! I dont get where it keeps creeping back in.
Thanks.
Make sure that when you process data in subsequent loops, you remove all previous data...
$sigsort= [];
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}

Silverstripe 3.5 - How to query for specific columns and return an array

I'm trying to do a select all to get three columns from a single table and then simply use the result as an array. Without the expense of a loop.
I have tried this using the ORM method:
DataObject::get('City')->sort('Name ASC')->toNestedArray();
This gives me an array perfectly. But I can't see a way to only return the columns I want. It returns all columns. This is a problem because I am json encoding this array and the packet is 3 times as big as it needs to be due to this.
So I tried this using SQLQuery instead:
DB::query('SELECT "ID","Name","ParentID" FROM "City"');
Now this allows me to select the three fields, but as far as I can tell, there is no method to return this query as an array like toNestedArray()
Searched high and low but nothing fits. Any ideas?
Edit: Should have mentioned I have tried setQueriedColumns() sorry. This doesn't seem to be intended for what I am doing here.
$cities = AspireCity::get()->sort(['Name' => 'ASC'])->setQueriedColumns(['ID', 'Name']);
Debug::dump($cities->toNestedArray());
Outputs:
Array
(
[0] => Array
(
[ClassName] => City
[LastEdited] => 2017-09-26 11:14:16
[Name] => Acacia Bay
[ID] => 70
[RecordClassName] => City
[Created] =>
[ParentID] => 9
)
[1] => Array
(
[ClassName] => City
[LastEdited] => 2017-09-26 11:14:16
[Name] => Ahaura
[ID] => 71
[RecordClassName] => City
[Created] =>
[ParentID] => 9
)
According to the API Docs, setQueriedColumns() is your friend:
From your question I assume the DataObject you want to query is called City, so we need this to get all cities out of the database:
City::get();
This returns a DataList and queries the database when you need it. Up to now, your DB doesn't know anything that you want some data from it. So let's refine it, sort it by "Name" ASC. I like the array syntax much more, IMHO it's easier to read, and if you need to sort against a second row, just add it to the array:
City::get()
->sort(['Name' => 'ASC']);
Now you wanted, for some reasons, just some columns back. As I don't know what database fields your City DataObject has, I assume you just want 'Name' and 'ZIP':
City::get()
->sort(['Name' => 'ASC'])
->setQueriedColumns(['Name', 'ZIP']);
This limits the queried columns and you can add toNestedArray() to get the data out as a pure vintage array. This might be useful to pass the data to an API, but maybe it's better to leave the objects and use City specific logic in your code.
So I decided that this was a case a of over-reliance on existing SS helper methods. While toNestedArray() is very handy, my focus on it was to based primarily on thinking I can avoid a loop by using it. When in reality, the method is of course a loop. So really my concern is unfounded.
The most important goal was reducing the dataset at the time of query. So the solution simply focuses on that.
// Inject the default country/city/suburb data as vars so they can be easily filtered.
$location['countries'] = DB::query('SELECT "ID","Description" FROM "Country" ORDER BY "ID" ASC');
$location['cities'] = DB::query('SELECT "ID","Name","ParentID" FROM "City" ORDER BY "Name" ASC');
$location['suburbs'] = DB::query('SELECT "ID","Name","ParentID" FROM "Suburb" ORDER BY "Name" ASC');
$masterLocationArray = [];
foreach($location as $key => $data) {
$locationArray = [];
foreach($data as $item) {
$locationArray[] = $item;
}
$masterLocationArray[$key] = $locationArray;
}
// $masterLocationArray is our filtered, tidy array. Do stuff with it

Combine array items by name with a separator?

I have the following PHP code which runs a MySQL query and returns the results as an array:
function mysql_resultTo2DAssocArray ( $result) {
$i=0;
$ret = array();
while ($row = mysql_fetch_assoc($result)) {
foreach ($row as $key => $value) {
$ret[$i][$key] = $value;
}
$i++;
}
return ($ret);
}
$compare = mysql_resultTo2DAssocArray(mysql_query("SELECT Temp.School, Temp.Status, Snow.Token FROM Temp
JOIN Snow ON Temp.School = Snow.School"));
The results of this look like:
Array
(
[0] => Array
(
[School] => School Name 1
[Status] => Delayed Two Hours
[Token] => Token1
)
[1] => Array
(
[School] => School Name 1
[Status] => Delayed Two Hours
[Token] => Token2
)
)
Is it possible to combine the Token items by a comma within those arrays if the School item is the same for each?
One thing is that it's possible for there to be more arrays within the global array, with different School names, that shouldn't be grouped but left alone. Basically, is it possible to ONLY group when School is the same. It's also possible for there to be more than two tokens.
SELECT Temp.School, Temp.Status, GROUP_CONCAT(Snow.Token) Tokens
FROM Temp JOIN Snow USING (School)
GROUP BY Temp.School
This isn't completely valid, because the Status column is not aggregated or part of the GROUP BY; however MySQL normally allows it (there's an option to disallow it, I don't remember the name offhand). If there are rows with different Status values, it will pick one of them arbitrarily; you didn't say what should happen with different Statuses.

Joining more than two mysql tables then manipulating rows into grouped multidimensional arrays

I'm trying to join multiple myqsl tables and then process resulting arrays using PHP but I'm having problems manipulating my data to get the groupings I'd like.
table.users
+--------------- uidname
table.profile_values
+----------------------- fiduidcategory_value
table.profile_fields
+--------------------- fid category_title
Here is my sql query:
SELECT users.name, profile_fields.category_title, profile_values.category_value FROM profile_values
INNER JOIN profile_fields
ON profile_values.fid=profile_fields.fid
INNER JOIN users
ON users.uid=profile_values.uid
ORDER BY users.name ASC
Using I while loop over fetch_array(), as expected, I get an array for each row number which looks something like:
Array (
[0] => Array (
[name] => Bob
[category_title] => Occupation
[category_value] => IT
)
[1] => Array (
[name] => Bob
[category_title] => Previous Experience
[category_value] => Very little.
)
...
)
The output I'm actually looking to generate is:
Array(
[name] => array(
[category_title 1] => value 1
[category_title 2] => value 2
...
)
....
)
I've spent the vast part of a day looking at various examples and haven't been able to find one that helps me understand the best place to interject and group my data. I've seen examples using GROUP_CONCAT, which is similar to what I want, but I'd like to keep my data in arrays if possible.
Should I be using a nested foreach loops after I have my rows assigned to arrays, using a GROUP BY in my sql statement, or a combination of both?
Use php to create the array you want then. Maybe something like:
$result = mysql_query($sql) or die(mysql_error());
$newArray = array();
while($row = mysql_fetch_assoc($result)){
$newArray[$row['name']][$row['category_title']][] = $row['category_value'];
}

Categories