how to add new field & value from selected joined table - sql

i have a joined table like this
i want to create new field named qty_exceed and the value is based from
(qty_stock - qty_taken)
do i have to do it in the query or make separate operation and store it in a varible?
my code
$getmaterial = ContractProduct::select(
'product_item.ref_rof_id',
'product_item.code',
'product_item.qty_stock',
'contract_product.qty_taken'
)
->where('ref_rof_id', $getrof->ref_rof_id)
->join('product_item', 'contract_product.ref_product_id', '=', 'product_item.code')
->get();
$data['getquoid'] = $getquoid;
$data['getmaterial'] = $getmaterial;
$view = $this->module_path . '.next-create';
return response()->view($view, $data);

You need to use DB::raw
But remember, raw statements will be injected into the query as strings, so you should be extremely careful to not create SQL injection vulnerabilities.
With DB::raw your code will look like this:
$getmaterial = ContractProduct::select(
'product_item.ref_rof_id',
'product_item.code',
'product_item.qty_stock',
'contract_product.qty_taken',
ContractProduct::raw('product_item.qty_stock - contract_product.qty_taken as qty_exceed')
)
->where('ref_rof_id', $getrof->ref_rof_id)
->join('product_item', 'contract_product.ref_product_id', '=', 'product_item.code')
->get();
$data['getquoid'] = $getquoid;
$data['getmaterial'] = $getmaterial;
$view = $this->module_path . '.next-create';
return response()->view($view, $data);

Related

Can Laravel automatically switch between column = ? and column IS NULL depending on value?

When building a complex SQL query for Laravel, using ? as placeholders for parameters is great. However when the value is null, the SQL syntax needs to be changed from = ? to IS NULL. Plus, since the number of parameters is one less, I need to pass a different array.
To get it to work, I have written it like this, but there must be a better way:
if ($cohortId === null) {
// sql should be: column IS NULL
$sqlCohortString = "IS NULL";
$params = [
Carbon::today()->subDays(90),
// no cohort id here
];
} else {
// sql should be: column = ?
$sqlCohortString = "= ?";
$params = [
Carbon::today()->subDays(90),
$cohortId
];
}
$query = "SELECT items.`name`,
snapshots.`value`,
snapshots.`taken_at`,
FROM snapshots
INNER JOIN (
SELECT MAX(id) AS id, item_id
FROM snapshots
WHERE `taken_at` > ?
AND snapshots.`cohort_id` $sqlCohortString
GROUP BY item_id
) latest
ON latest.`id` = snapshots.`id`
INNER JOIN items
ON items.`id` = snapshots.`item_id`
ORDER by media_items.`slug` ASC
";
$chartData = DB::select($query, $params);
My question is: does Laravel have a way to detect null values and replace ? more intelligently?
PS: The SQL is for a chart, so I need the single highest snapshot value for each item.
You can use ->when to create a conditional where clause:
$data = DB::table('table')
->when($cohortId === null, function ($query) {
return $query->whereNull('cohort_id');
}, function ($query) use ($cohortId) {
// the "use" keyword provides access to "outer" variables
return $query->where('cohort_id', '=', $cohortId);
})
->where('taken_at', '>', $someDate)
->toSql();

how to select query tables column with objects in query builder

i am joining two tables with query builder. here is the sample
$events = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name',)
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')->get();
can i declare an object of eventcalender as e and select with object name like 'e.id','e.event_name'.?
Yes, after the query you need to loop through them since they are more than one item:
foreach($events as $e){
$name = $e->event_name;
}
If you want to select only the first one that meets your constrains then use .first().
$event = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name',)
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')->first();
$name = $event->event_name;
$events = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name','countries.*')
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')
->get();
Afetr getting results
foreach($events as $event)
{
echo $event->event_name;
echo $event->country_name; //your specific field
}

codeigniter change complex query into active record

