SELECT query check for something outside of database - mysql

I have the following query below and it works for the most part, until I just noticed it is causing a slight issue. Basically what the existing query does it select all the information from my 'home_comments' table and then matches the max id from the profile_img table and takes that image.
The issue I am running into is that not all of my users have profile images within this database. For default images, I use a static image. So, is there anyway I can check if the user has a profile_img and if not use this?
$default_profile_img = '<img class="home-profile-pic" src="profile_images/default.jpg">';
Query:
$select_comments_sql = "
SELECT c. *, p.user_id, p.img
FROM home_comments AS c
INNER JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
INNER JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC
EDIT: updated SQL
$select_comments_sql = "
//SELECT c. *, p.user_id, p.img
SELECT c. *, PI.user_id, case when PI.img <> '' and PI.img is not null then PI.img else 'profile_images/default.jpg' end img
FROM home_comments AS c
LEFT JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
LEFT JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC
";
Errors:
[27-Oct-2016 13:29:56 America/Chicago] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '//SELECT c. *, p.user_id, p.img
SELECT c. *, PI.user_id, case when PI.img <> ' at line 1' in /home4//public_html/.com/account/ajax-php/comment-retrieve.php:36`

You can use a case statement:
$select_comments_sql = "
SELECT c. *, p.user_id, case when p.img <> '' and p.img is not null then p.img else 'my-default.png' end img
FROM home_comments AS c
INNER JOIN (SELECT max(id) as id, user_id
FROM profile_img
GROUP BY user_id) PI
on PI.user_id = c.user_id
INNER JOIN profile_img p
on PI.user_id = p.user_id
and PI.id = p.id
ORDER BY c.id DESC

Try this way, I assume you use mysqli and $row returns associative array.
$row = mysqli_fetch_assoc($select_comments_sql);
if(!empty($row['profile_image_field_name'])){
$default_profile_img = '<img class="home-profile-pic" src="profile_images/'.$row['profile_image_feild_name'].'">';
}else{
$default_profile_img = '<img class="home-profile-pic" src="profile_images/default.jpg">';
}

Related

How to use FIND_IN_SET with select statement in symfony 5.1?

symfony version: 5.1
There is a sql statement and work in command:
SELECT
p.sn as pid,
p.title as title,
pc.title as categoryName
GROUP_CONCAT(CONCAT_WS('=', pa.`meta_key`, pa.`meta_value`) order by a.`sort_by` asc) as filters
FROM `product` as p
LEFT JOIN `product_category` as pc on pc.id = p.`category_id`
LEFT JOIN `product_model` as pm on p.`model_id` = pm.id
LEFT JOIN `brand` as b on b.id = p.brand_id
LEFT JOIN `product_attribute` as pa on pa.`product_id` = p.id
LEFT JOIN `attribute` as a on pa.`attribute_id` = a.id
WHERE p.status = 1 and a.`search_enable` = 1 and pa.`attribute_id` is not null
and FIND_IN_SET('name=test', (
SELECT
GROUP_CONCAT(CONCAT_WS('=', pa2.`meta_key`, pa2.`meta_value`))
FROM `product_attribute` as pa2
LEFT JOIN `attribute` as a2 on a2.`id` = pa2.`attribute_id`
WHERE pa2.`product_id` = p.`id` and a2.`search_enable` = 1
GROUP BY pa2.`product_id`
)) and FIND_IN_SET('age=18', (
SELECT
GROUP_CONCAT(CONCAT_WS('=', pa2.`meta_key`, pa2.`meta_value`))
FROM `product_attribute` as pa2
LEFT JOIN `attribute` as a2 on a2.`id` = pa2.`attribute_id`
WHERE pa2.`product_id` = p.`id` and a2.`search_enable` = 1
GROUP BY pa2.`product_id`
))
GROUP BY p.`id`;
But the function of FIND_IN_SET is not working in doctrine query.
$query->andWhere("FIND_IN_SET('age=18', '(SELECT GROUP_CONCAT(CONCAT_WS('=', pa2.metaKey, pa2.metaKey)) FROM ProductAttribute as pa2 LEFT JOIN Attribute as a2 on a2.id = pa2.attribute WHERE pa2.product = p.id and a2.searchEnable = 1 GROUP BY pa2.product)')");
I get error message:
PHP message: [critical] Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "[Syntax Error] line 0, col 657: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='"
If I change the find_in_set statement remove the single quotes wit select statement:
$query->andWhere("FIND_IN_SET('age=18', (SELECT GROUP_CONCAT(CONCAT_WS('=', pa2.metaKey, pa2.metaKey)) FROM ProductAttribute as pa2 LEFT JOIN Attribute as a2 on a2.id = pa2.attribute WHERE pa2.product = p.id and a2.searchEnable = 1 GROUP BY pa2.product)");
I got this error message:
PHP message: [critical] Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "[Syntax Error] line 0, col 625: Error: Expected Literal, got 'SELECT'"
How to use the FIND_IN_SET with select statement?
About the relationship of table:
1, product and product_category are manyToOne;
2, product and product_model are manyToOne;
3, product and brand are manyToOne;
4, product and product_attribute are oneToMany;
5, product_attribute and attribute are ManyToOne;
The product has many attributes that a part of it will be filtered when user search product with keywords.
So, I want to a filter function same as amazon that user can click the option of filter to get a new list of products from search result.

