yii2-Active record with not in condition - activerecord

I am working on yii2. I am using active record for searching a reference number. The query is below
$q = isset($_GET['q']) ? $_GET['q'] : '';
if(empty($q)) exit;
$ser = Survey::find()->where("ref_no like '%$q%'")->andWhere(['status'=>1])->asArray()->all();
return json_encode($ser);
The above query will get all the reference numbers which are in survey table. Now I want to add a NOT IN condition. The raw query is below
...... where ref_no LIKE '%$q%' NOT IN (select ref_no from installations where ref_no LIKE '%q%')
How can I add this to my active record query?
Any help would be highly appreciated.

You can use subquery for this too (assuming your installation table i related to Installations model)
$subQuery = Installations::find()->select('ref_no')->where("ref_no like '%$q%'");
$query = Survey::find()->where(['not in', 'ref_no', $subQuery]);
$models = $query->all();

Change Your Query as Below :
$ser = Survey::find()->where("ref_no like '%$q%'")
->andWhere(['status'=>1])
->andWhere("ref_no NOT IN (select ref_no from installations where ref_no LIKE '%q%')")
->asArray()->all();
OR
$ser = Survey::find()
->where("ref_no like '%$q%' AND ref_no NOT IN (select ref_no from installations where ref_no LIKE '%q%')")
->andWhere(['status'=>1])
->asArray()->all();

Related

Convert SQL to Laravel Eloquent Statement

