mysql query to an array - php

I am new to php. I can't figure out how to query my db to list this mockup. For each array, I want to query the db to list only what is related to the left in ''.
My db consist of 2 tables.
table1 = album
id, name
table2 = picture
id, album, picPath
$q_albums = array(
'People' => array(
ALBUM_PATH.'4.jpg',
ALBUM_PATH.'11.jpg',
ALBUM_PATH.'10.jpg'),
'Nature' => array(
ALBUM_PATH.'2.jpg',
ALBUM_PATH.'3.jpg',
ALBUM_PATH.'5.jpg',
ALBUM_PATH.'6.jpg',
ALBUM_PATH.'7.jpg'),
'Art' => array(
ALBUM_PATH.'1.jpg',
ALBUM_PATH.'8.jpg',
ALBUM_PATH.'9.jpg',
ALBUM_PATH.'2.jpg'),
'Wilderness' => array(
ALBUM_PATH.'3.jpg',
ALBUM_PATH.'2.jpg',
ALBUM_PATH.'5.jpg',
ALBUM_PATH.'7.jpg',
ALBUM_PATH.'6.jpg'),
'Photography' => array(
ALBUM_PATH.'8.jpg',
ALBUM_PATH.'1.jpg',
ALBUM_PATH.'9.jpg',
ALBUM_PATH.'12.jpg'),
'Fashion' => array(
ALBUM_PATH.'11.jpg',
ALBUM_PATH.'4.jpg',
ALBUM_PATH.'10.jpg'),
);

As dev-null-dweller notes, you need to build the array from the query results in a loop. Fortunately, it's pretty easy:
$sql = <<<END
SELECT album.name AS albumName, picture.picPath AS picPath
FROM album JOIN picture ON album.id = picture.album
END;
$res = $mysqli->query( $sql );
$q_albums = array();
while ( $row = $res->fetch_object() ) {
// this line actually build the array, entry by entry:
$q_albums[ $row->albumName ][] = $row->picPath;
}
$res->close();
Edit: As Mr. Radical notes, if you want your results to include empty albums, you should change the JOIN to a LEFT JOIN. If you do that, the query will return a row with a null picPath for any empty albums, so you'll have to deal with those null paths somehow. One way would be to include something like the following code after building the array:
foreach ( $q_albums as $album => &$pics ) {
// remove dummy null entries from empty albums
if ( !isset( $pics[0] ) ) array_shift( $pics );
}

#Ilmari Karonen I would use LEFT JOIN instead of JOIN.
SELECT album.name AS albumName, picture.picPath AS picPath
FROM album LEFT JOIN picture ON album.id = picture.album

Related

how to select multiple rows using mysql and php?

I had two tables
ads
adImages
here table ads id and table adImages adsId are same. here i have to select all the rows from the table ads and adImages, and display it in json format.
My codes looks:
$query="SELECT a.*, b.images FROM `ads` AS a INNER JOIN `adImages` AS b ON a.id = b.adsId";
$result=mysql_query($query);
$value = mysql_num_rows($result);
if($value>=1)
{
while($row = mysql_fetch_array($result))
{
$details[] = array(
'id' => $row['id'],
'location' => $row['location'],
'title'=>$row['title'],
'mobile' => $row['mobile'],
'description' => $row['description'],
'category' => $row['category'],
'images' =>'http://greenwma.com/dev/uploads/'.$row['images'],
);
}
echo json_encode($details);
}
And its output json looks like :
[{"id":"10","location":"9.982852,76.300637","title":"Ggg","mobile":"5555555","description":"Google","category":"BusMedia","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016062319:07:39.jpg{"id":"10","location":"9.982852,76.300637","title":"Ggg","mobile":"5555555","description":"Google","category"BusMedia","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 17:27:05.jpg"},{"id":"11","location":"9.962439,76.305337","title":"Test","mobile":"898566899","description":"Test","category":"Bus Shelters","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:15:16.jpg"},{"id":"11","location":"9.962439,76.305337","title":"Test","mobile":"898566899","description":"Test","category":"Bus Shelters","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:08:50.jpg"},{"id":"11","location":"9.962439,76.305337","title":"Test","mobile":"898566899","description":"Test","category":"Bus Shelters","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:07:39.jpg"}]
here the problem is id,location,title,mobile,description,category are repeating for each image on same adsId.
And my need is that, I have to get json in the format
[{"id":"10","location":"9.982852,76.300637","title":"Ggg","mobile":"5555555","description":"Google ","category":"Bus Media","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:07:39.jpg","http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 17:27:05.jpg"},{"id":"11","location":"9.962439,76.305337","title":"Test","mobile":"898566899","description":"Test","category":"Bus Shelters","images":"http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:15:16.jpg","http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:08:50.jpg","http:\/\/greenwma.com\/dev\/uploads\/MapCapture2016-06-23 19:07:39.jpg"}]
that is, I have to get all images separated by comma in single json object. for that what all changes should I make in the above code.
You can use CONCAT() & GROUP_CONCAT() with sub queries to do it in one query and lesser loops.
SELECT a.*, GROUP_CONCAT(images) images FROM (
SELECT a.*, CONCAT('http://greenwma.com/dev/uploads/', b.images) images
FROM `ads` AS a
INNER JOIN `adImages` AS b ON a.id = b.adsId
) tbl
GROUP BY id

