I'm converting my existing website to CI, and I have been trying for several days to convert this query to CI-friendly code:
$result = mysql_query("
SELECT t1.mnumber, t1.mcontent, t1.mcontact
FROM sms t1
JOIN (
SELECT mContent,mcontact, mnumber, MAX(mID) mID
FROM sms
GROUP BY mContact
) t2 ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
GROUP BY t1.mContact
ORDER BY t1.mid DESC
");
But no matter what I try, I can't get the correct result on CI.
I hope you guys can help me out here!
The closest to a result that i did get, was when i used the subquery hack.
However, out of frustration i deleted the block of code and kept trying.
I decided to use a flat query, like the one posted above. This almost gives me results.
$query = $this->db->query("SELECT t1.mnumber, t1.mcontent, t1.mcontact FROM sms t1
JOIN (SELECT mContent,mcontact, mnumber, MAX(mID) mID FROM sms GROUP BY mContact) t2
ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid GROUP BY t1.mContact ORDER BY t1.mid DESC");
$contacts = array();
//Add data to our array
foreach($query->result() as $row){
echo $row->mNumber;
}
return $contacts;
However, in my view i get the notice "Message: Undefined property: stdClass::$mNumber"
So still no results, plus i prefer the CI query method.
You can use it in codeigniter like this
$query = " SELECT t1.mnumber, t1.mcontent, t1.mcontact
FROM sms t1
JOIN (
SELECT mContent,mcontact, mnumber, MAX(mID) mID
FROM sms
GROUP BY mContact
) t2 ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
GROUP BY t1.mContact
ORDER BY t1.mid DESC";
$result = $this->db->query($query);
return $result->result();
2nd Method
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(
'mContent',
'mcontact',
'mnumber',
'MAX(mID) mID'
);
$this->db->select($select);
$this->db->from('sms');
$this->db->group_by('mContact');
$subquery = $this->db->_compile_select(); // get the query string
$this->db->_reset_select(); // reset so it can newly form the query
unset($select);
$select = array(
't1.mnumber',
't1.mcontent',
't1.mcontact'
);
$this->db->select($select);
$this->db->join('',"($subquery)");
$this->db->from('sms t1');
$this->db->group_by('t1.mContact');
$this->db->order_by('t1.mid','DESC');
$result = $this->db->get();
return $result->result();
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.
Er, shouldn't that be (at a guess)...
SELECT t1.mnumber
, t1.mcontent
, t1.mcontact
, t1.mid
FROM sms t1
JOIN
( SELECT mcontact
, MAX(mID) mID
FROM sms
GROUP BY mContact
) t2
ON t1.mcontact = t2.mcontact
AND t1.mid = t2.mid
ORDER
BY t1.mid DESC;
This may not fully answer your question, but for those of you who are Googling for a "JOIN AND" (so that you can AND some extra stuff on the Join, before the WHERE clause kicks in), here's a hacky way to do it:
$this->db->join('table_to_join', 'first_table.connect_id = table_to_join.id AND table_to_join.some_filter != 0');
Definitely not pretty, but that obviously forces the AND to occur immediately after the JOIN, before you get into the WHERE stuff for the rest of your query on first_table
Well, its easy to implement in CI version 3+
$subQuery = $this->db->select( 'table2.*' )
->join( 'table3', 'table3.orderId = table2.fkOrderId', 'INNER' )
->where()->get_compiled_select( 'table2' );
$this->db->select( 'table1.*' )
->join( '(' . $subQuery . ') AS b', 'b.`fkCouponId` = table1.couponId', 'LEFT', FALSE )
->get( 'table1' )
TIP: Make sure you don't use any query builder methods above the subquery part.
Related
I am running this query in phpmyadmin and it works fine. But on running it in joshcam's MySQLi Database class it gets wrong data
Query:
SELECT
s.az
, s.ta
, s.zamanSarfShode
, p.name
FROM
saateruzane s
JOIN
projhe p
JOIN
kareruzane k
WHERE
s.ProjheId = p.id
AND
k.id = s.ruzId
AND
k.ruzGregorian = date(now())
PHP code :
$con->join('projhe p', 's.ProjheId = p.id');
$con->join('kareruzane k', 'k.id = s.ruzId');
$con->joinWhere('kareruzane k','k.ruzGregorian', 'date(now())');
$tines = $con->get('saateruzane s',null,'s.az ,s.ta ,s.zamanSarfShode ,p.name');
The definition for joinWhere is
public function joinWhere($whereJoin, $whereProp, $whereValue = 'DBNULL', $operator = '=', $cond = 'AND')
So you don't need to pass in every part. Instead, try this:
$con->joinWhere('kareruzane k','k.ruzGregorian = date(now())');
Though better than date(now()) is CURDATE()
$con->joinWhere('kareruzane k','k.ruzGregorian = curdate()');
However, I'm not sure you should be using a join here, since it's part of the WHERE clause on your original query, not the JOIN clause. So instead do
$con->where('k.ruzGregorian = curdate()');
With just a fast look on this lib docs, I found this:
'createdAt' => $db->now(),
// createdAt = NOW()
https://github.com/joshcam/PHP-MySQLi-Database-Class#insert-query
In your case try use
$con->joinWhere('kareruzane k','k.ruzGregorian', $con->now());
Array to string conversion while passing query data(array) in where clause. I tried enough so now i'm going to scared of. I tried to to replace ->result() with ->row() in $ord = "query" but no sake. I Please any body help me, what should i do now. Thank you. Here is my code.
public function order_join()
{
$ord = $this->db->query('SELECT `Order_ID` FROM `order` WHERE `DateTime` = (SELECT MAX(DateTime) FROM `order`)')->result();
$query = "SELECT a.Order_ID, a.User_ID,a.Pro_ID, a.Price as Total_Amount, SUM(b.Amount)
as Total_Amount_Recieved, (a.Price - SUM(b.Amount)) AS Remaining_Amount
FROM `order` a JOIN `payments` b ON a.Order_ID = b.Order_ID WHERE a.Order_ID = '".$ord."' ";
return $this->db->query($query)->row();
}
and this is error.
I have got two tables :
Dress (dress_id, title)
Dress_comment (comment_id, dress_id, comment)
I have been trying from hours now and unable to convert this query into the corresponding Codeigniters' Active Class Record functions.
Here is the query :
SELECT d.dress_id, d.title, COALESCE(dc.count, 0)
FROM dress d
JOIN (select dress_id, count(comment_id) as count from dress_comment group by dress_id) dc
ON d.dress_id = dc.dress_id
ORDER BY d.dress_id;
This is what I have tried till now :
//Creating the select subquery for the inner join
$this->db->select('dress_id, count(comment_id) as count')
->from('Dress_comment')
->group_by('dress_id')
->get();
$subQuery = $this->db->last_query();
//Main Query
$this->db->select('d.dress_id, d.title, COALESCE(dc.count,0)')
->from('Dress')
->join($subQuery . ' dc','dc.dress_id = d.dress_id','left')
->order_by('d.dress_id');
$result = $this->db->get();
return $result->result_array();
But Codeigniter is not running this query and always giving mysql syntax error. The sql format that codeigniter is converting this active methods to is
SELECT `d`.`dress_id`, `d`.`title`, COALESCE(dc.count, `0)`
FROM (`Dress`) LEFT JOIN `SELECT` `dress_id`, count(comment_id) as count
FROM (`Dress_comment`)
GROUP BY `dress_id` dc
ON `dc`.`dress_id` = `d`.`dress_id`
ORDER BY `d`.`dress_id`
I was able to solve the problem using the mysql query in the join function like this :
$this->db->select('d.dress_id, d.title, dc.count as comments, dl.count as likes, dt.title, di.image_url')
->from('Dress d')
->join('(select dress_id, count(comment_id) as count from dress_comment group by dress_id) dc','dc.dress_id = d.dress_id','left')
->order_by('d.dress_id');
I have the following SQL query but I can't seem to find out how I would change this query to make it work with CI:
SELECT *
FROM Table1
JOIN Table2 ON Table2.tID = Table1.tID
JOIN Table3 ON Table3.vID = Table2.vID
WHERE vegetable
IN (
'Potatoe', 'Carrot'
)
GROUP BY Table1.tID
HAVING COUNT( DISTINCT vegetable ) =2
Here is what I have so far on CI:
$arrCount = count($array);
$this->db->select('*');
this->db->from('Table1');
$this->db->join('Table2', 'Table2.tID = Table1.tID');
$this->db->join('Table3', 'Table3.vID = Table2.vID');
$this->db->where_in('vegetable', $array);
$this->db->group_by("Table1.tID");
$this->db->having('vegetable');
$this->db->count_all($arrCount);
$q = $this->db->get();
But doing this gives me the following sql statement:
Table 'DatabaseTest.2' doesn't exist
SELECT COUNT(*) AS `numrows` FROM `2`
I am pretty sure the ActiveRecord count I have used is incorrect but I am not sure what else it would be because I have found any COUNT() function with CI.
So my question is how can I make my SQL query in CodeIgniter?
Extra note, I have also tried running the query using CIs $this->db->query but get an array error, when looking with the in.
$this->db->query('SELECT *
FROM Table1
JOIN Table2 ON Table2.tID = Table1.tID
JOIN Table3 ON Table3.vID = Table2.vID
WHERE vegetables
IN (
' .$array . '
)
GROUP BY Table1.tID
HAVING COUNT( DISTINCT vegetables ) =' . $arrCount);
And heres the error message:
Unknown column 'Array' in 'where clause'
So it is assuming that I am using a where instead of a where in it looks like. Again can someone help me get my sql to work with CIs active record?
I haven't tested the first query with active records, but wouldn't this work? count_all is a query of on it's own. The first parameter is suppose to be the table... you entered the size of your array as the table which is 2!!! active records reference
$arrCount = sizeof($array);
$this->db->select('*');
this->db->from('Table1');
$this->db->join('Table2', 'Table2.tID = Table1.tID');
$this->db->join('Table3', 'Table3.vID = Table2.vID');
$this->db->where_in('vegetable', $array);
$this->db->group_by("Table1.tID");
$this->db->having('COUNT(DISTINCT vegetable)', $arrCount);
$q = $this->db->get();
Also, for the query, you need to convert your array into a string:
$this->db->query('SELECT *
FROM Table1
JOIN Table2 ON Table2.tID = Table1.tID
JOIN Table3 ON Table3.vID = Table2.vID
WHERE vegetables
IN (
' .implode(',',$array) . '
)
GROUP BY Table1.tID
HAVING COUNT( DISTINCT vegetables ) =' . $arrCount);
$this->db->query('SELECT *
FROM Table1
JOIN Table2 ON Table2.tID = Table1.tID
JOIN Table3 ON Table3.vID = Table2.vID
WHERE vegetables
IN ("' . implode('", "', $array) . '")'
GROUP BY Table1.tID
HAVING COUNT( DISTINCT vegetables ) =' . $arrCount);
Use implode() to turn your array into a MySQL readable string.
EDIT: Implode with quotes.
I might suggest get $this->db->count_all($arrCount); line away, at less until you get this working.
Hi I want to convert my normal mysql query to zend.db.select;
I want to use this script:
$select = $db->select();
// Add a FROM clause
$select->from( ...specify table and columns... )
// Add a WHERE clause
$select->where( ...specify search criteria... )
// Add an ORDER BY clause
$select->order( ...specify sorting criteria... );
$select->limit(20, 10);
for my query below
SELECT
IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid) friend1,c.UserName,
derived_messages.message, derived_messages.fromid, derived_messages.toid,
derived_messages.is_read,derived_messages.type,derived_messages.id as mesid,
derived_messages.date,
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1) as MesMapid
FROM
(
SELECT *
FROM messages
WHERE messages.deleted_by NOT
IN ( $user )
ORDER BY Date DESC
) derived_messages
INNER JOIN Users c ON c.MemberID = IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid)
WHERE (derived_messages.id IN
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1)
AND
(derived_messages.toid='$user' OR derived_messages.fromid='$user'))
GROUP BY friend1 ASC
ORDER BY derived_messages.date DESC, derived_messages.id DESC LIMIT $limit $offset
I hope someone can help m on this.
Thank you.
It's possible but unlikely someone will write the query for you.
My recommendation on tackling such a query is to write each individual subquery as its own Zend_Db_Select object and then build the final query using the subqueries that you already have objects for.
Zend_Db_Select doesn't directly support the IF function, so for that you will need to use Zend_Db_Expr to add that statement into your select.
Here is a basic example of what I am talking about. Let's build the following query:
SELECT IF(msg.toId = 'drew010', msg.fromId, msg.toId), id, name, age, history.ip
FROM users
JOIN history ON users.id = history.userId
WHERE users.id = (
SELECT id FROM users WHERE loginCount > 1000
)
GROUP BY id,
ORDER BY age DESC
First build the subselect that select users where loginCount > 1000.
$subquery1 = $db->select()
->from('users', array('id'))
->where('loginCount > ?', 1000);
Next, build the outer query with the IF function:
$cols = array(
new Zend_Db_Expr('IF(' . $db->quoteInto('msg.toId = ?', 'drew010') . '), msg.fromId, msg.toId'),
'id', 'name', 'age'
);
$query = $db->select()
->from('users', $cols)
->join('history', 'users.id = history.userId', array('ip'))
->where('id = ?', $subquery1)
->group('id')
->order('age DESC');
echo $query;
The output:
SELECT
IF(msg.toId = 'drew010', msg.fromId, msg.toId),
`users`.`id`,
`users`.`name`,
`users`.`age`,
`history`.`ip`
FROM `users`
INNER JOIN `history`
ON users.id = history.userId
WHERE id = (
(SELECT `users`.`id`
FROM `users`
WHERE (loginCount > 1000))
)
GROUP BY `id`
ORDER BY `age` DESC
So the way to go is break the entire query into individual queries first, and then construct the outer query. Just have patience and take it slow. That and read over the Zend_Db_Select docs to get a full picture of what you have available to you.