Replace mysql coloumn values when adding them to an php array - php

I have a table called "Current state", it has three columns known as:
id name state
1 FXD 1
2 GFX 3
3 ATOM 2
4 FARB 3
5 REX 1
6 FRX 2
In the following code I get it into array and print it:
$exc = $conn->prepare("SELECT name,state from current_state");
$exc->execute();
while($finalResult = $exc->fetch(PDO::FETCH_ASSOC))
{
$tables[] = $finalResult;
}
var_dump($tables);
But the problem is though numbers represent the state column values each of those numbers have a meaning:
1 = running
2 = finished
3 = dimnished
So what I want is to add the above string values right away to the tables array by comparing the values of the state column.
The current print result of a column would look like
array (size=2)
'name' => string 'FRX' (length=11)
'state' => string '2' (length=1)
But what I want is:
array (size=2)
'name' => string 'FRX' (length=11)
'state' => string 'finished' (length=8)

You can either do it in SQL with a CASE expression:
SELECT name,
CASE state
WHEN 1 THEN 'running'
WHEN 2 THEN 'finished'
WHEN 3 THEN 'diminished'
END AS state
FROM current_state
Or you could do it in PHP with an array:
$statemap = array(1 => 'running', 2 => 'finished', 3 => 'diminished');
Then your PHP loop would do the mapping:
while ($finalResult = $exc->fetch(PDO::FETCH_ASSOC)) {
$finalResult['state'] = $statemap[$finalResult['state']];
$tables[] = $finalResult;
}
Finally, you could have another table that contains the mappings, and join with it:
CREATE TABLE state_mappings (
state_num INT PRIMARY KEY,
state_name VARCHAR(20)
);
SELECT name, state_name
FROM state AS s
JOIN state_mappings AS m ON s.state = m.state_num

Related

Sorting associative array with multiple conditions

I have a table called "parents_kids", it has three columns known as:
id Guardian kids
1 Greg 1
2 Gary 3
3 Aaron 2
4 Farb 3
5 REX 1
6 Fred 2
In the following code I get it into array and print it:
$exc = $conn->prepare("SELECT ID,Guardian,kids from current_state");
$exc->execute();
while($finalResult = $exc->fetch(PDO::FETCH_ASSOC))
{
$tables[] = $finalResult;
}
var_dump($tables);
once i got this into an array, i sorted it in a custom order where
first the guardians with 2 kids, then with 1 kid and who has 3
ID Guardian kids
3 Aaron 2
6 Fred 2
1 Greg 1
5 REX 1
4 Farb 3
2 Gary 3
Now my requirement is to order this rest of the array according to its ID to descending order,
for example just like this
ID Guardian kids
6 Fred 2
3 Aaron 2
5 REX 1
1 Greg 1
4 Farb 3
2 Gary 3
i tried this many times but its dint work, the code i used to sort the first requirement is as follows
$order = array("2", "1", "3");
usort($tables, function ($a, $b) use ($order) {
$pos_a = array_search($a['kids'], $order);
$pos_b = array_search($b['kids'], $order);
return $pos_a - $pos_b;
});
can anybody help me to fullfil my second requirement which is sort the array by ID to descending order
This is how the array looks like
array (size=3)
0 =>
array (size=3)
'ID' => string '3' (length=1)
'Guardian' => string 'Aaron' (length=5)
'kids' => string '2' (length=1)
array (size=3)
1 =>
array (size=3)
'ID' => string '6' (length=1)
'Guardian' => string 'FRED' (length=4)
'kids' => string '2' (length=1)
etc
P.S doing it from the table is not going to work, because im using a loop above the code which makes it impossible to do it from the SQL, can anybody tell me a way to do it from the php
I think that it should help:
select ID,Guardian,kids
from current_state
order by case WHEN kids = 2 then 1
WHEN kids = 1 then 2
WHEN kids = 3 then 3
ELSE kids END ASC
, ID desc
There were two primary issues.
You were using status as the first key when it should have been kids based on your description.
You need to check whether the first subtraction was zero, and if so, compare the id values.
Here is a working solution.
$order = array("2", "1", "3");
usort($tables, function ($a, $b) use ($order) {
$pos_a = array_search($a['kids'], $order);
$pos_b = array_search($b['kids'], $order);
$result = $pos_a - $pos_b;
if ($result != 0) return $result;
return intval($b['ID']) - intval($a['ID']);
});
var_dump($tables);

