MySQL Join two different columns in the same table twice in CodeIgniter - php

I have announcements table, where I store announcements.catid (category id).
Categories table categories are used to be nested with the use of categories.pid.
What I am trying to do, is to get the categories nested one by one inside the multidimensional array.
Here is the image of how I want it to be inside highlighted part:
and here is the code:
public function get_mixed( $limit = NULL, $offset = NULL )
{
$this->db
->select('
announcements.id,
announcements.catid,
announcements.uid,
categories.title AS section,
categories.title AS category,
announcements.title,
announcements.text,
announcements.views,
announcements.created,
announcements.modified,
announcements.pubdate
')
->join('categories', 'announcements.catid = categories.id', 'left')
->join('categories as section', 'categories.pid = section.id', 'left')
->order_by('created DESC, '.$this->_order_by);
return $this->db->get( $this->_table_name, $limit, $offset )->result();
}
I tried first with by creating a section alias, but it gets me the same results.
Maybe there is a better approach ?

If you are aliasing one of the categories joins as section, then you would need to reference any fields you want from that categories table as section.[field] (for example, section.title)
Not knowing exactly what you want, my best guess at your revised query would be:
$this->db
->select('
announcements.id,
announcements.catid,
announcements.uid,
section.title AS section,
categories.title AS category,
announcements.title,
announcements.text,
announcements.views,
announcements.created,
announcements.modified,
announcements.pubdate
')
->join('categories', 'announcements.catid = categories.id', 'left')
->join('categories as section', 'categories.pid = section.id', 'left')
->order_by('created DESC, '.$this->_order_by);

Related

How to select everything in column with Doctrine and Symfony

I'm trying to build small query with QueryBuilder where category parameter that can be passed to query or not.
$category = 'Boots';
If not I'd like to select all categories.
I use "where" for this. In mySql you can use "WHERE column = column" and everything is selected. I tried this with the builder but it doesn't work:
$qb = $this->createQueryBuilder('p')
->select("p.id, p.price, stock.qty, p.images, category.name,
p.model, s.size AS size, c.name AS color,
b.name AS brand, category.name AS catName")
->innerJoin('p.stocks', 'stock')
->innerJoin('p.brand', 'b')
->innerJoin('stock.size','s')
->innerJoin('stock.color', 'c')
->innerJoin('p.category', 'category')
->where('category.name = :category')
->andWhere('s.size IN (:sizes)')
->andWhere('b.name IN (:brands)')
->andWhere('p.price > :priceFrom')
->andWhere('p.price < :priceTo')
->setParameter('category', 'category.name') /// ??? the problem is here
->setParameter('sizes', $sizes, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
->setParameter('brands', $brands, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
->setParameter('priceFrom', $priceFrom)
->setParameter('priceTo', $priceTo)
->groupBy('p.model')
->getQuery()
->getResult();
Check the lines:
->where('category.name = :category')
->setParameter('category', 'category.name') /// ??? the problem is here
When i try to set column to column it doesn't work. I tried also diferrent combinations like, but no results. Any advice? Thanks

multiple join in codeigniter not working as expected

there is 4 table
option_group(id, optionGroupName)
category_optiongroup(categoryId, optionGroupId, inOrder)
product_option(productId, optionGroupId, optionId)
option(id, optionValue)
some products has not inserted its optionValue yet in the product_option table but I want to get theme all Whether is inserted or not.
for example size of specific product has not set yet.
here is my model but it only return all optionValue that is set.
is it some how possible to do it with IFNULL()? if not doesn't matter
IFNULL(optionValue, 'Not Set')
$this->db->select('option.optionValue')
->from('category_optiongroup')
->where('categoryId', $data['categoryId'])
->join('product_option', 'product_option.productId='.$productId.
' AND product_option.optionGroupId=category_optiongroup.optionGroupId', 'left')
->join('option', 'option.id=product_option.optionId')
->order_by('category_optiongroup.inOrder', 'ASC');
$query = $this->db->get();
return $query;
two tips:
1st: both option and product_option tables needs left join
2nd: certainly IFNULL() needs an alias to call
$this->db->select('IFNULL(`option`.`optionValue`, "Not Set") AS optionValue', FALSE)
->from('category_optiongroup')
->join('product_option', 'product_option.productId='.$productId
.' AND product_option.optionGroupId=category_optiongroup.optionGroupId', 'left')
->join('option', 'option.id=product_option.optionId', 'left')
->where('categoryId', $data['categoryId'])
->order_by('category_optiongroup.inOrder', 'ASC');
$query = $this->db->get();
return $query;
You can use IFNULL like this
$this->db->select('IFNULL(`option`.optionValue,"Not Set")',false)
->from('category_optiongroup')
->join('product_option', 'product_option.productId='.$productId.
' AND product_option.optionGroupId = category_optiongroup.optionGroupId', 'left')
->join('`option`', '`option`.id=product_option.optionId')
->where('categoryId', $data['categoryId'])
->order_by('category_optiongroup.inOrder', 'ASC');
$query = $this->db->get();
return $query;

codeigniter join from 2nd table id with 3rd table id multi rows

I want to join multiple tables, as in my picture:
Here is my code:
$this->db->select('
pt2.turl as `p_img`,
p.title as `p_title`,
p.text as `p_text`,
p.create as `p_date`,
pt3.turl as `c_img`,
u.name as `c_name`,
c.text as `c_text`,
c.create as `c_date`
');
$this->db->from('posts as p, users as u, photos as pt2, photos as pt3');
$this->db->join('comments as c', 'p.id=c.pid AND u.id=c.uid');
$this->db->join('posts as p2', 'p2.pid=pt2.id', 'rihgt');
$this->db->join('users as u2', 'u2.photoid=pt3.id', 'right');
$this->db->order_by('c.id', 'DESC');
$this->db->limit('7');
$qry = $this->db->get();
return $qry->result();
If I understand you correctly, this is kind of what you're looking for. I haven't tried it out so it may not be exact, but you shouldn't need to make 2 table associations (pt2 and pt3) for the same table in the join. Just Include them in the select and join on the unique ID's
The "Left" is a join that is centered around you're left table so everything hangs off of that. Since you are joining the users table before the photo table, you should be able to join on its columns.
Hope this helps. Let me know if I missed something. :)
$select = array(
pt2.turl as `p_img`,
p.title as `p_title`,
p.text as `p_text`,
p.create as `p_date`,
pt2.turl as `c_img`,
u.name as `c_name`,
c.text as `c_text`,
c.create as `c_date`
);
//Set tables to variables. Just makes it easier for me
$postsTable = "posts as p"; //This will be your left table.
$userTable = "Users as u";
$commentsTable = "comments as c";
$photosTable = "photos as pt2";
$this
->db
->select($select)
->from($postsTable)
->join($userTable, "p.uid = u.id", "left")
->join($commentsTable, "p.cid = c.id", "left")
->join($photosTable, "u.photoid = pt2.id", "left")
->get();
I solved this problem myself
It would be like this:
$select= array (
//'*',
'pt.turl p_img',
'p.title p_title',
'p.text p_text',
'p.create p_date',
'pt2.turl c_img',
'c.text c_text',
'u.name c_name',
'c.create c_date'
);
$from = array (
'posts p'
);
$qry = $this
->db
->select($select)
->from($from)
->join('comments c', 'c.pid=p.id')
->join('photos pt', 'pt.id=p.pid')
->join('users u', 'u.id=c.uid')
->join('photos pt2', 'u.photoid=pt2.id')
->order_by('c.create', 'DESC')
->limit('7')
->get();
return $qry->result();

Join Eloquent Model with condition

I have the three Models Post, Page and Category.
Each Page is assigned to one Category and each Post is assigned to one Page.
I have already defined the relationships in the models. What I want to do now is to use Eloquent ORM to get all Post-objects that are from a Page with a certain Category. So basically, in SQL I would need to do it like this
select p.* from posts p INNER JOIN pages pa ON pa.id = p.page_id where p.created_time > '2015-08-18 00:00:00' and pa.categories_id = 1 and p.isVisible = 1 order by p.total_count desc limit 100
I'm now somehow trying to do the same with Eloquent, but I'm stuck. My current code looks like this
// Getting all the top posts from facebook for today.
/** #var Builder $topPosts */
$topPosts = Post::where('created_time', '>', Carbon::today()->toDateTimeString());
if ($type !== null) {
$topPosts = $topPosts->where('type', $type);
}
return $topPosts->orderBy('total_count', 'desc')
->visible()
->take($limit)
->get();
Now, I wanted to add the category, but I don't know how to do it. I tried these steps here:
$topPosts = $topPosts->with(['page' => function($query) use($categoryId){
$query->where('page_categories_id', $categoryId);
}]);
and this one
$topPosts = $topPosts->with('page')->where('page_categories_id', $categoryId);
but none of them worked. How would I achieve that? I always get the error message
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'categories_id' in 'where clause' (SQL: select * from posts where created_time > 2015-08-18 00:00:00 and categories_id = 1 and isVisible = 1 order by total_count desc limit 100)
It looks like you need to use whereHas() in place your with() statement there (http://laravel.com/docs/4.2/eloquent#querying-relations)
This should work, and is basically just querying Posts with associated Pages with the particular category_id. I haven't included your ordering and things..
$posts = Post::where('created_time', '>', Carbon::today()) // Eloquent shouldn't actually need the toDateTimeString()
->with('page') // leave this in to eager load the page
->whereHas('page', function($query) use ($categoryId) {
$query->where('page_categories_id', $categoryId);
})
->get();

Laravel 4 select column from another table in subquery

I am attempting to do the equivalent of this:
select p.id, p.title, b.brand,
(select big from images where images.product_id = p.id order by id asc limit 1) as image
from products p
inner join brands b on b.id = p.brand_id
Here is where I am at now, but it of course doesn't work:
public function getProducts($brand)
{
// the fields we want back
$fields = array('p.id', 'p.title', 'p.msrp', 'b.brand', 'p.image');
// if logged in add more fields
if(Auth::check())
{
array_push($fields, 'p.price_dealer');
}
$products = DB::table('products as p')
->join('brands as b', 'b.id', '=', 'p.brand_id')
->select(DB::raw('(select big from images i order by id asc limit 1) AS image'), 'i.id', '=', 'p.id')
->where('b.active', '=', 1)
->where('p.display', '=', 1)
->where('b.brand', '=', $brand)
->select($fields)
->get();
return Response::json(array('products' => $products));
}
I don't really see anything in the docs on how to do this, and I can't seem to piece it together from other posts.
In "regular" SQL, the subquery is treated AS a column, but I am not sure how to string that together here. Thanks for any help on this.
I strongly recommend you to use Eloquent, instead of pure SQL. It's one of the most beautful things in Laravel. Two models and relations and it's done! If you need to use pure SQL like that, put it all in DB::raw. It's easier, simpler and (ironically) less messy!
With the models, you could use relations between the two tables (represented by the models itself) and say (so far I understood) that Brands belongs to Products, and Images belongs to Product. Take a look at Eloquent's documentation on Laravel. Probably will be more clearly.
Once the relations are done, you can only say that you wanna get
$product = Product::where(function ($query) use ($brand){
$brand_id = Brand::where('brand', '=', $brand)->first()->id;
$query->where('brand_id', '=', $brand_id);
})
->image()
->get();
That and a better look at Eloquent's documentation should help you to do the job.
P.S.: I didn't test the code before send it and wrote it by head, but i think it works.

Categories