Multiple rows in a select with OR - mysql

I have this query and when I add a OR, return multiples rows, how I can fix this? I need another left join or Right join?
SELECT `images`.`id` as `id_image`, `images_lang`.`title` as `title`, `images_lang`.`autor` as `author`, `media_lang`.`file`, `category_lang`.`title` as `category`
FROM `images`
JOIN `images_lang` ON `images_lang`.`id_images` = `images`.`id`
JOIN `category_lang` ON `images`.`id_category` = `category_lang`.`id_category`
JOIN `media` ON `images`.`id` = `media`.`id_item`
JOIN `media_lang` ON `media`.`id` = `media_lang`.`id_media`
JOIN `relation` ON `relation`.`from_id` = `images`.`id`
JOIN `tag` ON `tag`.`id` = `relation`.`to_id`
JOIN `tag_lang` ON `tag`.`id` = `tag_lang`.`id_lang`
WHERE `media`.`table` = 'images'
AND `media_lang`.`id_lang` = '1'
AND `images_lang`.`id_lang` = '1'
AND `category_lang`.`id_lang` = '1'
AND `images`.`active` = 1
AND `relation`.`type` = 2
AND `tag_lang`.`id_lang` = '1'
AND `tag_lang`.`slug` = 'pa-am-oli'
OR `tag_lang`.`slug` = 'playa'
LIMIT 9
and the code in codeigniter, but I donĀ“t how add the or after the and ($keywords is an array for filter the elements)
$this->db->select('images.id as id_image, images_lang.title as title, images_lang.autor as author, media_lang.file, category_lang.title as category');
$this->db->from($this->table);
$this->db->join($this->table.'_lang',$this->table.'_lang.id_images = '.$this->table.'.id');
$this->db->join('category_lang',$this->table.'.id_category = category_lang.id_category');
$this->db->join('media',$this->table.'.id = media.id_item');
$this->db->join('media_lang','media.id = media_lang.id_media');
$this->db->where('media.table',$this->table);
$this->db->where('media_lang.id_lang',$id_lang);
$this->db->where($this->table.'_lang.id_lang', $id_lang);
$this->db->where('category_lang.id_lang', $id_lang);
$this->db->where('images.active', 1);
if($category){
$this->db->where('category_lang.title', $category);
}
if($keywords){
$this->db->join('relation', 'relation.from_id = '.$this->table.'.id');
$this->db->join('tag', 'tag.id = relation.to_id');
$this->db->join('tag_lang', 'tag.id = tag_lang.id_lang');
$this->db->where('relation.type', _IMAGES_2_TAGS_);
$this->db->where('tag_lang.id_lang', $id_lang);
foreach($keywords as $tag){
$this->db->or_where('tag_lang.slug', $tag);
}
}
if($from || $limit)
{
$this->db->limit((int)$limit, (int)$from);
}
$query = $this->db->get();
return $query->result_array();

I solved the query adding this (and a Select Distinct)
AND (`tag_lang`.`slug` = 'playa'
OR `tag_lang`.`slug` = 'pa-am-oli')
How I can add this in codeigniter?

I don't get what you need exactly, but if you want have just one line as a return by filtering using OR
In your case you should do the following:
WHERE (`media`.`table` = 'images' OR `tag_lang`.`slug` = 'playa')
AND (`media_lang`.`id_lang` = '1' OR `tag_lang`.`slug` = 'playa')
and so on, I hope that helps you and good luck!

Astute use of parentheses would solve your problem, but this is easier to read...
SELECT i.id id_image
, il.title
, il.autor author
, ml.file
, cl.title category
FROM images i
JOIN images_lang il
ON il.id_images = i.id
JOIN category_lang cl
ON cl.id_category = i.id_category
JOIN media m
ON m.id_item = i.id
JOIN media_lang ml
ON ml.id_media = m.id
JOIN relation r
ON r.from_id = i.id
JOIN tag t
ON t.id = r.to_id
JOIN tag_lang tl
ON tl.id_lang = t.id
WHERE m.table = 'images'
AND ml.id_lang = 1
AND il.id_lang = 1
AND cl.id_lang = 1
AND i.active = 1
AND r.type = 2
AND tl.id_lang = 1
AND tl.slug IN('pa-am-oli','playa')
LIMIT 9
... however, note that LIMIT without ORDER BY is fairly meaningless.

Related

Update sentence with subquery on MySQL