Var_dump shows value but returns null mysql query

Using PHP and MYSQL I do a left join on 2 tables. I then use var_dump to show the results.
$sql = "SELECT pro_table.pro_id, pro_table.sport_id, pro_table.pro_name,
results_table.pro_id, results_table.year, results_table.result_rank, results_table.result_score
FROM pro_table
LEFT JOIN results_table
ON pro_table.pro_id=results_table.pro_id
WHERE sport_id LIKE '$dropdownrecord'";
$myData = mysql_query($sql,$con);
while($record = mysql_fetch_array($myData)){
var_dump($record);
this outputs
array (size=13)
0 => string '276' (length=3)
'pro_id' => null
1 => string '14' (length=2)
'sport_id' => string '14' (length=2)
2 => string 'Bradley Wiggins' (length=15)
'pro_name' => string 'Bradley Wiggins' (length=15)
3 => null
4 => null
'year' => null
5 => null
'result_rank' => null
6 => null
'result_score' => null
I am not sure why my pro_id returns a 276 yet also says null?
My Problem was that I had both columns in both tables named the same think. I renamed one column and now it is working property.
Try something like this :
for($i=0;$record[$i] = $mysql_fetch_array($myData); $i++){
var_dump($record[$i]);
}

Retrieving specific data from sql query

Let's say I have the following query, wich gives me the amount of coupons downloaded and redeemed, grouped by date: [EDIT](I can't modify this query)[/EDIT]
$sql = "SELECT DATE(datetime) ,
SUM(CASE WHEN datetime!='' THEN 1 ELSE 0 END) As downloaded ,
SUM(CASE WHEN used = 1 AND DATE(datetime) != '' THEN 1 ELSE 0 END) AS redeemed
FROM Promotion_Redeem
WHERE datetime BETWEEN '2013-10-01' AND '2013-10-04'
GROUP BY DATE(datetime)";
How can I get the sum of downloaded and the sum of redeemed? this should be within $sql, somewhere... below is the result for this query:
row number 1
array (size=3)
0 => string '2013-10-01' (length=10)
1 => string '126' (length=3)
2 => string '11' (length=2)
row number 2
array (size=3)
0 => string '2013-10-02' (length=10)
1 => string '106' (length=3)
2 => string '5' (length=1)
row number 3
array (size=3)
0 => string '2013-10-03' (length=10)
1 => string '228' (length=3)
2 => string '12' (length=2)
row number 4
array (size=3)
0 => string '2013-10-04' (length=10)
1 => string '149' (length=3)
2 => string '9' (length=1)
[EDIT]bove you can see I get 4 rows, each one whith an array... I want, for instance, the sum of the third field from each of these arrays... In my example, this would equals to 37 (that means, 37 coupons redeemed)[/EDIT]
I got this data structure after using this:
while ($row = mysql_fetch_row($result)) {
echo "row number ".++$i;
var_dump($row);
}
Thanks in advance
Modify your php loop like so:
$downloaded=0;
$redeemed=0;
while ($row = mysql_fetch_row($result)) {
echo "row number ".++$i;
$downloaded+=$row[1];
$redeemed+=$row[2];
var_dump($row);
}
echo "Downloaded: $downloaded<br>";
echo "Redeemed: $redeemed<br>";

Getting the most from a single MySQL query

