Laravel groupby and count different values (Polymorphic) - mysql

I have a table with the name "reportable" and want to display the entries in a table on the website. Unfortunately I can't get the database query right, I don't have much experience with a One To Many (Polymorphic) table.
databse table:
Schema::create('reportable', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned()->nullable()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
$table->integer('reason');
$table->integer('reportable_id')->index();
$table->string('reportable_type')->index();
$table->text('notice')->nullable();
$table->tinyInteger('status')->default(0)->index();
$table->timestamps();
});
In the table on the web page I want to display only entries with the same reportable_id and reportable_type only once.
In addition, the entries with the same reportable_id and reportable_type should be counted and displayed as a numerical value.
In addition, the entries in the column 'reason' with the same reportable_id and reportable_type should be counted and displayed with the respective entry and as a numerical value.

if you want a list:
$query = Report::select(\DB::raw('reportable.reportable_id,reportable.reportable_type,SUM(reason) as reason_total')) // Or \DB::raw('reportable.*,SUM(reason) as reason_total')
->groupBy('reportable_type')
->groupBy('reportable_id')
->get();
And if you want to have a specific row you should have your query like this:
$reportableId = 1; // $reportableId = Input::get('report_id'); // It can come from get parameters http://localhost/reports?report_id= 1
$reportableType = 'User';
$query = Report::select(\DB::raw('reportable.reportable_id,reportable.reportable_type,SUM(reason) as reason_total')) // Or \DB::raw('reportable.*,SUM(reason) as reason_total')
->groupBy('reportable_type')
->groupBy('reportable_id')
->get();
if($reportableId)
$query = $query->where('reportable_id' , $reportableId );
if($reportableType)
$query = $query->where('reportable_type' , $reportableType );
return $query;

Related

Compare two fields within different table using Laravel

I have two tables employees and customers , i've gave the schema below.
Customers('id' , 'username', 'location');
Employees('id' , 'EmployeeID' , 'CustomerID', 'location');
Currently I can use a query to retrieve customers details like the below query , note this is when the user is logged into the system hence the Auth::
$customerQuery1 = DB::table('customer')
->where('id', '!=', Auth::id())
->where('item', '=' , Auth::customer()->recommendation)
->get();
Each Employee has many customers ,I want other customers to see other customer items so i have attach the CustomerID field which is a foreign key and relates to the id field within the Customer table.
I've tried something like the below however I think I may need a join query but i'm unsure.
$query2 = DB::table('Customer','Employee')
->select('username')
->where(['EmployeeID' => Auth::id(), 'CustomerID' => 'id'])
->get();
$query2 = DB::table('Customer')
->select('username')
->join('Employee', 'Customer.id', '=', 'Employee.CustomerID')
->where(['EmployeeID' => Auth::id(), 'CustomerID' => 'id'])
->get();
I am then returning the values to my blade file like the below
return view ('pages.dashboard')
->with('query1',$query1)
and then Im using php indentation within my blade file to return the users data
#foreach ($query1 as $Userfound)
{{ $Userfound->username}}</p>
#endforeach
Actual Query needed in plain english
so I need to select a customer , where CustomerID == id
NOTE: id is from the customers table, CustomerID stored in the Employees table.
You can create Models using Laravel, for example:
Employee.php
public function customers()
{
return $this->hasMany('App\Customer');
}
Customer.php
public function employee()
{
return $this->belongsTo('App\Employee');
}
Which you can access like so:
$customer = Customer::where('id',Auth::user()->id)->firstOrFail();
or
$employee = Employee::where('id',Auth::user()->id)->firstOrFail();
And to see an employee's customers:
$employee->customers()->get();
Or to see the other customers of $customer's employer:
$customer->employee()->customers()->get();

Column 'name' in field list is ambiguous codigniter

