CodeIgniter, active records, JOIN help? - mysql

I am trying to figure out why my JOIN is not working on a database query, I have two tables with a user_ID column, but when I return this it returns everything, not just the selected ones per user. What am I messing up any thoughts? Thank you!
function user_apps()
{
$this->db->select('*');
$this->db->from('apps');
$this->db->join('members', 'members.user_ID = apps.user_ID');
$query = $this->db->get();
return $query;
}
Here is an image of the DB tables, and goal is to basically get the urls from the apps table of each user,
http://cl.ly/516bd1e8aae62bd11773

You haven't specified a WHERE clause in your query. At the moment it is returning everything because you only have two users and they both have entries in the 'apps' table.
If you add:
$this->db->where('members.first_name', $first_name);
And pass a first name as a parameter to the function then it will only return results for that user.
function user_apps($first_name)
{
$this->db->select('*');
$this->db->from('apps');
$this->db->join('members', 'members.user_ID = apps.user_ID');
$this->db->where('members.first_name', $first_name);
$query = $this->db->get();
return $query;
}

Related

how to count or get record of rows, whose primary_key is not in foreign table?

I have a database that have two tables 'products' and "specifications". I want to count whose specifications are not in "specifications" table and products have duplicate names.
I have tried: Product::withCount(['specifications'])->has('specifications', '<', '1')->get();
but this is not working, taking too much time also tried with paginate but get no result.
Update 1:
Also please let me know the RAW query for this.
Update 2:
Here is the Product Relation code:
public function specifications()
{
return $this->hasMany('App\Specification');
}
Here is the function I made for deleting duplicate products and there specifications.
public function deleteDuplicateWithCountZero() {
$duplicateProducts = Product::whereIn('name', function ( $query ) {
$query->select('name')->from('products')->groupBy('name')->havingRaw('count(*) > 1');
})->paginate(50);
foreach($duplicateProducts as $duplicateProduct) {
$results = Product::where('name', '=', $duplicateProduct->name)->withCount(['specifications'])->get();
$productCount = count($results);
foreach($results as $result) {
if($result->specifications_count == 0 && $productCount > 1) {
$product = Product::find("$result->id");
Specification::where('product_id', "$product->id")->delete();
$product->delete();
$productCount--;
}
}
}
echo "Complete"; die();
}
Problem: How can I know all products and their specifications are deleted until count query, But count query taking too much time for all data. Please also suggest if I can correct this thing in phpmyadmin with a query.
Since the specification count is always going to be 0, you could hardcode the value in the query. Also, instead of has(), try doesntHave()
Product::query()
->select('*', DB::raw('0 as specifications_count'))
->doesntHave('specifications')
->get();

Filter With() in Query Scope

Controller
$r = \App\User::whereIn('id', $user_ids)->withPosts($category_id)->get();
User model
public function scopeWithPosts($query, $category_id)
{
return $query->with('posts')->where('category_id', $category_id);
}
I have been at this for too many hours now.
I am trying to use with() along with an query scope to add an extra filter to the relationship.
However it gives me the error " category_id not existing in users table"? What am I missing?
Laravel 6
The problem you are experiencing is that you are expecting the with('posts') function to return a query that is relative to the Posts ORM model. It won't, it will still return a reference to the original query. What you will find is that the with function returns $this, so you'll always get the original query.
What you are attempting is a SQL query to find the User, followed by another SQL query to get all the Post records of that user, with those posts filtered by category. So
SELECT * FROM Users WHERE id=?;
SELECT * FROM Posts WHERE user_id = ? AND category_id = ?
To do that in the Eloquent relationship, you need to subquery, like so:
return $query->with(['posts' => function ($q) use ($category_id) {
$q->where('category_id', $category_id);
}]);
Please comment if you need further info and I'll edit my answer.

Delete from two mysql tables at once using join codeigniter