How to retrieve all posts with all comments using 2 SQL queries

I am trying to make a page with a list of posts, and underneath each post all the comments belonging to that post. Initially I wanted to use just one query to retrieve all the posts + comments using the SQL's JOIN, but I find it impossible to for example retrieve a post with multiple comments. It only displays the posts with a maximum of 1 comment per post, or it just show a post multiple times depending on the amount of comments.
In this related question, somebody talked about using 2 queries:
How to print posts and comments with only one sql query
But how do I do this?
I've got the query and a while loop for posts, but I obviously don't want to run a query for comments for each post inside that loop.
$getPost = mysql_query('SELECT p.post_id,
p.user_id,
p.username,
p.content
FROM post p
ORDER BY p.post_id DESC');
while($row = mysql_fetch_array($getPost))
{
...
}
Table structure (reply is the table for storing comments):
POST (post_id (primary key), user_id, username, content, timestamp)
REPLY (reply_id (primary key), post_id, username, reply_content, timestamp)
You can do it in a single query, which is OK if the amount of data in your original posts is small:
$getPost = mysql_query('SELECT
p.*,
r.reply_id, r.username r_username, r.reply_content, r.timestamp r_timestamp
FROM post p
left join reply r
ORDER BY p.post_id DESC'
);
$posts = array();
$last_id = 0;
while($row = mysql_fetch_array($getPost))
{
if ($last_id != $row['post_id']) {
$posts[] = array(
'post_id' => $row['post_id'],
'user_id' => $row['user_id'],
'username' => $row['username'],
'content' => $row['content'],
'timestamp' => $row['timestamp'],
'comments' => array()
);
}
$posts[sizeof($posts) - 1]['comments'][] = array(
'reply_id' => $row['reply_id'],
'username' => $row['r_username'],
'reply_content' => $row['reply_content'],
'timestamp' = $row['r_timestamp']
);
}
Otherwise, break it into two queries like so:
$getPost = mysql_query('SELECT
p.*,
FROM post p
ORDER BY p.post_id DESC'
);
$rows = array();
$ids = array();
$index = array();
while($row = mysql_fetch_assoc($getPost)) {
$row['comments'] = array();
$rows[] = $row;
$ids[] = $row['post_id'];
$index[$row['post_id']] = sizeof($rows) - 1;
}
$getComments = mysql_query('select r.* from replies r where r.post_id in ("'
. join('","', $ids)
. '")');
while ($row = mysq_fetch_assoc($getComments)) {
$rows[$index[$row['post_id']]]['comments'][] = $row;
}
... Or something like that. Either option allows you to litter your first query with WHERE clauses and so forth to your heart's content. The advantage of the 2nd approach is that you don't re-transmit your original post data for each comment!
In order to also get those posts without comments, you need to use a LEFT OUTER JOIN. In that case, any row in the first table without any corresponding rows in the second table will be paired with a row consisting of null values.
SELECT * FROM posts
LEFT OUTER JOIN comments ON posts~post_id = comments~post_id;
By the way: there is also a RIGHT OUTER JOIN. When you would use that, you would get all comments, including those where the parent post got lost somehow, but no posts without comments.

Combine mysql query with sub query results into one PHP array

I have a table that contains events, to list these events I loop through the event table, check the event type and look up it's value in it's specific table with it's eventId.
At the moment this uses one query to get the 20 events and then up to 3 queries to get the data on those events. I currently have it coded procedurally but need to change it so that at the end it just returns the data in array form.
Here's a Pseduo code example of what I need to achieve:
while(eventQuery):
if commentQueryResult;
$array .= commentQueryResult;
if forumPostQueryResult;
$array .= forumPostQueryResult;
if uploadItemQueryResult;
$array .= uploadItemQueryResult;
endwhile;
return $array; // Combined returned results as one array
I will then be able to access the data and just foreach loop through it.
I'm just not sure the best way to combine multiple result sets into an array?
OR you could try and combine them into one query ...
$eventResult = mysql_query(
'SELECT userevent.event, userevent.eventId, userevent.friendId
FROM userevent
WHERE userevent.userId = 1 OR userevent.friendId = 1
ORDER BY userevent.id DESC
LIMIT 20'
);
while ($eventRow = mysql_fetch_row($eventResult)){
if($eventRow[0] == 1){
$result = mysql_fetch_array(mysql_query("
SELECT forumRooms.id, forumRooms.title
FROM forumPosts
INNER JOIN forumRooms ON forumPosts.`forumTopic` = forumRooms.`id`
WHERE forumPosts.id = '$eventRow[1]'"));
}
elseif($eventRow[0] == 2){
$result = mysql_fetch_array(mysql_query("
SELECT game.id, game.uriTitle, game.title
FROM usergamecomment
INNER JOIN game ON usergamecomment.`gameId` = game.id
WHERE usergamecomment.id = $eventRow[1]"));
}
elseif($eventRow[0] == 4){
$result = mysql_fetch_array(mysql_query("
SELECT usercomment.comment, UNIX_TIMESTAMP(usercomment.TIME), `user`.id, `user`.username, `user`.activate
FROM usercomment
INNER JOIN `user` ON usercomment.`userId` = `user`.id
WHERE usercomment.id = $eventRow[1]
AND `user`.activate = 1"));
}
elseif($eventRow[0] == 5){
$result = mysql_fetch_array(mysql_query("
SELECT game.id, game.title, game.uriTitle
FROM game
WHERE game.id = $eventRow[1]"));
}
// Combined Results as array
}
I'm in the process of converting all of these to PDO, that's the next step after working out the best way to minimise this.
Challenge accepted. ;)
Since you are actually only interested in the results inside the while loop, you could try this single query. Due to the LEFT JOINS it might not be faster, pretty much depends on your database. The final $result contains all elements with their respective fields.
$result = array();
$q = 'SELECT userevent.event AS userevent_event,
userevent.eventId AS userevent_eventId,
userevent.friendId AS userevent_friendId,
forumRooms.id AS forumRooms_id,
forumRooms.title AS forumRooms_title,
game.id AS game_id,
game.uriTitle AS game_uriTitle,
game.title AS game_title,
usercomment.comment AS usercomment_comment,
UNIX_TIMESTAMP(usercomment.TIME) AS usercomment_time,
user.id AS user_id,
user.username AS user_username,
user.activate AS user_activate,
g2.id AS game2_id,
g2.uriTitle AS game2_uriTitle,
g2.title AS game2_title
FROM userevent
LEFT JOIN forumPosts ON forumPosts.id = userevent.eventId
LEFT JOIN forumRooms ON forumPosts.forumTopic = forumRooms.id
LEFT JOIN usergamecomment ON usergamecomment.id = userevent.eventId
LEFT JOIN game ON usergamecomment.gameId = game.id
LEFT JOIN usercomment ON usercomment.id = userevent.eventId
LEFT JOIN user ON usercomment.userId = user.id
LEFT JOIN game g2 ON userevent.eventId = g2.id
WHERE (userevent.userId = 1 OR userevent.friendId = 1)
AND userevent.eventId >= (SELECT userevent.eventId
WHERE userevent.userId = 1 OR userevent.friendId = 1
ORDER BY userevent.id DESC LIMIT 1,20);';
$r = mysql_query($q);
while ( $o = mysql_fetch_row($r) ) {
switch($o['userevent_event']) {
case 1:
$result[] = array(
'id' => $o['forumsRooms_id'],
'title' => $o['forumsRooms_title'],
);
break;
case 2:
$result[] = array(
'id' => $o['game_id'],
'uriTitle' => $o['game_uriTitle'],
'title' => $o['game_title'],
);
break;
case 4:
$result[] = array(
'comment' => $o['usercomment_comment'],
'time' => $o['usercomment_time'],
'id' => $o['user_id'],
'username' => $o['user_username'],
'activate' => $o['user_activate'],
);
break;
case 5:
$result[] = array(
'id' => $o['game2_id'],
'uriTitle' => $o['game2_uriTitle'],
'title' => $o['game2_title'],
);
break;
}
}
Note: Eventually, the query has to be edited slightly, I just wrote that out of my head w/o testing. Optimization can surely be done if I'd knew more about the db structure.
Also, this is merely a proof of concept that it can indeed be done with a single query. ;)

MySQL LEFT JOIN where joined table is null

My current SQL is:
SELECT * FROM `node`
LEFT JOIN `field_data_field_area_of_study_category`
ON `field_data_field_area_of_study_category`.`entity_id` = `node`.`nid`
WHERE `node`.`type` = 'area_of_study'
GROUP BY `node`.`nid`
For now, to make it work I run a foreach loop to is_null() on the column.
I'm trying to emulate the is_null() check within the SQL query.
Thanks for reading.
EDIT
This is the foreach loop that runs the is_null(). I think a better way to ask my question would be: how do make the SQL return only rows from the node table where there is no matching field_data_field_area_of_study_category table?
foreach($aos_nodes as $aos_node):
if (is_null($aos_node->field_area_of_study_category_tid)):
$menu_item_display[$aos_node->title] = array(
'id' => $aos_node->nid,
'type' => 'node',
'children_markup' => '',
'icon' => '',
'name' => $aos_node->title,
'href' => drupal_get_path_alias('node/'.$aos_node->nid),
);
endif;
endforeach;
To return the rows where there isn't a matching one:
SELECT * FROM `node`
LEFT JOIN `field_data_field_area_of_study_category`
ON `field_data_field_area_of_study_category`.`entity_id` = `node`.`nid`
WHERE `node`.`type` = 'area_of_study'
and `field_data_field_area_of_study_category`.`entity_id` is null
GROUP BY `node`.`nid`
Additionally, you can use not exists:
select
*
from
node n
where
n.type = 'area_of_study'
and not exists (
select
1
from
field_data_field_area_of_study_category f
where
f.entity_id = n.nid
)

php mysql advanced selecting

table 1 = events -> holds a list of events
table 2 = response -> holds a list of users responses has a foreign key of eid which corresponds with events table
I need to join the tables together so it can return an array similar to this on php.
array(
0 => array(
'title' =>'', //title of events table
'contents' =>'this is a demo', //contents of events table
'users' => array( //users comes from response table
0 = array(
'firstname'=>'John',
),
1 = array(
'firstname'=>'James',
)
)
)
);
can this be done? using mysql only? coz i know you can do it on php.
You can gather all the necessary data in MySQL with a single JOIN query.
However, PHP will not return an array like your example by default. You would have to loop over the query result set and create such an array yourself.
I'm pretty sure the answer is no, since mysql always returns a "flat" resultset. So, you can get all the results you're looking for using:
SELECT e.title, e.contents, r.firstname
FROM events e LEFT JOIN response r ON e.id = r.eid
ORDER BY e.id, r.id
And then massaging it into the array with php, but I imagine this is what you're doing already.
EDIT:
By the way, if you want 1 row for each event, you could use GROUP_CONCAT:
SELECT e.title, e.contents, GROUP_CONCAT(DISTINCT r.firstname ORDER BY r.firstname SEPARATOR ',') as users
FROM events e LEFT JOIN response r ON e.id = r.eid
GROUP BY e.id
Just as Jason McCreary said. For you convenience, here is the query you need (though the field names might not be matching your db structure, as you did not provide this information)
SELECT
*
FROM
events
LEFT JOIN
responses ON (events.id = responses.eid)
The SQL is:
SELECT events.id, events.title, events.contents,
response.id AS rid, response.firstname
FROM events LEFT JOIN response
ON events.id = response.eid
I thought I would show you how to massage the results in to the array as you wished:
$query = "SELECT events.id, events.title, events.contents, response.id AS rid, response.firstname
FROM events LEFT JOIN response ON events.id = response.eid";
$result = mysql_query($query);
$events = array();
while ($record = mysql_fetch_assoc($result)) {
if (!array_key_exists($record['id'], $events)) {
$events[$record['id']] = array('title' => $record['title'], 'contents' => $record['contents'], 'users' => array());
}
if ($record['rid'] !== NULL) {
$events[$record['id']]['users'][$record['rid']] = array('firstname' => $record['firstname']);
}
}
mysql_free_result($result);

Categories