I have the following sentence, that returns the error
Unknown column targets.ID_TARGET in where clause
and I can't find any solution. Could you guys help?
The proposal is update 'sw_automatic' for each row with the value that th subquery provides (0 or 1)
update bt_pry_targets targets
set targets.sw_automatic = (
(
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK) )
where targets.sw_automatic is null;
In you subquery the column targets.ID_TARGET in not visible
so you could try using you subquery as a join table for updated
update bt_pry_targets targets
inner join (
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK
) t on t.PryTarget = targets.ID_TARGET
AND targets.sw_automatic is null
set targets.sw_automatic = t.TYPE_TASK

alternative to nested select mysql

I am running a query at the moment, and I believe that that nest selected is creating a bottle neck, is there an alternative option that I could use?
This is my query,
SELECT post_id,
post_order,
post_parent,
post_recycle,
post_status,
post_ps_id,
post_v_id,
post_src,
post_sn_id,
post_qpc_id,
post_date_posted,
post_scheduled_local_datetime,
post_recycle_repeats,
post_recycle_expiry_date,
post_text,
post_v_title,
link_url,
link_preview_removed,
link_name,
link_description,
link_caption,
link_url_is_bitlink,
link_bitly_destination_url,
link_expanded_url,
link_initial_is_bitlink,
link_destination,
link_picture,
link_picture_size,
link_facebook_image,
link_facebook_title,
link_facebook_description,
link_facebook_caption,
link_twitter_card,
link_twitter_image,
link_twitter_title,
link_twitter_description,
pause_m_id,
qpca_evergreen_too_frequent,
sn_network,
qpc_name,
qpc_colour,
ps_m_id,
ps_filename,
ps_via,
ps_s3,
ps_width,
ps_height,
ps_gif,
video.*,
(
SELECT COUNT(*) FROM post post_inner
WHERE (post_inner.post_parent = post.post_parent)
AND post_inner.post_status = 'published'
)
AS total_repeats
FROM post
JOIN social_network ON sn_id = post_sn_id AND sn_status = 'active'
JOIN queue_post_cat ON qpc_id = post_qpc_id
LEFT JOIN queue_post_cat_account ON qpca_qpc_id = post_qpc_id AND qpca_sn_id = post_sn_id
LEFT JOIN link ON link_id = post_link_id
LEFT JOIN pause ON pause_m_id = qpc_m_id AND pause_qpc_id = post_qpc_id AND pause_sn_id = post_sn_id
LEFT JOIN photo_status ON ps_id = post_ps_id
LEFT JOIN video ON post_v_id = v_id AND v_transcoded = 1 LEFT JOIN facebook ON fb_db_id = sn_account_id AND sn_network = 'facebook'
WHERE post_status != 'now'
AND post_m_id = 1
AND qpca_sn_id IS NOT NULL
AND qpca_qpc_id IS NOT NULL
AND post_status = 'queue' AND (sn_network = 'facebook'
OR sn_network = 'instagram' OR sn_network = 'twitter')
AND qpc_m_id = 1 AND (fb_type IS NULL OR fb_type != 'profile') ORDER BY post_order ASC
I believe the bottle neck is happening here,
SELECT COUNT(*) FROM post post_inner
WHERE (post_inner.post_parent = post.post_parent)
AND post_inner.post_status = 'published'
which is select within the main select, is there something I could do that would run faster?
You can try with subquery:
select * from
(
SELECT post_id,
post_order,
post_parent,
post_recycle,
post_status,
post_ps_id,
post_v_id,
post_src,
post_sn_id,
post_qpc_id,
post_date_posted,
post_scheduled_local_datetime,
post_recycle_repeats,
post_recycle_expiry_date,
post_text,
post_v_title,
link_url,
link_preview_removed,
link_name,
link_description,
link_caption,
link_url_is_bitlink,
link_bitly_destination_url,
link_expanded_url,
link_initial_is_bitlink,
link_destination,
link_picture,
link_picture_size,
link_facebook_image,
link_facebook_title,
link_facebook_description,
link_facebook_caption,
link_twitter_card,
link_twitter_image,
link_twitter_title,
link_twitter_description,
pause_m_id,
qpca_evergreen_too_frequent,
sn_network,
qpc_name,
qpc_colour,
ps_m_id,
ps_filename,
ps_via,
ps_s3,
ps_width,
ps_height,
ps_gif,
video.*,
FROM post
JOIN social_network ON sn_id = post_sn_id AND sn_status = 'active'
JOIN queue_post_cat ON qpc_id = post_qpc_id
LEFT JOIN queue_post_cat_account ON qpca_qpc_id = post_qpc_id AND qpca_sn_id = post_sn_id
LEFT JOIN link ON link_id = post_link_id
LEFT JOIN pause ON pause_m_id = qpc_m_id AND pause_qpc_id = post_qpc_id AND pause_sn_id = post_sn_id
LEFT JOIN photo_status ON ps_id = post_ps_id
LEFT JOIN video ON post_v_id = v_id AND v_transcoded = 1 LEFT JOIN facebook ON fb_db_id = sn_account_id AND sn_network = 'facebook'
WHERE post_status != 'now'
AND post_m_id = 1
AND qpca_sn_id IS NOT NULL
AND qpca_qpc_id IS NOT NULL
AND post_status = 'queue' AND (sn_network = 'facebook'
OR sn_network = 'instagram' OR sn_network = 'twitter')
AND qpc_m_id = 1 AND (fb_type IS NULL OR fb_type != 'profile')) A
inner join
(
SELECT post_parent ,COUNT(*) FROM post where post_status = 'published' group by post_parent
) B on A.post_parent = B.post_parent
ORDER BY post_order ASC

