I'm kind of new on codeigniter, hope you can help me.
I have a sql query below, how would it look like on codeigniter framework?
SELECT m.conversation_id, count(m.message_id)
FROM cms_conversations__messages AS m
LEFT JOIN cms_conversations__participants AS p ON p.conversation_id = m.conversation_id AND (p.last_read IS NULL OR m.added > p.last_read) AND m.user_id != 2
WHERE p.user_id = 2
GROUP BY p.user_id
Thank you in advance.
If you are sure that your query is right then this is the codeigniter way to do it
$this->db->select('m.conversation_id, count(m.message_id) as message_count');
$this->db->from('cms_conversations__messages as m');
$this->db->join('cms_conversations__participants as p', 'p.conversation_id = m.conversation_id and (p.last_read IS NULL OR m.added > p.last_read) and m.user_id != 2', 'left');
$this->db->where('p.user_id', '2');
$this->db->group_by('p.user_id');
return $this->db->get()->result(); // or you can also store it in a variable
For more you can see the documention.
Hope It helps
As an alternative to using Query Builder you can regular query using query() which supports bound data. (Documented Here)
In your case, it could be done like this.
$sql = "SELECT m.conversation_id, count(m.message_id)
FROM cms_conversations__messages AS m
LEFT JOIN cms_conversations__participants AS p ON p.conversation_id = m.conversation_id
AND (p.last_read IS NULL OR m.added > p.last_read)
AND m.user_id != ? WHERE p.user_id = ? GROUP BY p.user_id";
$id = 2;
$query = $this->db->query($sql, [$id, $id]);
//$query might be FALSE, always check for that before trying to get a dataset
if($query !== FALSE)
{
return $query->result();
}
return FALSE;
The data is bound to the two question marks in the $sql string which gets supplied as the array (i.e. [$id, $id]) in the second argument to query().
Related
Hello,
I am working on a Posts and Comment Models response API in Code Igniter!
MY Controller:
public function getPosts()
{
if (isset($_POST["getPosts"]))
{
$data = $this->api_model->getPosts();
$json_response2 = array('status' => 'success', 'postList' => $data->result_array());
echo json_encode($json_response2);
}
else
{
$data['status'] = 'error';
echo json_encode($data);
}
}
My Model:
public function get_posts()
{
$this->db->order_by('postID', 'DESC');
$query = $this->db->get('posts');
return $query->result_array();
}
MYSQL Tables:
for Posts---
postID | postTitle | postBody
for Comments---
commentID | postID | commentBody
I want to Get Comments Count for post Array in API response to display list of posts and comments Count for that Post?
ThankYou!
This is the query needed for you to get all those data in single query. It will join both table with left join clause and will give you the comment count as well.
SELECT
p.`postID`,
`postTitle`,
`postBody`,
COUNT(c.commentID) AS comment_cnt
FROM
`Posts` AS p
LEFT JOIN `Comments` AS c
ON p.postID = c.postID
GROUP BY c.postID
ORDER BY p.postID DESC ;
N:B left join is mandatory, otherwise it will not give you zero
commented post.
to convert it to codeigniter you can write it as.
$this->db->from('Posts p');
$this->db->join('Comments c','p.postID = c.postID','left');
$this->db->group_by('c.postID');
$this->db->order_by('p.postID', 'DESC');
$this->db->select('p.*,COUNT(c.commentID) AS comment_cnt');
$query = $this->db->get();
$res = $query->result_array();
Hope this would help you.
You need to join your comments table to get count and group by your postID.
Modify your get_posts() function in model as follows:
$this->db->from('posts');
$this->db->select("posts.*, count(*) as comments_count");
$this->db->join('comments', 'posts.postID = comments.postID');
$this->db->group_by('posts.postID');
$this->db->order_by('postID', 'DESC');
return $this->db->get()->result_array();
Also, you are using result_array() twice which is wrong. Change your controller line
$json_response2 = array('status' => 'success', 'postList' => $data->result_array());
as
$json_response2 = array('status' => 'success', 'postList' => $data);
because you are already getting result from model.
Also, use the correct name for function in controller, $this->api_model->get_posts();
Hope it helps.
SELECT apntoken,deviceid,created
FROM `distribution_mobiletokens` as dm
WHERE userid='20'
and not exists (
select 1
from `distribution_mobiletokens`
where userid = '20'
and deviceid = dm.deviceid
and created > dm.created
)
What this query does is selects all mobiletokens where the user id is equal to 20 and the deviceid is the same but chooses the newest apntoken for the device.
My database looks like below.
For more information on this query, I got this answer from another question I asked here(How to group by in SQL by largest date (Order By a Group By))
Things I've Tried
$mobiletokens = $em->createQueryBuilder()
->select('u.id,company.id as companyid,user.id as userid,u.apntoken')
->from('AppBundle:MobileTokens', 'u')
->leftJoin('u.companyId', 'company')
->leftJoin('u.userId', 'user')
->where('u.status = 1 and user.id = :userid')
->setParameter('userid',(int)$jsondata['userid'])
->groupby('u.apntoken')
->getQuery()
->getResult();
//#JA - Get the list of all the apn tokens we need to send the message to.
foreach($mobiletokens as $tokenobject){
$deviceTokens[] = $tokenobject["apntoken"];
echo $tokenobject["apntoken"]."\n";
}
die();
This gives me the incorrect response of
63416A61F2FD47CC7B579CAEACB002CB00FACC3786A8991F329BB41B1208C4BA
9B25BBCC3F3D2232934D86A7BC72967A5546B250281FB750FFE645C8EB105AF6
latestone
Any help here is appreciated!
Other Information
Data with SELECT * FROM
Data after using the SQL I provided up top.
You could use a subselect created with the querybuilder as example:
public function selectNewAppToken($userId)
{
// get an ExpressionBuilder instance, so that you
$expr = $this->_em->getExpressionBuilder();
// create a subquery in order to take all address records for a specified user id
$sub = $this->_em->createQueryBuilder()
->select('a')
->from('AppBundle:MobileTokens', 'a')
->where('a.user = dm.id')
->andWhere('a.deviceid = dm.deviceid')
->andWhere($expr->gte('a.created','dm.created'));
$qb = $this->_em->createQueryBuilder()
->select('dm')
->from('AppBundle:MobileTokens', 'dm')
->where($expr->not($expr->exists($sub->getDQL())))
->andWhere('dm.user = :user_id')
->setParameter('user_id', $userId);
return $qb->getQuery()->getResult();
}
I did this for now as a temporary fix, not sure if this is best answer though.
$em = $this->em;
$connection = $em->getConnection();
$statement = $connection->prepare("
SELECT apntoken,deviceid,created
FROM `distribution_mobiletokens` as dm
WHERE userid=:userid
and not exists (
select 1
from `distribution_mobiletokens`
where userid = :userid
and deviceid = dm.deviceid
and created > dm.created
)");
$statement->bindValue('userid', $jsondata['userid']);
$statement->execute();
$mobiletokens = $statement->fetchAll();
//#JA - Get the list of all the apn tokens we need to send the message to.
foreach($mobiletokens as $tokenobject){
$deviceTokens[] = $tokenobject["apntoken"];
echo $tokenobject["apntoken"]."\n";
}
I am trying to leftjoin off of the entity_id, but just receiving a error without details.
Is there a trick to leftjoin off of the entity_id in Drupal?
$query = db_query('SELECT COUNT(n.field_feed_vehicle_code_value) FROM {field_data_field_feed_vehicle_code} n LEFT JOIN {field_data_field_feed_vehicle_date_used} du ON n.entity_id = du.entity_id WHERE n.field_feed_vehicle_code_value = :utilization AND du.field_feed_vehicle_date_used = :utilization_date', array(':utilization' => $fieldVehicleCode, ':utilization_date' => $fieldDVIRDate))->fetchField();
I found other questions talking about leftjoins, but nothing really on entity_id. I also found this Drupal 7 select query with joins but this solution did not work either.
$query = db_select('node', 'n');
$query->leftJoin('field_data_field_feed_vehicle_code', 'vc', 'n.nid = vc.entity_id');
$query->leftJoin('field_data_field_feed_vehicle_date_used', 'du', 'n.nid = du.entity_id');
$query
->fields('n', array('nid'))
->fields('vc.field_feed_vehicle_code_value', $fieldVehicleCode , '=')
->fields('du.field_feed_vehicle_date_used', $fieldDVIRDate , '=')
->condition('type', 'dvir_utilization_feed')
->condition('status', 1)
->execute();
$num = $query->rowCount();
I believe that you want to use
->condition('vc.field_feed_vehicle_code_value', $fieldVehicleCode , '=')
->condition('du.field_feed_vehicle_date_used', $fieldDVIRDate , '=')
as that is not the correct syntax for ->fields
I ended up having the wrong field name and had to do db_query, although I would have preferred db_select.
$query = db_query('SELECT COUNT(vc.field_feed_vehicle_code_value)
FROM {node} n
LEFT JOIN {field_data_field_feed_vehicle_code} vc ON n.nid = vc.entity_id
LEFT JOIN {field_data_field_feed_vehicle_date_used} du ON n.nid = du.entity_id
WHERE vc.field_feed_vehicle_code_value = :utilization
AND du.field_feed_vehicle_date_used_value = :utilization_date',
array(':utilization' => $fieldVehicleCode, ':utilization_date' => $fieldDVIRDate))->fetchField();
$utilization = $query;
I want to implement the following sql query:
SELECT title
FROM sys_category
JOIN sys_category_record_mm ON sys_category.uid = sys_category_record_mm.uid_local
JOIN tt_content ON sys_category_record_mm.uid_foreign = tt_content.uid
WHERE tt_content.uid = 645
If I execute this query directly via phpmyadmin it is working, but if I try the following via userfunction the content of $row is false, so I think the syntax for my multi join must be wrong. Hope you can help me :)
public function getCategories()
{
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery
(
'title',
'sys_category JOIN sys_category_record_mm ON sys_category.uid = sys_category_record_mm.uid_local JOIN tt_content ON sys_category_record_mm.uid_foreign = tt_content.uid',
'sys_category.uid = 645'
);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc( $res );
var_dump( $row );
}
My bad, the problem was, that I used
'sys_category.uid = 645'
instead of
'tt_content.uid = 645'
Basically, I need to order a list of WordPress users by the city they live in. I've got a custom user meta field for city, and I've got the query working properly, but the query lists everyone who hasn't filled out a city at the beginning since it places blank fields at the beginning of the order.
What I need is to figure out how to only select and display users who have given a value other than blank in the city field. Unfortunately, I've found myself stumped.
Any thoughts on how to do this? Also, if anyone knows a way to orderby a custom user meta field using wp_user_query as opposed to this mess, I'm all ears.
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$limit = 10;
$offset = ($paged - 1) * $limit;
$key = 'city';
$sql = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
INNER JOIN {$wpdb->usermeta} wp_usermeta ON ({$wpdb->users}.ID = wp_usermeta.user_id)
INNER JOIN {$wpdb->usermeta} wp_usermeta2 ON ({$wpdb->users}.ID = wp_usermeta2.user_id)
WHERE 1=1
AND wp_usermeta.meta_key = 'wp_capabilities'
AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%\"subscriber\"%'
AND wp_usermeta2.meta_key = '$key'
ORDER BY wp_usermeta2.meta_value ASC
LIMIT $offset, $limit";
$site_users = $wpdb->get_results($sql);
$found_rows = $wpdb->get_var("SELECT FOUND_ROWS();");
foreach ($site_users as $site_user) {
// user info here
}
Try something like
...
WHERE 1=1
AND wp_whatever.name_of_city IS NOT NULL
AND LENGTH(wp_whatever.name_of_city) > 0
AND wp_usermeta.meta_key = 'wp_capabilities'
...