this is my table structure.
tbl_user:
companyname,name,email.
tbl_userinfo:
phone,address,area,state,city,description.
tbl_category:
category_id,name.
i am joining three tables here is my model
$this->db->select(array('name', 'companyname','phone','address','email','state','city','pincode','area','description','image', 'c.name AS categoryname'));
$this->db->from('tbl_user');
$this->db->join('tbl_userinfo', 'tbl_userinfo.user_id = tbl_user.user_id');
$this->db->join ('tbl_category', 'tbl_category.category_id = tbl_userinfo.service_category');
$this->db->group_by(array('name', 'companyname', 'phone', 'address', 'email','state','city','pincode','area','description','image','categoryname'));
//$this->db->order_by('tbl_category.category_id');
$this->db->where(array('tbl_user.user_id' => 16));
i wanted third column name as well but i m getting Column 'name' in field list is ambiguous codigniter
another code that i did use but it wont show me any values for joining of two table.
$this->db->select(array('tbl_user.name', 'tbl_user.companyname','tbl_userinfo.phone','tbl_userinfo.address','tbl_user.email','tbl_userinfo.state','tbl_userinfo.city','tbl_userinfo.pincode','tbl_userinfo.area','tbl_userinfo.description','tbl_userinfo.image', 'tbl_category.name'));
$this->db->from('tbl_user');
$this->db->join('tbl_userinfo', 'tbl_userinfo.user_id = tbl_user.user_id');
$this->db->join ('tbl_category', 'tbl_userinfo.service_category = tbl_category.category_id');
$this->db->group_by(array('tbl_user.name', 'tbl_user.companyname','tbl_userinfo.phone','tbl_userinfo.address','tbl_user.email','tbl_userinfo.state','tbl_userinfo.city','tbl_userinfo.pincode','tbl_userinfo.area','tbl_userinfo.description','tbl_userinfo.image', 'tbl_category.name'));
$this->db->where(array('tbl_user.user_id' => 16));
This is most likely happening because two of your tables both have a 'name' column. I would suggest explicitly selecting the column by using [table name].[column].
$result = $this->db->query('past your query here after checking it in an sql browser');
Try this:
$user_id = '16';
$query = $this->db->select('tbl_user.companyname, tbl_user.name as UserName, tbl_user.email, tbl_userinfo.phone, tbl_userinfo.address, tbl_userinfo.area, tbl_userinfo.state, tbl_userinfo.city, tbl_userinfo.description, tbl_category.category_id, tbl_category.name as CategoryName')
->from('tbl_user')
->join('tbl_userinfo', 'tbl_userinfo.user_id = tbl_user.user_id')
->join ('tbl_category', 'tbl_category.category_id = tbl_userinfo.service_category')
->where('tbl_user.user_id', $user_id)
->group_by('tbl_user.companyname')
->get()
->result();
You can replate 'tbl_user.*' with the columns names you want to get from that table, example: 'tbl_user.user_id, tbl_user.name as UName, tbl_category.name as CName' change the name of column if you have 2 or more columns with the same name in diferent tables you are joining, it will create always an ambiguous error because there are 2 columns with the same name and codeigniter doesn't know which one you want, if you want both you need to rename the both columns.
Also add the join to left because if there is no user_id or category_id it will not display you the result.
Hope this will help you.
comes with my own code.
$this->db->select(array('u.name', 'u.companyname','i.phone','i.address','u.email','i.state','i.city','i.pincode','i.area','i.description','i.image', 'c.name AS categoryname'));
$this->db->from('tbl_user as u');
$this->db->join('tbl_userinfo as i', 'i.user_id = i.user_id');
$this->db->join ('tbl_category as c', 'c.category_id = i.service_category');
$this->db->group_by(array('u.user_id'));
$this->db->where(array('u.group_id' => 16));
$query = $this->db->get ();
return $query->result();

How to perform Inner joins , left joins with readbean ORM?

If I have 2 tables one is users and one is stores , the users id field is associated with the store's user_id field .
Now if I want to find all those users who has a store how can I perform it on readbean ?
and please do explain as I'm just getting started with it.
Thanks
If your queries looking complex, You can simply use plain sql inside redbean.
$records = R::getAll("SELECT * FROM tbl1 LEFT JOIN tbl2 ON tbl1.id = tbl2.tbl1_id");
This will result into and all satisfying records array.
Here I have used R::getAll($your_qry) method, to fetch for single row use R::getRow($yoyr_sql_qry); method.
If you have any difficulties. let me know.
Is it a 1:Many or Many:Many?
If I understand what you said, it's 1:Many
DB model: stores belong to users
So, a store can belong to exactly one (1) user, correct?
If so, it's easy using redbean
$user = R::dispense('users'); // create a user
$store = R::dispense('stores'); // create a store
$store2 = R::dispense('stores'); // create a store
$store1->name = 'Foo';
$store2->name = 'Bar';
$user->xownStoresList[] = $store; // save user ( and store )
$user->xownStoresList[] = $store2; // save user ( and store )
$id = R::store( $user );
foreach ( $user->ownStoresList as $store ) {
echo $store->name . ', ';
}
// outputs: "foo, bar,"