MySQL: JOIN multiple tables

I have the following query I am trying to join 2 tables (' Industry' , 'Country' ) on 2 conditions, but it gives me the following error
Error Code: 1054. Unknown column 'i.id' in 'on clause'
Does anybody know how should I tackle this?
SELECT c.name AS country_name, i.name as industry_name, num_projects, num_consultants, admin_rating
FROM industry i, country c
JOIN (SELECT pc.country_id, pi.industry_id, COUNT(p.id) AS num_projects
FROM project p, project_country pc, project_industry pi
where p.id = pc.project_id and pi.project_id=p.id
GROUP BY pc.country_id,pi.industry_id) x ON x.country_id = c.id and x.industry_id=i.id
JOIN (SELECT u.country_id,ie.industry_id, COUNT(u.id) AS num_consultants
FROM user u, consultant_profile, industry_experience ie
WHERE u.is_active = 1 AND u.type = 0 and
ie.consultant_profile_id= consultant_profile.id
and u.id= consultant_profile.id
GROUP BY u.country_id,ie.industry_id) y ON y.country_id = c.id and y.industry_id = i.id order by num_projects DESC limit 20;
EDIT the table structure is as following:
industry - id
project_industry - industry_id, project_id
industry_experience - consultant_profile_id, industry_id
consultant_profile - id,user_id
Since you still did not provide any sql fiddle
you can start from my one:
http://sqlfiddle.com/#!9/6c0569/1
SELECT pc.country_id, pi.industry_id,
COUNT(p.id) AS num_projects,
COUNT(u.id) AS num_consultants
FROM project p
INNER JOIN project_country pc
ON p.id = pc.project_id
INNER JOIN project_industry pi
ON pi.project_id=p.id
INNER JOIN `user` u
ON u.is_active = 1 AND u.type = 0
and u.country_id = pc.country_id
INNER JOIN industry_experience ie
ON u.id = ie.consultant_profile_id
AND ie.industry_id = pi.industry_id
GROUP BY pc.country_id, pi.industry_id
if you will add some data into that fiddle we can discuss deeper

use subquery in inner join mysql

