Joining two tables with a LIKE statement - mysql

I am trying to join my tables with a LIKE STATEMENT and my current query is this :
SELECT
COUNT(comment_id) AS nb,
produit.nom
FROM
comments
INNER JOIN produit ON comments.comment_location like (select '%'+produit.id+'%')
GROUP BY
comment_location
and the SQL FOR THE TABLES is this :
table comments:
CREATE TABLE `comments` (
`comment_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`comment_date` datetime NOT NULL,
`comment_content` varchar(255) NOT NULL,
`comment_location` varchar(255) NOT NULL,
PRIMARY KEY (`comment_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8
table produit :
CREATE TABLE `produit` (
`id` int(11) NOT NULL,
`nom` varchar(25) NOT NULL,
`description` varchar(200) NOT NULL,
`categorie` varchar(25) NOT NULL,
`image` varchar(200) NOT NULL,
`prix` float NOT NULL,
`quantite` int(11) NOT NULL,
`prix_initiale` float NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_CATEGORIE` (`categorie`),
CONSTRAINT `FK_CATEGORIE` FOREIGN KEY (`categorie`) REFERENCES `categorie` (`nom`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
my query does execute but doesn't return the table i was looking for
but if i try replacing produit.id in (select '%'+produit.id+'%') with a constant the table shows the corresponding rows .
What am i doing wrong

You need to modify query as below. You dont need SELECT again in the LIKE clause.
SELECT
COUNT(comment_id) AS nb,
produit.nom
FROM
comments
INNER JOIN produit ON comments.comment_location like CONCAT('%',produit.id,'%')
GROUP BY
comment_location

SELECT COUNT(comment_id) AS nb, produit.nom AS nom FROM comments INNER JOIN produit ON comments.comment_location LIKE CONCAT('%', produit.id, '%')
GROUP BY comment_location
by #Phil

Related

How to use JOIN in advance MySQL query

So I have been struggling with this question for a while, and trying to figure out the best way to use JOIN to get the answer of finding the "CertCount" per planet. I know that it wants to have it GROUP BY planets, but I have no clue where planets comes from. Here is the question and code below:
Find the number of certifications held by people grouped by planet. This should have two columns the first, "name" will be the names of planets that have at least one certification. The second column should be "CertCount" and will be the number of certifications held by people from that planet for example if Lee is certified in "Viper" and "Mechanic" and Kara is certified in "Viper" and they are both from Caprica, then the "CertCount" for caprica should be 3:
CREATE TABLE `bsg_cert` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
CREATE TABLE `bsg_cert_people` (
`cid` int(11) NOT NULL DEFAULT '0',
`pid` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`cid`,`pid`),
KEY `pid` (`pid`),
CONSTRAINT `bsg_cert_people_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `bsg_cert` (`id`),
CONSTRAINT `bsg_cert_people_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `bsg_people` (`id`)
) ENGINE=InnoDB
CREATE TABLE `bsg_people` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fname` varchar(255) NOT NULL,
`lname` varchar(255) DEFAULT NULL,
`homeworld` int(11) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `homeworld` (`homeworld`),
CONSTRAINT `bsg_people_ibfk_1` FOREIGN KEY (`homeworld`) REFERENCES `bsg_planets` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB
CREATE TABLE `bsg_planets` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`population` bigint(20) DEFAULT NULL,
`language` varchar(255) DEFAULT NULL,
`capital` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB
So for the moment: I have the following:
SELECT bsg_planets.name ,
COUNT(*) AS CertCount
FROM bsg_cert_people people_cert
I know that I am missing some code, but I'm not sure where to go from here, and could use a little nudge in the right direction.
You need to join the table according to their primary and foreign key and then do the GROUP BY
SELECT ps.id,
ps.name ,
COUNT(distinct *) AS CertCount
FROM bsg_cert_people cp
JOIN bsg_people pe ON cp.pid = pe.id
JOIN bsg_planets ps ON pe.homeworld = ps.id
GROUP BY ps.id, ps.name
All you need is to do inner join among all 3 tables based on common ids of tables and then group by with Planet id.
Following query should work:
SELECT ps.name ,
count(cert.cid) AS CertCount
FROM bsg_cert_people cert
JOIN bsg_people people ON cert.pid = people.id
JOIN bsg_planets planet ON people.homeworld = planet.id
GROUP BY plsnet.id
having count(distinct *) > 0;
Hope it helps!

MySQL JOIN Posts - Tags is taking too long

I'm facing some performance issues on MySQL JOIN statement. It's basically a posts-tags relationship with many rows: about 100000 posts and 20000 tags.
Unfortunately the query takes too long so that's what I'm asking for your help.
In a very basic query I need to get specific posts columns plus concatenated tags for each post. In fact the real query is more complex but I could start from here.
This is my query:
SELECT
SQL_CALC_FOUND_ROWS null as rows,
posts.id,
posts.title
GROUP_CONCAT(tags.desc SEPARATOR ", ") as ptags
FROM posts
JOIN posts_tags ON posts_tags.id_post = posts.id
JOIN tags ON tags.id = posts_tags.id_tag
GROUP BY posts.id
ORDER BY posts.id DESC
LIMIT 0,20
These are my keys definition
--- POSTS Table ----
PRIMARY KEY (`id`)
--- POSTS_TAGS Table ----
PRIMARY KEY (`id`),
KEY `id_post` (`id_post`),
KEY `id_tag` (`id_tag`)
--- TAGS Table ----
PRIMARY KEY (`id`)
This is my very first post, so I'm sorry if I've missed something. Any help will be appreciated.
**** EDIT ****
Added real Tables and Queries. Note that Posts is now named Noticias and Posts_tags is now named Tags_Noticias . Added MySQL Explain from PHPMyAdmin and JetProfiler.
CREATE TABLE IF NOT EXISTS `noticias` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`volanta` varchar(150) DEFAULT NULL,
`titulo` varchar(250) NOT NULL,
`texto` text NOT NULL,
`fecha` datetime NOT NULL,
`fecha_modificado` datetime NOT NULL,
`id_autor` int(2) NOT NULL,
`id_seccion` int(2) NOT NULL,
`id_posicion` int(1) NOT NULL,
`publicado` int(1) NOT NULL DEFAULT '1',
`clave_primaria` varchar(30) DEFAULT NULL,
`url` varchar(500) NOT NULL,
`meta_titulo` varchar(100) NOT NULL,
`meta_descripcion` varchar(200) NOT NULL,
`redirect` int(1) NOT NULL,
`estado_seo` varchar(10) NOT NULL DEFAULT 'danger',
`geo_data` varchar(50) DEFAULT NULL,
`media_principal` varchar(500) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_autor` (`id_autor`),
KEY `id_seccion` (`id_seccion`),
KEY `id_posicion` (`id_posicion`),
KEY `fecha` (`fecha`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=98560;
-
CREATE TABLE IF NOT EXISTS `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`descripcion` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `descripcion` (`descripcion`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=21097 ;
-
CREATE TABLE IF NOT EXISTS `tags_noticias` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_tag` int(11) NOT NULL,
`id_noticia` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_noticia` (`id_noticia`),
KEY `id_tag` (`id_tag`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=284979 ;
-
SELECT
SQL_CALC_FOUND_ROWS null as rows,
noticias.id,
noticias.titulo,
noticias.fecha,
noticias.url,
noticias.publicado,
noticias.estado_seo,
GROUP_CONCAT(tags.descripcion SEPARATOR ", ") as ntags
FROM noticias
JOIN tags_noticias ON tags_noticias.id_noticia = noticias.id
JOIN tags ON tags.id = tags_noticias.id_tag
GROUP BY noticias.id
ORDER BY noticias.id DESC
LIMIT 0,20
MySQL explain
JetProfiler Explain

sum function with join between two date ranges

hi friends i have two tables with name order and product order
CREATE TABLE `order` (
`order_num` int(11) NOT NULL AUTO_INCREMENT,
`date` date DEFAULT NULL,
`time` time DEFAULT NULL,
`cutomer_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`order_num`)
) ENGINE=InnoDB AUTO_INCREMENT=235 DEFAULT CHARSET=latin1
And
CREATE TABLE `product_order` (
`order_num` int(11) NOT NULL,
`idproduct` int(11) NOT NULL,
`quantity` tinyint(4) DEFAULT NULL,
`sub_price` int(11) DEFAULT NULL,
`price` int(11) DEFAULT NULL,
`actual_price` int(11) DEFAULT NULL,
PRIMARY KEY (`order_num`,`idproduct`),
KEY `fk_product_order_order1_idx` (`order_num`),
KEY `fk_product_order_product1_idx` (`idproduct`),
CONSTRAINT `fk_product_order_order1` FOREIGN KEY (`order_num`) REFERENCES `order` (`order_num`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_product_order_product1` FOREIGN KEY (`idproduct`) REFERENCES `product` (`idproduct`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
i want to join both table and want to retrieve the sum of product_order.actual_price,product_order.sub_price and product_order.quantity
between specific dates
my query return zero rows and i don't know how to solve this problem
here is my query
Select `order`.date,
Sum(product_order.actual_price) as actual_price_sum,
Sum(product_order.sub_price) as sub_price_sum,
Sum(product_order.quantity) as sold_quantity,
(Sum(product_order.sub_price)-Sum(product_order.actual_price)) as profit
From `order`
Inner Join product_order On `order`.order_num = product_order.order_num
WHERE CAST(`date` AS date) BETWEEN '2014-11-11' and '2015-11-11'
Group By `order`.date

how can i extract total forum_question and fourm_answer count as subject wise in mysql i have below mysql structure

forum_question :
CREATE TABLE IF NOT EXISTS `forum_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`question` text NOT NULL,
`subject_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `subject_id` (`subject_id`,`student_id`),
KEY `student_id` (`student_id`)
)
forum_answer table
CREATE TABLE IF NOT EXISTS `forum_answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`answer` text NOT NULL,
`question_id` int(11) NOT NULL,
`faculty_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`,`faculty_id`),
KEY `faculty_id` (`faculty_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
and subject table
CREATE TABLE IF NOT EXISTS `subject` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL
)
Try this edited query, I am sure this will work
SELECT
COUNT(que.id) AS totalQuestions,
(SELECT COUNT(DISTINCT(forum_answer.id))
FROM
forum_answer
WHERE
forum_answer.question_id = que.id
GROUP BY que.id)
AS totalAns
FROM
forum_question que
INNER JOIN
subject sub
ON (que.subject_id = sub.id)
WHERE
que.id > 0
GROUP BY sub.id
If by total you mean the total amount of rows, you can do the following:
`SELECT COUNT(*) FROM forum_question WHERE subject_id=YOURSUBJECT`
if you want just all rows, remove the WHERE clause.
Please you can try this Query
SELECT
subject.name AS subject_name,
count(forum_question.id) AS total_question,
(SELECT count(forum_answer.id)
FROM
forum_answer
WHERE
forum_answer.question_id = forum_question.id) AS total_answer
FROM
subject
Inner Join forum_question ON subject.id = forum_question.subject_id
GROUP BY subject.id
Sorry it was my mistake. now I edited the query and hope it will work for you

mysql select from one to many relation

I have two tables - Users and Products. User may have a few products. I need to select all products and show which user they belong.
How to solve it using mysql joins.
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(16) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8
I've tried like this:
SELECT users.login FROM users LEFT JOIN products ON users.id=products.user_id;
But in this case it shows me only user logins, but i need to get product name, price and description as well.
SELECT p.name, p.price, p.description, group_concat(u.login) as users
FROM products p
LEFT JOIN users u ON u.id = p.user_id
GROUP BY p.name, p.price, p.description