I have a website that lists apartments that are available for rent. I have a few different tables in my MySQL database. One table is for basic information about the Apartment building as a whole, including address, ammenities, photos, an ID (NID), etc.
Another table lists the units available for rent within each building. So each apartment building has multiple floorplans, with a few studios, a few 1 bedroom units, sometimes a few 2 bedroom units, etc.
Currently I query my 'unit' table and ask for all units in a given apartment building. My query looks something like SELECT * FROM node_unit WHERE nid='555'
This might return something like the following:
NID Name Rent SqFT Bedrooms Bathrooms
555 Unit 1 $500 620 0 1
555 Unit 2 $550 680 0 1
555 Unit 3 $600 820 1 1
555 Unit 4 $650 920 1 1
555 Unit 5 $700 1220 2 1
555 Unit 6 $800 1420 2 2
555 Unit 7 $900 1500 3 2
555 Unit 8 $1100 1620 3 3
etc, etc
What I am then doing in my PHP is using an accordian to group the 1 bedrooms together, the 2 bedrooms together, etc.
Not all apartments have 2 bedrooms units, some only have 1 bedroom units, so I need to know within my PHP code if I should print another accordian.
Currently I am using multiple hits to the database to determine if a given building has any 2 bedroom units, if so print another row. Does this building have any 3 bedroom units? If so print another row, but I would like to stop hitting my database so much.
Finally, here is my question:
How can I store the results from my first DB call and somehow parse thru the data and and determine if a given NID has studios, 1 beds, 2 beds, etc? (I just started learning PHP/MySQL recently)
I would suggest a query like this:
SELECT * FROM node_unit WHERE nid='555'
ORDER BY Bedrooms ASC, Bathrooms ASC, Rent ASC
This would return your records ordered by # of bedrooms, # bathrooms, and rent amount (in that order).
You could easily store this in multidimensional array when reading from database like this (assuming mysqli use with result set stored in $result, but concept is same for other DB connection libraries)
$room_array = array();
while ($row = mysqli_fetch_assoc($result)) {
$room_array[(int)$row['Bedrooms']][] = $row;
}
You now have a multidimensional array with number of bedrooms as first index. The array might look like this if you var_dump it:
Array (
[0] => Array (
[0] => Array (
'NID' => '555',
'Name' => 'Unit 1',
'Rent' => '$500',
'SqFt' => '620',
'Bedrooms' => '0',
'Bathrooms' => '1',
)
[1] => Array (
'NID' => '555',
'Name' => 'Unit 2',
'Rent' => '$550',
'SqFt' => '680',
'Bedrooms' => '0',
'Bathrooms' => '1',
)
)
[1] => Array (
[0] => Array (
'NID' => '555',
'Name' => 'Unit 3',
'Rent' => '$600',
'SqFt' => '820',
'Bedrooms' => '1',
'Bathrooms' => '1',
)
[1] => Array (
'NID' => '555',
'Name' => 'Unit 4',
'Rent' => '$650',
'SqFt' => '920',
'Bedrooms' => '1',
'Bathrooms' => '1',
)
[2] => Array (
...
)
[3] => Array (
...
)
)
This makes it really easy to iterate over the number of bedrooms values in an outer loop, which creates your accordions, and then iterate the individual rooms in an inner loop.
foreach ($room_array as $num_bedrooms => $rooms) {
// start accordion
foreach ($rooms as $room) {
// output room details
}
// end accordion
}
All this would only require the single query.
Also make sure you have indexes on bedrooms, bathrooms, rent (or whichever you use in the sort) as well as on nid since it is used as the filter.
Try this as your database query, it will generate a row for each building for each unit type it has. You could also use it as a subquery and join to the parent table to get any other details you need about the building in one shot.
select 'studio' as unit_type, nid from node_unit group by nid having count(case when bedrooms = 0 then 1 end) > 0
union all
select 'one bedroom' as unit_type, nid from node_unit group by nid having count(case when bedrooms = 1 then 1 end) > 0
union all
select 'two bedroom' as unit_type, nid from node_unit group by nid having count(case when bedrooms = 2 then 1 end) > 0
union all
select 'three bedroom' as unit_type, nid from node_unit group by nid having count(case when bedrooms = 3 then 1 end) > 0

help getting products + their comments by followers with mysql

ok i have an product table. and a commment table. a user table and an social table.
social
SID AUID BUID
1 1 2 // user 1 follow 2
2 1 3 // user 1 follow 3
3 2 1
we can see that user id 1 is following user 2 and 3
user
UID NAME
1 me
2 imthenamefromuser2
3 imthenamefromuser3
product
PID UID NAME TIMECREATE
1 2 user2product 12-04-2011
2 3 user3product 12-03-2011
comment pcid = parent comment id
CID UID PID COMMENT PCID
1 1 2 comment on product2 NULL
2 2 2 another comment on p2 NULL
3 3 2 someoneelse on p2 NULL
4 1 2 who are you? 3
5 3 2 im user 3 dude 4
6 1 1 a new post on p2 NULL
ok the question is
how can we get the list of products their followers with their following comments ( max 20 comments ) ?
heres what i have so far ( without the comments ) lets example the $uid is 1
function listFromFollower($uid){
#here
$data = $this->fetchAll("SELECT products.name AS product, users.name, products.pid, products.timecreate
FROM products
INNER JOIN users ON users.uid = products.uid
INNER JOIN social ON products.uid = social.buid
WHERE social.auid = :uid", array( 'uid' => $uid));
return $data;
}
it gets something like
array
0 =>
array
'product' => string 'user2product' (length=9)
'name' => string 'imthenamefromuser2' (length=12)
'pid' => string '1' (length=1)
'timecreate' => string '2011-02-26 13:30:07' (length=19)
1 =>
array
'product' => string 'user3product' (length=8)
'name' => string 'imthenamefromuser3' (length=12)
'pid' => string '2' (length=1)
'timecreate' => string '2011-02-26 13:30:54' (length=19)
maybe it should be something like
array
0 =>
array
'product' => string 'user2product' (length=9)
'name' => string 'imthenamefromuser2' (length=12)
'pid' => string '1' (length=1)
'timecreate' => string '2011-02-26 13:30:07' (length=19)
0 =>
array
'name' => string ''
'comment' => string ''
1 =>
array
'name' => string ''
'comment' => string ''
0 =>
array
'name' => string 'a threaded comment'
'comment' => string ''
untill20 =>
array
'name' => string ''
'comment' => string ''
1 =>
array
'product' => string 'user3product' (length=8)
'name' => string 'imthenamefromuser3' (length=12)
'pid' => string '2' (length=1)
'timecreate' => string '2011-02-26 13:30:54' (length=19)
Thanks!
You can't get the result from the query to come out like you want. So there are two options. Run the query as you have and loop through each product to get their comments.
Or else get a large result that contains all the comments as well and them process to array to pull out the comments.
As Kevin Peno commented, is there any reason you need all this data? and not just the comment count? Because that would be a simple query with no processing.
Anyway here's a sample of how you could execute the 2nd option using a LEFT JOIN for comments:
function listFromFollower($uid){
$rows = $this->fetchAll("
SELECT products.name AS product, users.name, products.pid,
products.timecreate, commenters.name as commenter, comments.comment
FROM products
INNER JOIN users ON users.uid = products.uid
INNER JOIN social ON products.uid = social.buid
LEFT JOIN comments ON comments.pid = product.pid
INNER JOIN users AS commenters ON commenters.uid = comments.uid
WHERE social.auid = :uid", array( 'uid' => $uid));
$data = array();
foreach($rows as $row) {
// If we haven't added this product to data yet, add it.
if (!isset($data[$row['pid']])) {
$data[$row['pid']] = $row;
// Tidy up the data, we don't want commenter and comment here
unset($data[$row['pid']]['commenter']);
unset($data[$row['pid']]['comment']);
// Initialize an array for the comments
$data[$row['pid']]['comments'] = array();
}
$data[$row['pid']]['comments'][] = array(
'name' => $row['commenter'],
'comment' => $row['comment']
);
}
return $data;
}
Now you should have the same array as you had before, but now each element in the array with also have an array with the key comments that contains the comments.

Categories