I am trying to delete from two mysql tables at once using this function.
public function deleteBusiness($id)
{
$this->db->from("business");
$this->db->join("opening_hours", "business");
$this->db->where("business", $id);
return $this->db->delete(array("business","opening_hours"));
}
It appears to be working correctly, as the correct data is being deleted from both tables, but when I call it with the following...
if($this->businesses_model->deleteBusiness($id)){
$this->session->set_flashdata('flash_message', 'Business Deleted');
} else {
$this->session->set_flashdata('flash_message', 'There was a problem deleting that business');
}
the failed error message is being displayed.
Replace Above code with Following Code let me know if does not work
public function deleteBusiness($id)
{
$this->db->from("business");
$this->db->join("opening_hours", "business");
$this->db->where("business", $id);
$this->db->delete(array("business","opening_hours"));
return $this->db->affected_rows();
}
if($this->businesses_model->deleteBusiness($id) > 0){
$this->session->set_flashdata('flash_message', 'Business Deleted');
} else {
$this->session->set_flashdata('flash_message', 'There was a problem deleting that business');
}
let me know if it does not work
It looks like you are trying to Delete a row from business table and all the rows in the opening_hours related to that business.
Unfortunately your code will not work as CodeIgniter ignores joins when doing Active Record deletes.
Their Documentation does says that you can pass an array to delete method and it will delete from multiple rows
$tables = array('table1', 'table2', 'table3');
$this->db->where('id', '5');
$this->db->delete($tables);
However, please see that it will delete rows from 3 tables where id = 5. Same way in your case it will delete from business and opening_hours where id is say 2. Obviously this is not what you want.
Only option is to use either 2 queries like below or use a Raw SQL query.
$this->db->from("business");
$this->db->where("id", $id);
$this->db->delete('business');
$this->db->from("opening_hours");
$this->db->where("business_id", $id);
$this->db->delete('opening_hours');

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

What is wrong with this Code Igniter mySQL query?

I have two tables for storing information about a user. One is for authentication, the other is information the user will enter themselves. I am writing a model that will be used when the user interacts with this information. The following method is to return data for display and modification.
I need a query that will return 'email' and 'username' from $accounts_table and * from $profiles_table. I can't seem to get my head around the JOIN syntax though. I understand how joins work, but my queries throw sentax errors.
function get_userdata($id){
$data = array();
$this->db->get_where($this->profiles_table, array('user_id' => $id));
$this->db->join($this->accounts_table.'.email', $this->accounts_table.'.id = '.$this->profiles_table.'.user_id');
$data= $this->db->get();
return $data;
}
I see a couple of issues:
You should be using $this->db->where(), instead of $this->db->get_where(). get_where() executes the query immediately.
$this->db->get_where('user_id', $id);
Also the first argument of $this->db->join() should only be the table name, excluding the field.
$this->db->join($this->accounts_table, $this->accounts_table.'.id = '.$this->profiles_table.'.user_id');
And you're returning $data which is just an empty array(). You would need to pass the query results to $data like this:
$data = $record->result_array();
get_where executes the query. So, your join is its own query, which doesn't work.
You need to break get_where into where and from.
Also, in MySQL, you JOIN a table, not a field. If you want that field, add it to the SELECT.
$this->db->select($this->profiles_table.'.*');
$this->db->select($this->accounts_table.'.email,'.$this->accounts_table.'.username');
$this->db->from($this->profiles_table);
$this->db->where('user_id', $id);
$this->db->join($this->accounts_table, $this->accounts_table.'.id = '.$this->profiles_table.'.user_id');
$data = $this->db->get();
NOTE: $this->db->get() returns a query object, you need to use result or row to get the data.
I think you've a mistake:
$this->db->join($this->accounts_table.'.email', $this->accounts_table.'.id = '.$this->profiles_table.'.user_id');
First parameter should a table NOT a field: $this->accounts_table.'.email' is wrong IMHO. Or only a typo :)