This is my query
SELECT CONCAT(`SM_Title`,' ',`SM_Full_Name`) AS NAME,
`RG_Date`,
`RG_Reg_No`,
`RG_Stu_ID`,
`SM_Tell_Mobile`,
`SM_Tel_Residance`,
`RG_Reg_Type`,
Default_Batch,
`RG_Status`,
`RG_Final_Fee`,
`RG_Total_Paid`,
(`RG_Final_Fee`-`RG_Total_Paid`) AS TOTALDUE,
SUM(`SI_Ins_Amount` - `SI_Paid_Amount`) AS AS_AT_APRIAL_END
INNER JOIN
(SELECT `SI_Ins_Amount`,
`SI_Reg_No`
FROM
`student_installments`
GROUP BY MONTHNAME(`SI_Due_Date`)) Z ON
Z.`SI_Reg_No` = `registrations`.`RG_Reg_No`
FROM `registrations`
LEFT JOIN `student_master` ON `student_master`.`SM_ID` = `registrations`.`RG_Stu_ID`
LEFT JOIN `student_installments` ON `student_installments`.`SI_Reg_No` = `registrations`.`RG_Reg_No`
WHERE (`RG_Reg_Type` LIKE '%HND%' OR `RG_Reg_Type` LIKE '%LMU%' )
AND `SI_Due_Date` <= '2014-04-30' GROUP BY `SI_Reg_No`
It gave me an error near
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Z LIMIT 0, 25' at line 1
SELECT
CONCAT(SM_Title,' ',SM_Full_Name) AS NAME,
RG_Date,
RG_Reg_No,
RG_Stu_ID,
SM_Tell_Mobile,
SM_Tel_Residance,
RG_Reg_Type,
Default_Batch,
RG_Status,
RG_Final_Fee,
RG_Total_Paid,
(RG_Final_Fee-RG_Total_Paid) AS TOTALDUE,
SUM(SI_Ins_Amount - SI_Paid_Amount) AS AS_AT_APRIAL_END
FROM registrations
INNER JOIN
(SELECT SI_Ins_Amount,SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)) Z ON Z.SI_Reg_No = registrations.RG_Reg_No
LEFT JOIN student_master ON student_master.SM_ID = registrations.RG_Stu_ID
LEFT JOIN student_installments ON student_installments.SI_Reg_No = registrations.RG_Reg_No
WHERE (RG_Reg_Type LIKE '%HND%' OR RG_Reg_Type LIKE '%LMU%' )
AND SI_Due_Date <= '2014-04-30'
GROUP BY SI_Reg_No
I notice you have fogotten the left table or subselect that you want to join to the (SELECT SI_INs .....) and previous this I could see there is no from clause before join.
I hope this helps you
Regards
You are using from clause in wrong position it should be just after selection of your columns, you can use below query:
SELECT
CONCAT(SM_Title,' ',SM_Full_Name) AS NAME ,RG_Date,RG_Reg_No,RG_Stu_ID,SM_Tell_Mobile,SM_Tel_Residance,RG_Reg_Type,Default_Batch,RG_Status,RG_Final_Fee,RG_Total_Paid,(RG_Final_Fee-RG_Total_Paid) AS TOTALDUE, SUM(SI_Ins_Amount - SI_Paid_Amount) AS AS_AT_APRIAL_END
FROM registrations AS reg
JOIN
(SELECT
SI_Ins_Amount,SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)) AS Z
ON Z.SI_Reg_No = reg.RG_Reg_No
LEFT JOIN student_master AS sm
ON sm.SM_ID = reg.RG_Stu_ID
LEFT JOIN student_installments AS si
ON si.SI_Reg_No = reg.RG_Reg_No
WHERE (RG_Reg_Type LIKE '%HND%' OR RG_Reg_Type LIKE '%LMU%' ) AND SI_Due_Date <= '2014-04-30'
GROUP BY SI_Reg_No;
In the part below, from keyword should go before the inner join:
FROM registrations
INNER JOIN
(SELECT SI_Ins_Amount,
SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)
) Z
ON Z.SI_Reg_No = registrations.RG_Reg_No

COALESCE function in MYSQL with select gives error

I am wondering what is the problem of my query which is simple for me, please also have a look and please let me know if I missed something
SELECT users.*, p.*,
COALESCE(SELECT picture_location FROM pictures
WHERE user_id = 'patient' AND default_pic = 1,
SELECT picture_location FROM pictures
WHERE user_id = 'patient' ORDER BY id ASC LIMIT 1) AS default_pic,
pic.picture_location, MONTHNAME(users.registered_on) AS month_reg,
YEAR(users.registered_on) AS year_reg FROM users
LEFT JOIN profile p ON p.profile_id = users.profile_id
LEFT JOIN pictures pic ON pic.user_id = p.profile_id
WHERE users.pseudo = 'patient' GROUP BY users.pseudo
ORDER BY pic.default_pic DESC LIMIT 1
Do you see something ? It returns me this :
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT picture_location FROM pictures WHERE user_id = 'patient' AND default_pic ' at line 1
A nested select needs an additional layer of parentheses:
SELECT users.*, p.*,
COALESCE((SELECT picture_location FROM pictures WHERE user_id = 'patient' AND default_pic = 1),
(SELECT picture_location FROM pictures WHERE user_id = 'patient' ORDER BY id ASC LIMIT 1)) AS default_pic,
pic.picture_location,
MONTHNAME(users.registered_on) AS month_reg, YEAR(users.registered_on) AS year_reg
FROM users LEFT JOIN
profile p
ON p.profile_id = users.profile_id LEFT JOIN
pictures pic
ON pic.user_id = p.profile_id
WHERE users.pseudo = 'patient'
GROUP BY users.pseudo
ORDER BY pic.default_pic DESC
LIMIT 1;

MySQL limit inside of the subquery produces error

I'm receiving:
[Err] 1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
While executing the following query:
UPDATE account.account
SET STATUS = 'BLOCK'
WHERE
id IN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY
log.`who`
HAVING
COUNT(log.who) > 2
LIMIT 10
);
Is there a posibility to rewrite this query so MySQL could execute it?
The solution is to join against a subquery rather than use an IN(). The INNER JOIN will only return rows in account matching ids from the limited subquery. It is then possible to do the UPDATE without a WHERE clause.
Update
account.account AS account
INNER JOIN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY log.`who`
HAVING COUNT(log.who) > 2
LIMIT 10
) subq ON account.id = subq.id
SET STATUS='BLOCK'
To verify the rows that would be modified, use a SELECT first:
SELECT
account.*
FROM
account.account
INNER JOIN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY log.`who`
HAVING COUNT(log.who) > 2
LIMIT 10
) subq ON account.id = subq.id