I have two input fields. Both leading to an array array of colors that will be matched on the database. The arrays can look like this
Array ( [0] => red [1] => blue [2] => green )
One input is used for searching a table called ´image_topcolor´ and the other input is searching another table, ´image_bottomcolor´.
I'm trying to come up with a structure to search for images with these two inputs based on color selection.
I want the user to be able to select several colors and then return all images which has the selected color in the database. The search works fine when using only one input field with the following code:
$this->db->select('*');
$this->db->from('image');
if(!empty($top_colors[0]) && empty($bottom_colors[0])) {
$this->db->join('image_topcolor', 'image_topcolor.image_id = image.id' ,'inner');
$this->db->join('color', 'color.id = image_topcolor.color_id', 'inner');
}
if(!empty($bottom_colors[0]) && empty($top_colors[0])) {
$this->db->join('image_bottomcolor', 'image_bottomcolor.image_id = image.id' ,'inner');
$this->db->join('color', 'color.id = image_bottomcolor.color_id', 'inner');
}
if(!empty($bottom_colors[0])) {
$this->db->where_in('color', $bottom_colors);
}
if(!empty($top_colors[0])) {
$this->db->where_in('color', $top_colors);
}
This returns images to the user even if the user has selected a color that doesn't have an id matched with an image yet, which is perfect!
I want this to work the same way when using both input fields to find all images that matches the colors from the inputs.
I want to use something similiar to:
$this->db->select('*');
$this->db->from('image');
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$this->db->join('image_topcolor', 'image_topcolor.image_id = image.id' ,'left');
$this->db->join('image_bottomcolor', 'image_bottomcolor.image_id = image.id' ,'left');
$this->db->join('color as a', 'image_topcolor.color_id = a.id','left');
$this->db->join('color as b', 'image_bottomcolor.color_id = b.id','left');
}
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$this->db->where_in('a', $top_colors);
$this->db->where_in('b', $bottom_colors);
}
This returns with the error
"Column 'color' in where clause is ambiguous"
"SELECT * FROM image
LEFT JOIN image_topcolor
ON image_topcolor
. image_id
= image
. id
LEFT JOIN image_bottomcolor
ON image_bottomcolor
. image_id
= image
. id
LEFT JOIN color
as a
ON image_topcolor
. color_id
= a
. id
LEFT JOIN color
as b
ON image_bottomcolor
. color_id
= b
. id
WHERE color
IN('blue') AND color
IN('red') AND a
. color
IN('red') AND b
. color
IN('blue')"
I'm not sure how I can use both arrays to find all images that matches any of the selected colors.
My tables looks like this:
image
id | color | info
---|-------|------
1 | blue | foo
2 | red | bar
color
id | color |
---|-------|
1 | red |
2 | blue |
3 | green |
image_topcolor
image_id | color_id |
---------|----------|
1 | 1 |
1 | 2 |
image_bottomcolor
image_id | color_id |
---------|----------|
2 | 1 |
2 | 3 |
Sorry for the long post. Question recap: How can I get the results of all images with matching colors when using both inputs? Just like I get when using only one input.
Thanks!
Update
This query is now not generating any errors.
But I'm still not getting the results if the user selects a color that doesn't exist. I only get the result if the image has the same selected color in both tables. Example: An image has red, blue top_color and blue, green bottom color. I cannot get this result by searching for red top and green bottom. However if I search for blue top and blue bottom, I get the result. I guess this has do with the joins?
$this->db->select('*');
$this->db->from('image');
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$this->db->join('image_topcolor', 'image_topcolor.image_id = image.id' ,'left');
$this->db->join('image_bottomcolor', 'image_bottomcolor.image_id = image.id' ,'left');
$this->db->join('color as a', 'image_topcolor.color_id = a.id','left');
$this->db->join('color as b', 'image_bottomcolor.color_id = b.id','left');
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$result = array_merge($top_colors, $bottom_colors);
$this->db->where_in('a.color', $top_colors);
$this->db->where_in('b.color', $bottom_colors);
}
Since you joined the same table twice, the two tables have exactly the same set of fields. Therefore, every time you reference a field from one of these two tables, you need to prefix the field name with the table alias, such as a.color
.
I believe in codeigniter you can achieve this in the following way:
...
$this->db->where_in('a.color', $top_colors);
$this->db->where_in('b.color', $bottom_colors);
...
You did not use the where_in syntax correct. You need to use the name of the field as the first argument of the function, not the table name (alias).
Try this:
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$this->db->where_in('a.color', $top_colors);
$this->db->where_in('b.color', $bottom_colors);
}
UPDATE: To get your desired result you should also use or_where_in, like this:
if(!empty($top_colors[0]) && !empty($bottom_colors[0])) {
$this->db->where_in('a.color', $top_colors);
$this->db->or_where_in('b.color', $bottom_colors);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.