I am using an inner join statement to retrieve data from both the tables Venues and Users. However, I would like to have an array looking like this
$resultsFromVenueTableArray = array(
$relevantVenueKey => $relevantVenueValue,
$resultsFromUserTable => $arrayOfValuesFromUserTable
);
rather than just one array full of all of the retrieved data looking something like this:
$resultsFromQuery = array(
$venueKey,
$userKey,
$venueKey...
)
How could I achieve this?
Here's my code;
$query = $this->db->query("SELECT * FROM Venues INNER JOIN Users ON Users.id = $userID", array($userID));
$venues = array();
foreach ($query->result() as $row) {
$row->username = $username;
$venues[] = $row;
}
It isn't clear from the question exactly what you would like to do, but you can pull out specific columns from both tables like so:
SELECT Venues.*, Users.username FROM Venues INNER JOIN Users ON...
which would allow you to pull out only the 'username' column from 'Users'.
A join is always going to leave you with an array of rows, if you need something else you'll probably have to manipulate the data once you've got it in PHP unless I've misunderstood your question.
Something like this would get you all venues by a user, with the username as the array key:
$venuesByUser = array();
foreach ($query->result() as $row) {
$venuesByUser[$row->username][] = $row;
}
Related
I am working on a report on which all employees and their salary detail will be fetch according to the departments wise. I have successfully fetch the employees by the department using multidimensional array but now I need to fetch the employees_salary_detail on that employees detail multidimensional array. It means first department->emp_detail->salarydetail. I have successfully fetch the first two part but now i am facing issue on fetching the last array in that emp_detail array.
public function getDepartmentReport(){
$employee = $this->db->select('*')
->from('departments')
->where('project_id', $this->session->userdata('client_id'))->get()->result_array();
$data = array();
foreach($employee as $m => $v){
$v['emp_detail'] = $this->db->select('first_name,employee_code,employees_salary.*')
->from('employees')
->join('employees_salary', 'employees_salary.employee_id = employees.id')
->where('employees.department_id',$v['id'])
->where('employees_salary.month', 'Nov')
->get()->result_array();
$data[] = $v;
foreach($v['emp_detail'] as $m => $s){
$s['salary_detail'] = $this->db->select('*')
->from('employees_salary_detail')->where('employees_salary_detail.salary_id', $s['id'])
->get()->result_array();
$data[] = $s;
}
}
return $data;
}
But now it is creating seperate array for showing salary detail not in that emp_detail array.
I don't know where i am making mistake. please help me to fix this issue.
THANK YOU IN ADVANCE FOR HELPING
Use Join Method to join all three tables in the database on the basis of common keys. I can see you have joined two tables same way you can join multiple tables and create a single array of data.
$qry = $this->db->query("SELECT * FROM product_section INNER
JOIN products ON product_section.ps_prid = products.prid INNER
JOIN wishlist ON wishlist.wish_product_id = products.product_id
INNER JOIN customer ON wishlist.wish_user_id = customer.cust_id
INNER JOIN brands ON brands.brand_id = products.product_brand
WHERE customer.cust_id = '$cid' GROUP BY
product_section.ps_prid");
like this above code
I have a database with several tables. I'm able to query IDs from a single table. What I'd like to do is Use those IDs to query another tables IDs, then use these new IDs to query fields from the final table. Here is what I am currently doing:
Here is how I acquire the first set of IDs:
$returnedPost = mysqli_query($con, "SELECT Region_ID FROM Region WHERE RegionName='" . $queryVar . "'");
function resultToArray($result) {
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
$rows = resultToArray($returnedPost);
//$rows[x]['Region_ID'];//returns Region_ID 1...n
I'd like to use the IDs in $rows to be able to query a new set of IDs from other tables as follows:
$newTbl = mysqli_query($con, "SELECT Location_ID FROM Location WHERE Region_ID=" . $rows[$x]['Region_ID']);
$rows2 = resultToArray($newTbl);
$finalTbl = mysqli_query($con, "SELECT Field1, Field2 FROM Posts WHERE Location_ID=" . $rows2[$x]['Location_ID']);
Can someone please tell me how I can accomplish this? Thanks.
you can use INNER JOIN in one query to get at this data, maybe something like this
SELECT P.Field1,P.Field2
FROM Region R
INNER JOIN Location L ON R.Region_ID = L.Region_ID
INNER JOIN Posts P ON L.Location_ID = P.Location_ID
WHERE R.RegionName = Your_Region_QueryVar
Question first, explanation later:
Insteat of the first array, i want one which looks like the secound array:
echo json_encode($movies);
//WHAT I DO NOT WANT: [{"movie_name":"test1","genre_name":"Action"},{"movie_name":"test2","genre_name":"Drama"},{"movie_name":"test2","genre_name":"Action"}]
//WHAT I WANT: [{"movie_name":"test1","genres":["Action"]},{"movie_name":"test2","genres":["Drama","Action"]}]
So insteat of severals rows with the same value for movie_name but different values for genre_name, i want one row for each movie, where all genre_names are merged into one gernes array;
The solution i wish:
The data is fetched from an database using php and mysqli. This is the SQL query i use and which generates the first array:
SELECT movies.movie_name, genres.genre_name FROM genres
INNER JOIN genre_movie ON genres.id = genre_movie.genre_id
INNER JOIN movies ON movies.id = genre_movie.movie_id;
I am not good with SQL and think there is a query which gets the me the secound array (the one I WANT) right away.
My solution so far:
i actually solved the problem using a php arglorithm, but its kinda complecated and hard if the anything scales or i add new columns:
foreach($myArray as $movie)
{
foreach($newList as $key => $item)
{
if($item['movie_name'] == $movie['movie_name']){
$exists = true;
$position = $key;
}
}
if($exists == true)
{
$newList[$position]['genres'][] = $movie['genre_name'];
$exists= false;
} else {
$newList[] = array('movie_name' => $movie['movie_name'], 'genres' => array($movie['genre_name']));
}
}
Take a look at group_concat: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
I didn't emulate your tables but maybe this is your query:
SELECT movies.movie_name, group_concat(genres.genre_name) FROM genres
INNER JOIN genre_movie ON genres.id = genre_movie.genre_id
INNER JOIN movies ON movies.id = genre_movie.movie_id
GROUP BY movies.movie_name;
Edition
Well, I emulated it now, and yes, it's your query. I would just change:
group_concat(genres.genre_name)
For:
group_concat(distinct(genres.genre_name))
To return only different values.
i want to do the following but haven't found how to.
Or i'm not sure if there is a better way / practice, if you can point me that way i will appreciate it.
I have 2 tables on my DB
Table1 : Categories
Table2 : Subcategories
Table2 is associated with table1 by the primary key.
So for 1 row in the table1 i can have multiple associated rows on the table2.
I query and fetch the data on my Table1 like this:
$result = $mysqli->query("SELECT * FROM table1");
$post = array();
while ($row = $result->fetch_object()){
$row->sub = get_subcategories($row['id']); /* this value is added to the array since i want to store in here the associated arrays from the table2 */
$post[] = $row;
}
return $post;
Then i do the following query also on another function for the table2 data based on every id from the table1
function get_subcategories($id){
$result = $mysqli->query("SELECT * FROM table2 where categories_id = '$id'");
$post = array();
while ($row = $result->fetch_object()){
$post[] = $row;
}
return $post;
}
But the result im getting when using var_dump doesn't seem right.
Can i do it? or what am i doing wrong?
Thanks in advance
Use a single JOIN query:
$result = $mysqli->query("SELECT * FROM table1 t1 JOIN table2 t2 ON t2.categories_id = t1.id ORDER BY t1.id");
$posts = array();
while ($row = $result->fetch_object) {
if (!isset($posts[$row->categories_id])) {
$posts[$row->categories_id] = $row;
$posts[$row->categories_id]->sub = array();
}
$posts[$row->categories_id]->sub[] = $row;
}
This will create nested arrays. The first level will be an associative array whose keys are category IDs and values are objects. The objects will have a sub property that is an array of all the subcategories. Both the categories and subcategories are the objects returned by fetch_object, so there will be duplication. But you can just refer to the appropriate object properties for a particular level.
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.