MYSQL fetch records from table 1 that do not exist in table 2

I created a php function to fetch records from a sql table subscriptions, and I want to add a condition to mysql_query to ignore the records in table subscriptions that exists in table removed_items, here is my code;
function subscriptions_func($user_id, $limit){
$subs = array();
$sub_query = mysql_query("
SELECT `subscriptions`.`fo_id`, `subscriptions`.`for_id`, `picture`.`since`, `picture`.`user_id`, `picture`.`pic_id`
FROM `subscriptions`
LEFT JOIN `picture`
ON `subscriptions`.`fo_id` = `picture`.`user_id`
WHERE `subscriptions`.`for_id` = $user_id
AND `picture`.`since` > `subscriptions`.`timmp`
GROUP BY `subscriptions`.`fo_id`
ORDER BY MAX(`picture`.`since_id`) DESC
$limit
");
while ($sub_row = mysql_fetch_assoc($sub_query)) {
$subs [] = array(
'fo_id' => $sub_row['fo_id'],
'for_id' => $sub_row['for_id'],
'user_id' => $sub_row['user_id'],
'pic_id' => $sub_row['pic_id'],
'since' => $sub_row['since']
);
}
return $subs ;
}
My solution is to create another function to fetch the records from table removed_items and set a php condition where I call subscriptions_func() to skip/unset the records that resemble the records in subscriptions_func(), as the following
$sub = subscriptions_func($user_id);
foreach($sub as $sub){
$rmv_sub = rmv_items_func($sub[‘pic_id’]);
If($rmv_sub[‘pic_id’] != $sub[‘pic_id’]){
echo $sub[‘pic_id’];
}
}
This solution succeeded to skip the items in the table removed_items however this solution makes gaps in the array stored in the variable $sub which makes plank spots in the echoed items.
Is there a condition I can add to the function subscriptions_func() to cut all the additional conditions and checks?
Assuming id is the primary key of subscriptions and subs_id is the foreign key in removed_items, then you just have to add a condition to the WHERE clause. Something like this should work :
...
AND `subscriptions`.id NOT IN (SELECT `removed_items`.subs_id FROM `removed_items`)
...
Not related to your problem :
Your code seems vulnerable to SQL injection : use prepared statement to prevent this.
The original Mysql API is deprecated, it is highly recommended to switch to Mysqli instead.

Zend_Db: How to get the number of rows from a table?

I want to find out how many rows are in a table. The database that I am using is a MySQL database. I already have a Db_Table class that I am using for calls like fetchAll(). But I don't need any information from the table, just the row count. How can I get a count of all the rows in the table without calling fetchAll()?
$count = $db->fetchOne( 'SELECT COUNT(*) AS count FROM yourTable' );
Counting rows with fetchAll considered harmful.
Here's how to do it the Zend_Db_Select way:
$habits_table = new Habits(); /* #var $habits_table Zend_Db_Table_Abstract */
$select = $habits_table->select();
$select->from($habits_table->info(Habits::NAME), 'count(*) as COUNT');
$result = $habits_table->fetchRow($select);
print_r($result['COUNT']);die;
Proper Zend-Way is to use Zend_Db_Select like this:
$sql = $table->select()->columns(array('name', 'email', 'status'))->where('status = 1')->order('name');
$data = $table->fetchAll($sql);
$sql->reset('columns')->columns(new Zend_Db_Expr('COUNT(*)'));
$count = $table->getAdapter()->fetchOne($sql);
This is how it's done in Zend_Paginator. Other option is to add SQL_CALC_FOUND_ROWS before your column list and then get the number of found rows with this query:
$count = $this->getAdapter()->fetchOne('SELECT FOUND_ROWS()');
You could do a
SELECT COUNT(*)
FROM your_table
$dbo->setFetchMode( Zend_Db::FETCH_OBJ );
$sql = 'SELECT COUNT(*) AS count FROM #table';
$res = $dbo->fetchAll( $sql );
// $res[0]->count contains the number of rows
I'm kind of a minimalist:
public function count()
{
$rows = $db->select()->from($db, 'count(*) as amt')->query()->fetchAll();
return($rows[0]['amt']);
}
Can be used generically on all tables.
Add count capability to your Zend_DB Object To count all table rows
public function count()
{
return (int) $this->_table->getAdapter()->fetchOne(
$this->_table->select()->from($this->_table, 'COUNT(id)')
);
}