SQL orderby select

i have SQL query. I would like to orderby this by parent category. But i return only default category. I would like to know if i can
ORDER BY SELECT id_parent FROM cats WHERE id_category = id_default_category
Here is my query :
SELECT cp.`id_product_attribute`,
cp.`id_product`, cp.`quantity` AS cart_quantity,
cp.id_shop, pl.`name`,
p.`is_virtual`,
pl.`description_short`,
pl.`available_now`,
pl.`available_later`,
product_shop.`id_category_default`,
p.`id_supplier`,
p.`id_manufacturer`,
product_shop.`on_sale`,
product_shop.`ecotax`,
product_shop.`additional_shipping_cost`,
product_shop.`available_for_order`,
product_shop.`price`,
product_shop.`active`,
product_shop.`unity`,
product_shop.`unit_price_ratio`,
stock.`quantity` AS quantity_available,
p.`width`,
p.`height`,
p.`depth`,
stock.`out_of_stock`,
p.`weight`,
p.`date_add`,
p.`date_upd`,
IFNULL(stock.quantity, 0) as quantity,
pl.`link_rewrite`,
cl.`link_rewrite` AS category,
CONCAT(LPAD(cp.`id_product`, 10, 0),
LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0),
IFNULL(cp.`id_address_delivery`, 0)) AS unique_id,
cp.id_address_delivery,
product_shop.advanced_stock_management,
ps.product_supplier_reference supplier_reference
FROM `ps_cart_product` cp
LEFT JOIN `ps_product` `p` ON p.`id_product` = cp.`id_product`
INNER JOIN `ps_product_shop` product_shop ON (product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)
LEFT JOIN `ps_product_lang` `pl` ON p.`id_product` = pl.`id_product`
AND pl.`id_lang` = 1 AND pl.id_shop = cp.id_shop
LEFT JOIN `ps_category_lang` `cl` ON product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = 1 AND cl.id_shop = cp.id_shop
LEFT JOIN `ps_product_supplier` `ps` ON ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`
LEFT JOIN ps_sanishopstock_available stock
ON (stock.id_product = cp.id_product AND stock.id_product_attribute = IFNULL(`cp`.id_product_attribute, 0) AND stock.id_shop = 1 AND stock.id_shop_group = 0 )
WHERE cp.`id_cart` = 757
ORDER BY product_shop.id_category_default ASC, cp.id_product, cp.date_add ASC;
There is a lot of different table, i'm lost !
If someone have any idea.
Thanks a lot !
Yes. But like any subquery, you need parentheses:
ORDER BY (SELECT c.id_parent FROM cats c WHERE id_category = id_default_category)
I would also qualify the column names in the WHERE, but I don't know where they come from.

Like best performance in nested query

I have a principal requet with 2 requets in. I have a problem in my second nested query, I have a condition on id and if I made my request id = 10 takes a long time to execute, so if I replace it by id LIKE 10 my request execute in one second.
Here the request:
SELECT SQL_NO_CACHE contact_groupe.id_contact_groupe
FROM toto.contact_groupe
LEFT JOIN toto.`contact` AS `contact`
ON ((toto.contact_groupe.id_contact_groupe = toto.contact.id_contact_groupe))
LEFT JOIN toto.`project` AS `project`
ON ((toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe)
AND ( toto.project.id_project
IN (
SELECT MAX(toto.project.id_project)
FROM toto.project
WHERE ( toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe )
) ))
LEFT JOIN toto.`phase` AS `phase`
ON ((project.id_phase = toto.phase.id_phase))
LEFT JOIN sql_base.`user` AS `user_suivi`
ON ((toto.contact_groupe.id_user_suivi = user_suivi.id_user))
WHERE ( en_attente = '0' AND contact_groupe.id_contact_groupe
IN (
SELECT DISTINCT(contact_groupe.id_contact_groupe)
FROM toto.contact_groupe
LEFT JOIN toto.`contact` AS `contact`
ON ((toto.contact_groupe.id_contact_groupe = toto.contact.id_contact_groupe)
LEFT JOIN toto.`source_contact_groupe` AS `source_contact_groupe`
ON ((toto.contact_groupe.id_contact_groupe = toto.source_contact_groupe.id_contact_groupe))
LEFT JOIN toto.`project` AS `project`
ON ((toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe))
LEFT JOIN toto.`remarque` AS `remarque`
ON ((toto.contact_groupe.id_contact_groupe = toto.remarque.id_contact_groupe))
LEFT JOIN toto.`project_type_construction_options` AS `project_type_construction_options`
ON ((project.id_project = toto.project_type_construction_options.id_project))
LEFT JOIN toto.`project_concurrent` AS `project_concurrent`
ON ((project.id_project = toto.project_concurrent.id_project))
LEFT JOIN toto.`telephone` AS `telephone`
ON ((contact.id_contact = toto.telephone.id_contact))
WHERE ( en_attente = '0' AND ( toto.project.id_project = '10' ) AND toto.contact_groupe.id_entreprise = '2' )
)
AND toto.contact_groupe.id_entreprise = '2' )
ORDER BY toto.contact_groupe.id_contact_groupe ASC
the line is the following problem toto.project.id_project = '10' and I don't understand why the time to execute request is so different between = and LIKE
Let's start with your subquery. Those 17 lines that you've written are functionally identical to this, so why not use this instead?
SELECT DISTINCT g.id_contact_groupe
FROM contact_groupe g
JOIN project p
ON p.id_contact_groupe = g.id_contact_groupe
WHERE g.en_attente = 0
AND p.id_project = 10
AND g.id_entreprise = 2

mysql complex where query

I'm trying to solve this problem for past few days any help would be appreciated.
I have a Return item which have term1 in taxonomy1 AND term2 in taksonomy2.
This is my query:
SELECT items.*
FROM (`items`)
LEFT JOIN `rel_taxonomy` ON `rel_taxonomy`.`item_id` = `items`.`id`
LEFT JOIN `terms_taxonomy` ON `terms_taxonomy`.`terms_taxonomy_id` = `rel_taxonomy`.`terms_taxonomy_id`
LEFT JOIN `terms` ON `term`.`id` = `terms_taxonomy`.`term_id`
WHERE (items.org = '2') AND ( ((terms_taxonomy.taxonomy = '1') AND (term.pojam LIKE '%term1%')) AND ((terms_taxonomy.taxonomy = '2') AND (term.pojam LIKE '%term2%')))
GROUP BY `items`.`id`
If I replace the line:
WHERE (items.org = '2') AND ( ((terms_taxonomy.taxonomy = '1') AND (term.pojam LIKE '%term1%')) AND ((terms_taxonomy.taxonomy = '2') AND (term.pojam LIKE '%term2%')))
with the following (replacing an AND with an OR):
WHERE (items.org = '2') AND ( ((terms_taxonomy.taxonomy = '1') AND (term.pojam LIKE '%term1%')) OR((terms_taxonomy.taxonomy = '2') AND (term.pojam LIKE '%term2%')))
everything works fine. But I still need AND.
Table scheme
items
id | title | org
rel_taxonomy
item_id | terms_taxonomy_id
terms_taxonomy
terms_taxonomy_id | terms_id | taxsonomy
terms
id | term
so I'm trying to get item which have term1 in taxonomy1 AND term2 in taksonomy2.
Use OR and add a HAVING clause
SELECT i.id
FROM items i
LEFT JOIN rel_taxonomy rt ON rt.item_id = i.id
LEFT JOIN terms_taxonomy tt ON tt.terms_taxonomy_id = rt.terms_taxonomy_id
LEFT JOIN terms t ON t.id = tt.term_id
WHERE i.org = '2'
AND
(
(tt.taxonomy = '1' AND t.pojam LIKE '%term1%')
OR (tt.taxonomy = '2' AND t.pojam LIKE '%term2%')
)
GROUP BY i.id
having count(distinct tt.taxonomy) = 2