Why does a LEFT JOIN break my MySQL query? - mysql

SELECT value AS $point_fld, COUNT(value) as cnt
FROM ?_data d LEFT JOIN
?_user u
ON d.`table` = 'user' AND d.`id` = u.user_id
WHERE `key` = ? AND `value`<>'' AND `value`<>'Blank' AND
u.added BETWEEN ? AND ?
/* ----- I added this bit */
LEFT JOIN ?_invoice_payment p
ON d.'id' = p.user_id
SUM(p.amount) as moneysum
/* End ---- */
GROUP BY $point_fld
I am trying to edit this query to add in a sum value for payments based on which users are returned in the first part. The commented text is what I added. It is working just as intended but when I add in my part to get the values it breaks it.
Any suggestions would be amazing thanks. I'm pretty new to joins and stuff in SQL.

SELECT value AS $point_fld,
COUNT(value) as cnt,
SUM(p.amount) as moneysum
FROM ?_data d
INNER JOIN ?_user u ON d.`table` = 'user' AND d.`id` = u.user_id
LEFT JOIN ?_invoice_payment p ON d.'id' = p.user_id
WHERE `key` = ? AND `value`<>'' AND `value`<>'Blank' AND
u.added BETWEEN ? AND ?
GROUP BY value

OK this is what finally worked. Thanks for the help!
SELECT value AS $point_fld,
COUNT(DISTINCT u.user_id) as cnt,
SUM(p.amount) as moneysum
FROM ?_data d
LEFT JOIN ?_user u ON d.table = 'user' AND d.id = u.user_id
LEFT JOIN ?_invoice_payment p ON d.id = p.user_id
WHERE key = ? AND value<>'' AND value<>'Blank' AND
u.added BETWEEN ? AND ?
GROUP BY value

Related

Mysql - Display ID which occurs more than once

I have a column called "job_processing_id", "Description", "Who_marked_it"
My task is to find out any job_processing_id occuring more than once and display it.
I have written the below query :
Select cdh.job_processing_id, cdh.test_counter, tt.test_type, cd.description, u.name, cdh.added_at from call_description_history as cdh left join test_type as tt on tt.id = cdh.test_type_id left join call_description as cd on cd.id = cdh.call_description_id left join user as u on u.id = cdh.added_by where job_processing_id in (SELECT job_processing_id FROM call_description_history group by job_processing_id having count(job_processing_id)>1) and u.id NOT IN (7652, 5225) and added_a
But it also displays ID's that occure only once , which i don't need it.
Can someone help me how to get rid of it please?
Try this
SELECT job_processing_id, count(job_processing_id) FROM call_description_history group by job_processing_id having count(job_processing_id)>1;

Why does MySQL View and the same View's underlying SELECT query return different results?

