SQL query with multiple Joins using CodeIgniter active records - sql

I have this working query:
$q = $this->db->query('SELECT u.name FROM users u
JOIN user_group ug ON u.id = ug.user_id
JOIN groups g ON g.id = ug.group_id WHERE ug.group_id = "4" ');
And I want to replace it with aactive record. I come up with something like this but obviously it doesn't work :
$this->db->select('name');
$this->db->from('users');
$this->db->join('user_group', 'user_group.user_id = users.id);
$this->db->join('groups', 'groups.id = user_group.group_id');
$q = $this->db->get();
Thanks
Leron

I think you forget add where clause. And there was single quote missing.
$this->db->select('name');
$this->db->from('users');
$this->db->join('user_group', 'user_group.user_id = users.id');
$this->db->join('groups', 'groups.id = user_group.group_id');
$this->db->where('user_group.group_id', 4);
$q = $this->db->get();

Related

How to do a SQL JOIN where multiple joined rows need to contain things

When someone on my site search for an image that has multiple tags I need to query and find all images that have the searched tags, but can't seem to figure out this query.
I have an Images table.
The Images table has a relation to Posts_Images.
Posts_Images would have a relation to Posts table.
Posts has a relation to Posts_Tags table.
Posts_Tags table will have the relations to Tags table.
The query I have so far:
SELECT "images".* FROM "images"
INNER JOIN "posts_images" ON posts_images.image_id = images.id
INNER JOIN "posts" ON posts.id = posts_images.post_id AND posts.state IS NULL
INNER JOIN "posts_tags" ON posts_tags.post_id = posts.id
INNER JOIN "tags" ON posts_tags.tag_id = tags.id
WHERE (("images"."order"=0) AND ("images"."has_processed"=TRUE)) AND (LOWER(tags.tag)='comic') AND ("tags"."tag" ILIKE '%Fallout%') ORDER BY "date_uploaded" DESC LIMIT 30
It gets no results, it is checking if the tags equals both values, but I want to see if any of the tags that were joined have all the values I need.
The desired result would be any Post that has a tag matching Comic and ILIKE '%Fallout%'
You seem to want something like this:
SELECT i.*
FROM images JOIN
posts_images pi
ON pi.image_id = i.id JOIN
posts p
ON p.id = pi.post_id AND p.state IS NULL JOIN
posts_tags pt
ON pt.post_id = p.id JOIN
tags t
ON pt.tag_id = t.id
WHERE i."order" = 0 AND
i.has_processed AND
(LOWER(t.tag) = 'comic') OR
(t.tag ILIKE '%Fallout%')
GROUP BY i.id
HAVING COUNT(DISTINCT tag) >= 2
ORDER BY date_uploaded DESC
LIMIT 30;
The logic is in the HAVING clause. I'm not 100% sure that this is exactly what you want for multiple matches.
In addition to gordon-linoff’s response - query can be described using ActiveQuery:
Images::find()
->alias('i')
->joinWith([
'postsImages pi',
'postsImages.posts p',
'postsImages.posts.tags t'
])
->where([
'p.state' => null,
'i.order' => 0,
'i.has_processed' => true,
])
->andWhere(
'or'
'LOWER(t.tag) = "comic"',
['like', 't.tag', 'Fallout']
])
->groupBy('id')
->having('COUNT(DISTINCT tag) >= 2')
->orderBy('date_uploaded DESC')
->limit(30)
->all()
$images = Images::find()
->innerJoin('posts_images', 'posts_images.image_id = images.id')
->innerJoin('posts', 'posts.id = posts_images.post_id AND posts.state IS NULL')
->where(['images.order' => 0, 'images.has_processed' => true]);
if (!is_null($query)) {
$tags = explode(',', $query);
$images = $images
->innerJoin('posts_tags', 'posts_tags.post_id = posts.id')
->innerJoin('tags', 'posts_tags.tag_id = tags.id');
$tagsQuery = ['OR'];
foreach ($tags as $tag) {
$tag = trim(htmlentities($tag));
if (strtolower($tag) == 'comic') {
$tagsQuery[] = ['tags.tag' => $tag];
} else {
$tagsQuery[] = [
'ILIKE',
'tags.tag', $tag
];
}
}
if (!empty($tagsQuery)) {
$images = $images->andWhere($tagsQuery)
->having('COUNT(DISTINCT tags.tag) >= ' . sizeof($tags));
}
}
$images = $images
->groupBy('images.id')
->orderBy(['date_uploaded' => SORT_DESC])
->offset($offset)
->limit($count);
return $images->all();

Query with select and count in laravel

I did this Query in SQL but I can't make it work in Eloquent.
Please help me.
SELECT
tags.desc,
COUNT(planificacion_info.id_area) as cantidad_intervenciones
FROM
tags
INNER JOIN planificacion_info ON planificacion_info.id_area = tags.id_tag
WHERE
tags.grupo = 'area' and tags.estado = true
GROUP BY
tags.desc
You can do it like this :
$result = \DB::table('tags')->selectRaw('tags.desc, COUNT(planificacion_info.id_area) as cantidad_intervenciones')
->join('planificacion_info', 'planificacion_info.id_area', '=', 'tags.id_tag')
->where('tags.grupo', 'area')
->whereRaw('tags.estado = true')
->groupBy('tags.desc')
->get();
which gives you this request :
SELECT
tags.desc,
COUNT(planificacion_info.id_area) AS cantidad_intervenciones
FROM
`tags`
INNER JOIN `planificacion_info` ON `planificacion_info`.`id_area` = `tags`.`id_tag`
WHERE
`tags`.`grupo` = 'area'
AND tags.estado = TRUE
GROUP BY
`tags`.`desc`
Would be something liek this
$tags= DB::table('tags')
->select('tags.desc',DB::raw("COUNT(planificacion_info.id_area) AS cantidad_intervenciones")
->innerJoin('planificacion_info','planificacion_info.id_area','=','tags.id_tag')
->where('tags.grupo','area')
->where('tags.estado',true)
->groupBy('tags.desc')
->get();

LEFT join AND command in yii2

I want to write a query in yii2
and i dont know how to write it
i tried few things from documentaion but its not working
here is my query
SELECT notification.*,event.title,user.firstname,user.lastname FROM notification
LEFT JOIN event ON event.id = notification.source_id
AND notification.activity_type = "checkin"
Where user.firstname in (select id from user where user_id=1)
LEFT JOIN user ON user.id = notification.source_id
AND notification.activity_type = "friend"
Where user.firstname in (select id from user where user_id=1)
and here is the query i write for now,i need to add AND function just like its in the query
$query ->select(['notification.*,event.title,user.firstname,user.lastname'])
->from('notification')
->leftJoin('event', 'event.id = notification.source_id')
->leftJoin('user', 'user.id = notification.source_id');
Have you tried the following:
$query ->select(['notification.*,event.title,user.firstname,user.lastname'])
->from('notification')
->leftJoin('event', 'event.id = notification.source_id AND notification.activity_type = "checkin" ')
->leftJoin('user', 'user.id = notification.source_id AND notification.activity_type = "friend"');

DRUPAL db_or adding AND between multiple variables

I have inherited an application that is using the drupal filtering system to find results. The user can select to search the 'campus_location' column but when they enter multiple variables, it adds an AND between the condition.
Here is the printed version of the query generated by drupal:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
**AND**( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
I need the last AND to be an OR so it looks like this:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
OR( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
Which produces the correct results.
Here is the code that I inherited where it looks over the words in the search box. I just can't seem to figure out where it is adding the variables where it is putting the AND.
$words = explode(",", $_SESSION['form_state']['values']['filter']);
foreach($words as $word)
{
$or = db_or();
foreach($cols as $col)
{
$table = 'c';
if(in_array($col, array('completed_date', 'score')))
$table = 'cl';
elseif(in_array($col, array('name', 'mail')))
$table = 'u';
elseif($col == 'date')
$table = 'r';
elseif(in_array($col, array('announce', 'num_success_stories', 'num_action_steps'))) //can't put these in WHERE clause. Need to go in HAVING.
continue;
echo $word;
$or = $or->condition($table . '.' . $col, champs_make_like_sql($word), 'LIKE');
}
$result = $query->condition($or);
}

Querying Wordpress thumbnails

I am trying to get the thumbnail meta data for the posts in my wordpress blog together with their category and some other data.
The thumbnail data is serialized and I will unserialize it later.
Here is the query I have:
SELECT wpostmeta.meta_value AS url,
wposts.post_content, wposts.post_title, wposts.post_status, wposts.post_name,
cat_terms.name AS category_name, cat_terms.term_id AS category_id,
ttable.meta_value AS thumb_data
FROM `wp_postmeta` AS wpostmeta,
`wp_posts` AS wposts
INNER JOIN wp_term_relationships AS cat_term_relationships ON (wposts.ID = cat_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS cat_term_taxonomy ON (cat_term_relationships.term_taxonomy_id = cat_term_taxonomy.term_taxonomy_id AND cat_term_taxonomy.taxonomy = 'category')
INNER JOIN wp_terms AS cat_terms ON (cat_term_taxonomy.term_id = cat_terms.term_id)
LEFT JOIN `wp_postmeta` AS ttable ON (wposts.ID = ttable.post_id AND ttable.meta_key = '_wp_attachment_metadata')
WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = 'url'
AND wposts.post_type = 'post'
Everything works except for the attachment part. 'thumb_data' is NULL.
Could you please help me fix this?
This query solved my problem:
$sql = "SELECT wposts.ID AS ID, thumbposts.ID AS thumbposts_ID,
postmeta.meta_value AS url,
wposts.post_content, wposts.post_title, wposts.post_status, wposts.post_name,
cat_terms.name AS category_name, cat_terms.term_id AS category_id,
thumb.meta_value AS thumb_data
FROM `wp_postmeta` AS postmeta,
`wp_posts` AS thumbposts,
`wp_postmeta` AS thumb,
`wp_posts` AS wposts
INNER JOIN wp_term_relationships AS cat_term_relationships ON (wposts.ID = cat_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS cat_term_taxonomy ON (cat_term_relationships.term_taxonomy_id = cat_term_taxonomy.term_taxonomy_id AND cat_term_taxonomy.taxonomy = 'category')
INNER JOIN wp_terms AS cat_terms ON (cat_term_taxonomy.term_id = cat_terms.term_id)
WHERE wposts.ID = postmeta.post_id
AND postmeta.meta_key = 'url'
AND thumbposts.post_parent = wposts.ID
AND thumbposts.post_type = 'attachment'
AND thumb.post_id = thumbposts.ID
AND thumb.meta_key = '_wp_attachment_metadata'
AND wposts.post_type = 'post'";
if($filter == 1){
$sql .= " AND cat_terms.term_id = '1'";
}
if($filter == 2){
$sql .= " AND cat_terms.term_id = '3'";
}
$sql .= " GROUP BY wposts.ID
ORDER BY wposts.post_date ASC";
Can you explain exactly what you are trying to achieve - there is no real need to go direct to the database in the vast number of situations.
For example you can use get_posts with 'post_type'=>'attachment' and 'post_mime_type'=>'image' to get image attachments and then output the metadata, and there are many functions inbuilt to deal with resizing, displaying and cropping the thumbnails, such as get_post_thumbnail() etc.