I have a codeigniter app.
My active record syntax works perfectly and is:
function get_as_09($q){
$this->db->select('m3');
$this->db->where('ProductCode', $q);
$query = $this->db->get('ProductList');
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$row_set[] = htmlentities(stripslashes($row['m3'])); //build an array
}
return $row_set;
}
}
This is effectively
select 'm3' from 'ProductList' where ProductCode='$1'
What I need to do is convert the below query into an active record type query and return it to the controller as per above active record syntax:
select length from
(SELECT
[Length]
,CONCAT(([width]*1000),([thickness]*1000),REPLACE([ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]) as p
where options='25100cr' order by length
I picture something like below but this does not work.
$this->db->select(length);
$this->db->from(SELECT [Length],CONCAT(([width]*1000),([thickness]*1000),REPLACE[ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]);
$this->db->where(options, $q);
$this->db->order(length, desc);
Help appreciated as always. Thanks again.
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
$select = array(
'Length'
'CONCAT(([width]*1000)',
'thickness * 1000',
'REPLACE(ProductCode, concat((width*1000),(thickness*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options'
);
$this->db->select($select);
$this->db->from('ProductList');
$Subquery = $this->db->_compile_select();
$this->db->_reset_select();
$this->db->select('length');
$this->db->from("($Subquery)");
$this->db->where('options','25100cr');
$this->db->order_by('length');
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.
Source

How to get particular column in zend using Left join

I am new to zend framework,
Following is the plain mysql query which takes particular column from table,
SELECT jobs_users.id,jobs_users.first_name from jobs_users left join friends on jobs_users.id=friends.friend_id where friends.member_id=29
I tried with zend to implement the above query like below,
public function getFriendsProfileList($id){
$db = Zend_Db_Table::getDefaultAdapter();
$select = $db->select();
$select->from('jobs_users')
->joinLeft(
'friends',
'jobs_users.id=friends.friend_id',
array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo')
)
->where("friends.member_id = ?", $id);
$result = $db->fetchAll($select);
return $result;
}
Here i got result with all column name , not with exact column name which i have given in query.
Kindly help me on this.
Use this instead:
$select->from('jobs_users', array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo'))
->joinLeft('friends', 'jobs_users.id=friends.friend_id')
->where("friends.member_id = ?", '20');
You may also try this:
$select = $db->select();
$select->setIntegrityCheck(false);
$select->joinLeft('jobs_users','',array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo'));
$select->joinLeft('friends','jobs_users.id=friends.friend_id', array());
$select->where("friends.member_id = ?", $id);
$result = $db->fetchAll($select);
return $result;

how to get last inserted id - zend

I'm trying to get latest inserted id from a table using this code:
$id = $tbl->fetchAll (array('public=1'), 'id desc');
but it's always returning "1"
any ideas?
update: I've just discovered toArray();, which retrieves all the data from fetchAll. The problem is, I only need the ID. My current code looks like this:
$rowsetArray = $id->toArray();
$rowCount = 1;
foreach ($rowsetArray as $rowArray) {
foreach ($rowArray as $column => $value) {
if ($column="id") {$myid[$brr] = $value;}
//echo"\n$myid[$brr]";
}
++$rowCount;
++$brr;
}
Obviously, I've got the if ($column="id") {$myid[$brr] = $value;} thing wrong.
Can anyone point me in the right direction?
An aternative would be to filter ID's from fetchAll. Is that possible?
Think you can use:
$id = $tbl->lastInsertId();
Aren't you trying to get last INSERT id from SELECT query?
Use lastInsertId() or the value returned by insert: $id = $db->insert();
Why are you using fetchAll() to retrieve the last inserted ID? fetchAll() will return a rowset of results (multiple records) as an object (not an array, but can be converted into an array using the toArray() method). However, if you are trying to reuse a rowset you already have, and you know the last record is the first record in the rowset, you can do this:
$select = $table->select()
->where('public = 1')
->order('id DESC');
$rows = $table->fetchAll($select);
$firstRow = $rows->current();
$lastId = $firstRow->id;
If you were to use fetchRow(), it would return a single row, so you wouldn't have to call current() on the result:
$select = $table->select()
->where('public = 1')
->order('id DESC');
$row = $table->fetchRow($select);
$lastId = $row->id;
It sounds like it's returning true rather than the actual value. Check the return value for the function fetchAll