I could do with some help here with this issue in which I'm trying to generate a set of results with balances brought forward and balances carried forward.
The MySQL script:
CREATE OR REPLACE VIEW vwbalances AS
SELECT th.user_id usrid
, YEAR(th.date_created) year
, IFNULL(
(SELECT SUM(tx.amount)
FROM transdetail tx
JOIN transhdr th
ON th.thdr_id = tx.thdr_id
JOIN users u
ON th.user_id = u.user_id
JOIN transtype tt
ON tt.ttype_id = tx.ttype_id
WHERE tx.ttype_id in (2,9,11)
AND u.user_id = usrid
and YEAR(tx.date_created) < year
)
,0) bal_bfwd
, SUM(td.amount) bal_ytd
, ifnull(
(SELECT SUM(ty.amount)
FROM transdetail ty
JOIN transhdr th
ON th.thdr_id = ty.thdr_id
JOIN users u
ON th.user_id = u.user_id
JOIN transtype tt
ON tt.ttype_id = ty.ttype_id
WHERE ty.ttype_id in (2,9,11)
AND u.user_id = usrid
AND YEAR(ty.date_created) <= year
)
,0) bal_cfwd
FROM transdetail td
JOIN transhdr th
ON th.thdr_id = td.thdr_id
JOIN users u
ON th.user_id = u.user_id
JOIN transtype tt
ON tt.ttype_id = td.ttype_id
WHERE td.ttype_id in (2,9,11)
GROUP
BY th.user_id
, YEAR(th.date_created)
I get this (incorrect results) when I run SELECT * FROM vwbalances:
And I get this (correct results) when I run the full SELECT statement that I used to create the VIEW:
Thanks in advance.
The query you posted shouldn't even work.
The usrid is an alias in your most outer select. It is not available in your subqueries.
Unless you have a column called year things like year(tx.date_created) < year shouldn't work either
You use the same table alias in your outer query and in your subqueries. This should also not be possible. If it is, that's probably why you get weird results.
Apart from that, you don't have to do the basically same query multiple times. You can shorten your query to something like this:
SELECT `th`.`user_id` AS usrid
, year(`th`.`date_created`) AS 'year'
sum(if(year(td.date_created`) < year, amount, 0)) as bal_ytd,
sum(if(year(td.date_created`) <= year, amount, 0)) as bal_cfwd
FROM `transdetail` `td`
JOIN `transhdr` `th` ON `th`.`thdr_id` = `td`.`thdr_id`
JOIN `users` `u` ON `th`.`user_id` = `u`.`user_id`
JOIN `transtype` `tt` ON `tt`.`ttype_id` = `td`.`ttype_id`
WHERE `td`.`ttype_id` IN (2, 9, 11)
GROUP BY `th`.`user_id`
, year(`th`.`date_created`)
(given of course, that this weird year thing works for you)
The following script has worked correctly. All help and tips appreciated:
CREATE OR REPLACE VIEW vwbalances AS
SELECT tho.user_id AS usrid, YEAR(td.date_created) AS 'year'
, ROUND(IFNULL((SELECT sum(tx.amount) FROM transdetail tx
JOIN transhdr th ON th.thdr_id = tx.thdr_id
JOIN users u ON th.user_id = u.user_id
JOIN transtype tt ON tt.ttype_id = tx.ttype_id
WHERE tx.ttype_id IN (2,9,11) AND u.user_id = tho.user_id AND
YEAR(tx.date_created) < YEAR(td.date_created) ),0),2) AS
bal_bfwd
, round(sum(td.amount),2) AS bal_ytd
, ROUND(IFNULL((select SUM(ty.amount) FROM transdetail ty
JOIN transhdr th on th.thdr_id = ty.thdr_id
JOIN users u ON th.user_id = u.user_id
JOIN transtype tt ON tt.ttype_id = ty.ttype_id
WHERE ty.ttype_id IN (2,9,11) AND u.user_id = tho.user_id AND
YEAR(ty.date_created) <= YEAR(td.date_created)),0),2) AS
bal_cfwd
FROM transdetail td JOIN transhdr tho ON tho.thdr_id =
td.thdr_id
JOIN users u ON tho.user_id = u.user_id
JOIN transtype tt on tt.ttype_id = td.ttype_id
WHERE td.ttype_id IN (2,9,11)
GROUP BY tho.user_id, YEAR(td.date_created);

MySQL Where Statement While checking value

$sql = "SELECT cc.name AS c_name, ev.name AS event_name, ev.eventModeId AS event_mode, ev.carClassHash, cc.carClassHash
FROM EVENT_DATA e
INNER JOIN PERSONA p ON e.personaId = p.ID
INNER JOIN CUSTOMCAR cc ON cc.ownedCarId = e.carId
INNER JOIN CAR_CLASSES ccs ON ccs.store_name = cc.name
INNER JOIN USER u ON u.ID = p.USERID
LEFT JOIN BAN b ON b.user_id = u.ID
INNER JOIN EVENT ev ON ev.ID = e.EVENTID
WHERE (p.name = ?
AND ev.carClassHash = cc.carClassHash)";
This query works for me except I'd also like to display any carClassHash with the value '607077938'. Is there a way I could somehow keep the above query to check if the event hash matches the car class hash but also still display values where the carClassHash (cc.carClassHash) is equal to '607077938'?
Thanks! :)
Why not use OR in the WHERE clause?
[...]
WHERE ((p.name = ? AND ev.carClassHash = cc.carClassHash) OR (cc.carClassHash = 607077938))
This should work if that value is an integer. If it's a string, use quotes around it.

Adding in max id for a SELECT query