I've been working on a few tables where through a rather complex relationship (that I'm trying to clean up, but I still need reports made from the data through my Laravel).
At the moment, I can pull the data using the following SQL query to my MySQL database:
SELECT
customers.id,
customers.customer_name,
SUM(shipments.balance) AS shipmentBalance
FROM customers
LEFT JOIN shipments
ON customers.id = shipments.bill_to
AND balance > (SELECT IFNULL(SUM(payments_distributions.amount),0)
FROM payments_distributions
WHERE payments_distributions.shipment_id = pro_number)
GROUP BY customers.id, customers.customer_name
ORDER BY shipmentBalance DESC
LIMIT 5;
I'm just not sure how to rewrite it properly into the whereRaw or DB::raw statements that Laravel Eloquent requires, as my previous attempts have failed.
Update
Here is the closest solution I have tried:
DB::table('customers')
->select('customers', DB::raw('SUM(shipments.balance) AS shipmentBalance'))
->leftJoin(
DB::raw('
(select shipments
ON customers.id = shipments.bill_to
AND balance > (SELECT IFNULL(SUM(payments_distributions.amount),0)
FROM payments_distributions
WHERE payments_distributions.shipment_id = pro_number)'))
->groupBy('customers.id')
->orderByRaw('shipmentBalance DESC')
->limit(5)
->get();
Update 2
Edit for Dom:
Using everything as it stands with your answer, I get the following response:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'on clause' (SQL: select customers.id, customers.customer_name,SUM(s.balance) AS shipmentBalance from `customers` left join `shipments` as `s` on `customers`.`id` = `s`.`bill_to` and s.balance > (SELECT IFNULL(SUM(payments_distributions.amount),0) FROM payments_distributions WHERE payments_distributions.shipment_id = s.pro_number) = `` group by `customers`.`id`, `customers`.`customer_name` order by SUM(s.balance) DESC limit 5)
But if I remove this section, it brings up the page and the customers (though in the wrong order as I have removed one of the necessary components:
$join->on(DB::raw('s.balance >
(SELECT IFNULL(SUM(payments_distributions.amount),0)
FROM payments_distributions
WHERE payments_distributions.shipment_id = s.pro_number)
'));
Is there anything I can provide you with to get this specific statement to work with your entire answer?
Use this:
DB::table('customers')
->select('customers.id', 'customers.customer_name', DB::raw('SUM(shipments.balance) AS shipmentBalance'))
->leftJoin('shipments', function($join) {
$join->on('customers.id', 'shipments.bill_to')
->where('balance', '>', function($query) {
$query->selectRaw('IFNULL(SUM(payments_distributions.amount),0)')
->from('payments_distributions')
->where('payments_distributions.shipment_id', DB::raw('pro_number'));
});
})
->groupBy('customers.id', 'customers.customer_name')
->orderByDesc('shipmentBalance')
->limit(5)
->get();
Without the Models containing relationships or being able to test on this specific project, this is the most eloquent way I can think of performing your task.
The benefit of starting with the Customer model is you will have a laravel collection and can paginate as needed. Also review the eloquent docs, they help you understand all the different options. Hope his helps.
P.S. Start by using your model in your controller or wherever you are placing this query with:
use App\Customer
The query
$theQuery = Customer::select(DB::raw('customers.id, customers.customer_name,SUM(s.balance) AS shipmentBalance'))
->leftJoin('shipments as s', function($join)
{
$join->on('customers.id', '=', 's.bill_to');
$join->on(DB::raw('s.balance >
(SELECT IFNULL(SUM(payments_distributions.amount),0)
FROM payments_distributions
WHERE payments_distributions.shipment_id = s.pro_number)
'));
})
->groupBy('customers.id', 'customers.customer_name')
->orderByRaw('SUM(s.balance) DESC')
->limit(5)
->get();

how we insert multiple data into a table one column in sql

$query= $this->db->query("INSERT INTO _errorlog SET errors = ".$this->db->escape($post['season']).$this->db->escape($post['venue']).$this->db->escape($post['week'])($post['home_team']).$this->db->escape($post['away_team']));
Please try with this,
$query= $this->db->query("INSERT INTO _errorlog SET errors = ".$this->db->escape($post['season']).$this->db->escape($post['venue']).$this->db->escape($post['week']).$this->db->escape($post['home_team']).$this->db->escape($post['away_team']));
Your database query was wrong.
Check ($post['home_team']) at your db query, looks like you have forget add .$this->dbc->escape().
$q = INSERT INTO _errorlog SET errors = ".$this->db->escape($post['season']).$this->db->escape($post['venue']).$this->db->escape($post['week'])($post['home_team']).$this->db->escape($post['away_team'])
So your query should be this.
$q = 'INSERT INTO _errorlog SET errors = "'.$this->db->escape($post['season']).$this->db->escape($post['venue']).$this->db->escape($post['week']).$this->db->escape($post['home_team']).$this->db->escape($post['away_team']).'"';

Interleaving the rows of two different SQL tables, group by one row

My Sql query is like this
$view = mysql_query ("SELECT domain,count(distinct session_id) as
views FROM `statistik` left join statistik_strippeddomains on
statistik_strippeddomains.id = statistik.strippeddomain WHERE
`angebote_id` = '".(int)$_GET['id']."' and strippeddomain!=1
group by domain having count (distinct session_id) >
".(int)($film_daten['angebote_views']/100)." order
count(distinct session_id$vladd) desc limit 25");
How can I write its Codeigniter Model I appreciate any Help
try this
$this->db->select('statistik.domain,statistik.count(DISTINCT(session_id)) as views');
$this->db->from('statistik');
$this->db->join('statistik_strippeddomains', 'statistik_strippeddomains.id = statistik.strippeddomain', 'left');
$this->db->where('angebote_id',$_GET['id']);
$this->db->where('strippeddomain !=',1);
$this->db->group_by('domain');
$this->db->having('count > '.$film_daten['angebote_views']/100, NULL, FALSE);
$this->db->order_by('count','desc');
$this->db->limit('25');
$query = $this->db->get();
Comment me If you have any query.

Using Mysql WHERE IN clause in codeigniter

I have the following mysql query. Could you please tell me how to write the same query in Codeigniter's way ?
SELECT * FROM myTable
WHERE trans_id IN ( SELECT trans_id FROM myTable WHERE code='B')
AND code!='B'
You can use sub query way of codeigniter to do this for this purpose you will have to hack codeigniter. like this
Go to system/database/DB_active_rec.php
Remove public or protected keyword from these functions
public function _compile_select($select_override = FALSE)
public function _reset_select()
Now subquery writing in available
And now here is your query with active record
$this->db->select('trans_id');
$this->db->from('myTable');
$this->db->where('code','B');
$subQuery = $this->db->_compile_select();
$this->db->_reset_select();
// And now your main query
$this->db->select("*");
$this->db->where_in("$subQuery");
$this->db->where('code !=', 'B');
$this->db->get('myTable');
And the thing is done. Cheers!!!
Note : While using sub queries you must use
$this->db->from('myTable')
instead of
$this->db->get('myTable')
which runs the query.
Watch this too
How can I rewrite this SQL into CodeIgniter's Active Records?
Note : In Codeigntier 3 these functions are already public so you do not need to hack them.
$data = $this->db->get_where('columnname',array('code' => 'B'));
$this->db->where_in('columnname',$data);
$this->db->where('code !=','B');
$query = $this->db->get();
return $query->result_array();
Try this one:
$this->db->select("*");
$this->db->where_in("(SELECT trans_id FROM myTable WHERE code = 'B')");
$this->db->where('code !=', 'B');
$this->db->get('myTable');
Note: $this->db->select("*"); is optional when you are selecting all columns from table
try this:
return $this->db->query("
SELECT * FROM myTable
WHERE trans_id IN ( SELECT trans_id FROM myTable WHERE code='B')
AND code!='B'
")->result_array();
Is not active record but is codeigniter's way http://codeigniter.com/user_guide/database/examples.html
see Standard Query With Multiple Results (Array Version) section
you can use a simpler approach, while still using active record
$this->db->select("a.trans_id ,a.number, a.name, a.phone")
$this->db->from("Name_Of_Your_Table a");
$subQueryIn = "SELECT trans_id FROM Another_Table";
$this->db->where("a.trans_id in ($subQueryIn)",NULL);

"SELECT ... IN (SELECT ...)" query in CodeIgniter

I have a query similar to this:
SELECT username
FROM users
WHERE locationid IN
(SELECT locationid FROM locations WHERE countryid='$')
$ is a value I get from end user.
How could I run this query in CodeIgniter? I can't find a solution in CodeIgnite's user guide.
Thank you so much for your answers!
Regards!
Look here.
Basically you have to do bind params:
$sql = "SELECT username FROM users WHERE locationid IN (SELECT locationid FROM locations WHERE countryid=?)";
$this->db->query($sql, '__COUNTRY_NAME__');
But, like Mr.E said, use joins:
$sql = "select username from users inner join locations on users.locationid = locations.locationid where countryid = ?";
$this->db->query($sql, '__COUNTRY_NAME__');
Note that these solutions use the Code Igniter Active Records Class
This method uses sub queries like you wish but you should sanitize $countryId yourself!
$this->db->select('username')
->from('user')
->where('`locationId` in', '(select `locationId` from `locations` where `countryId` = '.$countryId.')', false)
->get();
Or this method would do it using joins and will sanitize the data for you (recommended)!
$this->db->select('username')
->from('users')
->join('locations', 'users.locationid = locations.locationid', 'inner')
->where('countryid', $countryId)
->get();
Also, to note - the Active Record Class also has a $this->db->where_in() method.
I think you can create a simple SQL query:
$sql="select username from user where id in (select id from idtables)";
$query=$this->db->query($sql);
and then you can use it normally.

Resources