I am trying to configure to only select the max id with a limit of one to my current query.
I have a link to a rextester below which shows the an actual example of what I am trying to figure out. Sorry for the error in it though...not sure what I did wrong when I created the example.
Anyways, you will see:
INSERT INTO `profile_img`
VALUES
(1,24,'beach'),
(2,55,'sandals'),
(3,56,'hotel'),
(4,55,'ocean'),
(5,55,'corona'),
(6,55,'tacos')
;
Which are some values in my profile_img table. Right now my query selects all of the profile images for the this ON p.user_id = f.friend_one. Resulting in duplicate output. It looks like this:
I just want it to output
55
56
and the appropiate max id img with it. Any one know how I can only SELECT the max id for for the img column of the profile_img table for the user_id that matches friend_one? ON p.user_id = f.friend_one.
However, sometimes the user does not have a profile_img. Previously I have used this in a query to get the default img for those that do not have one. (case when p.img <> '' then p.img else 'profile_images/default.jpg' end) as img
SELECT f.*
, p.*
FROM friends f
LEFT JOIN profile_img p
ON p.user_id = f.friend_one
WHERE f.friend_two = ?
AND f.status = ?
http://rextester.com/RLXS27142
If I understand correctly, you just want the profile image with the largest id:
SELECT f.*, p.*,
COALESCE(p.img, 'profile_images/default.jpg') as profile_img
FROM friends f LEFT JOIN
profile_img p
ON p.user_id = f.friend_one AND
p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
WHERE f.friend_two = ? AND f.status = ?;

Ho to get last item in mysql using max()

I want to get the last item as result using max(), but i'm just getting the first item even if im using max()
Here's the SQL code:
SELECT r.correct, r.items, r.percentage,MAX(r.date_taken) as date_taken,
u.username,u.FN, u.user_course_type,
IFNULL(u.user_major_type,'N/A') as user_major_type,u.level_name,
u.section_name
FROM bcc_fs_exam_result r
INNER JOIN
(SELECT u.id_user, u.username, CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type, m.user_major_type, l.level_name, s.section_name
FROM bcc_fs_user u
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
) u ON r.id_user = u.id_user WHERE r.id_exam = 5 GROUP BY r.id_user
TIA
What I take from your question is that you want to get the "correct", "items", "percentage" ect. columns of the row in bcc_fs_exam_result which has the last or first date.
If that's correct then you can filter bcc_fs_exam_result by first finding what is the min or max date by for each id_user then join that back on the exam results table.
SELECT
r.correct,
r.items,
r.percentage,
r.date_taken,
u.username,
u.FN,
u.user_course_type,
IFNULL(u.user_major_type,'N/A') as user_major_type,
u.level_name,
u.section_name
FROM bcc_fs_exam_result r
INNER JOIN (
SELECT u.id_user,
u.username,
CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type,
m.user_major_type,
l.level_name,
s.section_name
FROM bcc_fs_user u
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
) u ON r.id_user = u.id_user
INNER JOIN (
SELECT
id_user, max(r.date_taken) as last_date_taken
FROM bcc_fs_exam_result
GROUP BY id_user
) as lastdate ON lastDate.id_user = r.id_user and r.date_taken = lastdate.last_date_taken
which could be more simply written as :
SELECT
r.correct,
r.items,
r.percentage,
r.date_taken,
u.username,
CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type,
IFNULL(m.user_major_type,'N/A') as user_major_type,
l.level_name,
s.section_name
FROM bcc_fs_exam_result r
INNER JOIN (
SELECT
id_user, max(r.date_taken) as last_date_taken
FROM bcc_fs_exam_result
GROUP BY id_user
) as lastdate ON lastDate.id_user = r.id_user and r.date_taken = lastdate.last_date_taken
INNER JOIN bcc_fs_user u on r.id_user = u.id_user
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
You have assumed that id_user + date_taken is a surrogate key of bcc_fs_exam_result which you should probably enforce with a constraint if at all possible. Otherwise it looks from your sample data that the order of the unique id column id_result follows the date_takenso you might be better to use Max(id_result) rather than Max(date_taken). That would avoid returning duplicate rows for one id_user where two rows of bcc_fs_exam_result have the same taken_date and `id_user.