join clause not showing all results - mysql

this is a very weird issue.
I have 3 tables, all with key relations on agent_id.
Now this query :
select DATE_FORMAT(created_on,"%d/%m/%y") as date
from logs
where agent_id = "18"
and log_status="1"
and date_format(created_on,"%m/%y") = "12/12"
group by YEAR(created_on), MONTH(created_on), DAY(created_on) desc
Does exactly what it suppoused to, it returns 3 rows of :
date
31/12/12
30/12/12
26/12/12
However when I join 2 other tables it excludes the date of 31/12/12. This is the query :
select DATE_FORMAT(l.created_on,"%d/%m/%y") as date
from logs l
join logs_rewards lr on l.id = lr.related_log_id
join agents a on a.id = l.agent_id
where l.log_status = "1"
and DATE_FORMAT(l.created_on,"%m/%y") = '12/12'
AND l.agent_id = '18'
group by YEAR(l.created_on), MONTH(l.created_on), DAY(l.created_on) desc
This returns :
date
30/12/12
26/12/12
And I can't figure out why that happens. Any help?
I've tried changing AND l.agent_id = '18' to AND a.id = '18' but same result.

This is because data are not mapped in all the 3 tables.
Below query will work
select DATE_FORMAT(l.created_on,"%d/%m/%y") as date
from logs l
left join logs_rewards lr on l.id = lr.related_log_id
left join agents a on a.id = l.agent_id
where l.log_status = "1"
and DATE_FORMAT(l.created_on,"%m/%y") = '12/12'
AND l.agent_id = '18'
group by YEAR(l.created_on), MONTH(l.created_on), DAY(l.created_on) desc

Maybe you want to replace JOIN with LEFT JOIN to get all results from logs.

Related

Returning records from multiple (4) tables

I am trying to write a query returning records from multiple tables.
ConfRooms contains a list of rooms
FIDS_Hardware contains information about the hardware in the room
ConfBookings contains a list of booked rooms
ConfRoomOverride contains information on the room status, i.e does the room have an override flag set
Return all the records from "ConfRooms AS c" where c.HotelID = 'EXBHX'.
Return all the records from "FIDS_Hardware AS h" where r.HotelID = 'EXBHX' AND c.ConfRoomID = h.deviceID.
Return all the record from "ConfBookings AS b" where HotelID = 'EXBHX' AND c.ConfRoomName = b.RoomName.
Return all the record from "ConfRoomOverride AS o" where HotelID = 'EXBHX' AND c.ConfRoomNID = b.RoomID
At the moment my query is not returning all the records from "ConfRooms" but returns only the room that have a booked status in ConfBookings.
Can anyone see where I am going wrong.
SELECT
h.messageCount,
h.deviceID,
c.ConfRoomName,
r.DisplayMainBoard,
r.RecordID,
r.RoomID,
r.RoomName,
r.RoomBooked,
r.RoomFromDate,
r.RoomToDate,
r.FullBoardRoom,
COUNT(r.RecordID) AS RC,
r.Override,
r.HotelID,
o.Override AS ConfOverride
FROM
ConfRooms AS c
Left Join FIDS_Hardware AS h ON (c.ConfRoomID = h.deviceID)
Left Join ConfBookings AS r ON (c.ConfRoomName = r.RoomName)
Left Join ConfRoomOverride AS o ON (c.ConfRoomID = o.RoomID)
WHERE c.HotelID = 'EXBHX'
AND r.HotelID = 'EXBHX'
AND h.hotelID = 'EXBHX'
GROUP BY c.ConfRoomID
ORDER BY h.messageCount DESC,
ConfOverride DESC,
r.RoomBooked DESC,
c.ConfOrder ASC
Just try this :
SELECT
h.messageCount,
h.deviceID,
c.ConfRoomName,
r.DisplayMainBoard,
r.RecordID,
r.RoomID,
r.RoomName,
r.RoomBooked,
r.RoomFromDate,
r.RoomToDate,
r.FullBoardRoom,
COUNT(r.RecordID) AS RC,
r.Override,
r.HotelID,
o.Override AS ConfOverride
FROM
ConfRooms AS c
Left Join FIDS_Hardware AS h ON (c.ConfRoomID = h.deviceID AND h.hotelID = 'EXBHX')
Left Join ConfBookings AS r ON (c.ConfRoomName = r.RoomName AND r.HotelID = 'EXBHX')
Left Join ConfRoomOverride AS o ON (c.ConfRoomID = o.RoomID)
WHERE c.HotelID = 'EXBHX'
GROUP BY c.ConfRoomID
ORDER BY h.messageCount DESC,
ConfOverride DESC,
r.RoomBooked DESC,
c.ConfOrder ASC
The problem is that your WHERE clause removes the benefits of your multiple left joins.
When you left join FIDS_Hardware AS h, it means that h values can be null but when you are executing "h.hotelID = 'EXBHX'" in your where clause you only select rows where h values are not null (a row has matched).
So what you need to do is to move these conditions right inside the ON clause of the left join as above.

Sql trouble with coalesce() not working propely

i have a query and i'm having trouble to change the name of the last row of columb name to 'TOTAL'. The result gives me the same name of the row above the last row.
Here's my query:
SELECT COALESCE(ticket_types.name,'TOTAL') AS name,
COUNT(1) AS quantity
FROM tr_logs
LEFT JOIN tickets ON tr_logs.value = tickets.id
LEFT JOIN ticket_types ON tickets.ticket_type_id = ticket_types.id
LEFT JOIN transactions ON tr_logs.transaction_id = transactions.id
LEFT JOIN tr_fields_data AS tfd_shipping ON tfd_shipping.transaction_id = transactions.id
WHERE type = 'ADDITEM'
AND transactions.event_id = '46'
AND DATE(tr_logs.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd_shipping.data IN ('0','570','571','771')
AND name IS NOT NULL
GROUP BY ticket_types.id WITH ROLLUP
The result looks like this:
name quantity
premium 56
outlaw 6
outlaw 62
Last row name from rollup is not null.... I need it to be TOTAL and not outlaw
Thanks
You haven't changed the name to TOTAL at all: you've changed the name of the column to name, and you've told it to replace any null values with TOTAL.
If you want to change the name of ticket_types.name to total, you just want
SELECT ticket_types.name AS total ...
(But it would be weird to rename something called name to total, so perhaps you need to clarify your requirements a little.)
This may or not be related to your observed problem, but the WHERE and GROUP BY clauses turn all the outer joins into inner joins. You should simplify the query to:
SELECT COALESCE(tt.name, 'TOTAL') AS name, COUNT(1) AS quantity
FROM tr_logs l JOIN
tickets
ON l.value = t.id JOIN
ticket_types tt
ON t.ticket_type_id = tt.id JOIN
transactions tr
ON l.transaction_id = tr.id JOIN
tr_fields_data fd
ON fd.transaction_id = tr.id
WHERE type = 'ADDITEM' AND
tr.event_id = '46' AND
DATE(l.created_date) BETWEEN '2017-03-26' AND '2017-05-24' AND
fd.data IN ('0', '570', '571', '771') AND
tt.name IS NOT NULL
GROUP BY tt.id WITH ROLLUP
Thanks to Gordon Linoff I have figure out my problem.
The name of the last row was never null beacause i GROUP BY with a different attribute.
Here's the solution.
SELECT COALESCE(tckn,'TOTAL') AS name, quantity FROM
(SELECT tt.name AS tckn, COUNT(1) AS quantity
FROM tr_logs AS l
LEFT JOIN tickets AS t ON l.value = t.id
LEFT JOIN ticket_types AS tt ON t.ticket_type_id = tt.id
LEFT JOIN transactions AS tr ON l.transaction_id = tr.id
LEFT JOIN tr_fields_data AS tfd ON tfd.transaction_id = tr.id
WHERE type = 'ADDITEM'
AND tr.event_id = '46'
AND DATE(l.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd.data IN ('0','570','571','771')
GROUP BY tckn WITH ROLLUP) as sum;

Difficult MySQL Statement

I've got this query but the result is wrong.
How can I use the min() statement and the Group by Statement so that I will get for each AthletenID the lowest DiszOrder?
Select
ar_Leistungen.`AthletenID`,
ar_Leistungen.`Leistung`,
ar_Leistungen.`Disziplin`,
ar_Leistungen.`Klasse`,
min(ar_Leistungen.`DiszOrder`),
ar_Athleten.`Vorname`,
ar_Athleten.`Jahrgang`,
ar_Wettkampf.`Wettkampfdatum`
from
ar_Leistungen,
ar_Athleten,
ar_Wettkampf
Where
ar_Athleten.ID = ar_Leistungen.AthletenID and
ar_Leistungen.WettkampfID = ar_Wettkampf.ID and
ar_Leistungen.`Disziplin` = '100' and
ar_Leistungen.`Leistung` > 0 and
(ar_Athleten.`Jahrgang` = '1995' or ar_Athleten.`Jahrgang` = '1994') and
ar_Wettkampf.`Wettkampfdatum` LIKE '%2013%'
Group By
AthletenID
Order by
DiszOrder Desc
Limit
0, 100
You can have a subquery which separately gets the lowest DiszOrder for each AthletenID and join it with the other table so you can freely get the other value of the columns.
SELECT a.AthletenID,
a.Leistung,
a.Disziplin,
ar_Leistungen.Klasse,
a.DiszOrder),
b.Vorname,
b.Jahrgang,
c.Wettkampfdatum
FROM ar_Leistungen a
INNER JOIN ar_Athleten b
ON b.ID = a.AthletenID
INNER JOIN ar_Wettkampf c
ON a.WettkampfID = c.ID
INNER JOIN
(
SELECT AthletenID, MIN(DiszOrder) DiszOrder
FROM ar_Leistungen
GROUP BY AthletenID
) d ON a.AthletenID = d.AthletenID AND
a.DiszOrder = d.DiszOrder
WHERE a.Disziplin = '100' AND
a.Leistung > 0 AND
(b.Jahrgang IN ('1995', '1994'))

MySQL query sub query or grouping

Each modx_site_content record may have several records in modx_site_tmplvar_contentvalues.
I need to retrieve both modx_site_tmplvar_contentvalues.value where the tvv.tmplvarid = 3 AND the tvv.tmplvarid = 1. where tvv.tmplvarid is a future date, I need to return the tvv.value of tvv.tmplvarid 3 which is a comma separated list of tags.
This query does not return the values I need & I'm not sure how to get just what I want.
SELECT sc.id, sc.pagetitle, tvv.value, tvv.tmplvarid, tvv.id, tvv.value
FROM modx_site_content sc
left join modx_site_tmplvar_contentvalues tvv on tvv.contentid = sc.id
where published = '1'
and (tvv.tmplvarid = '3' and tvv.value >= curdate())
order by sc.id;
basically in the end I need to return only the list of tags (tvv.tmplvarid = 3) where the other associated record (tvv.tmplvarid = 1) is a date in the future.
Any thoughts, can this be done with grouping instead? I don't actually need anything from the modx_site_content table.
So you need to return the tags both rows in the modx_site_tmplvar_contentvalues table that has tmplvarid of 1 and 3 both related to the same modx_site_content, but only when the tmplvarid 3 row has a datetime field in the future?
I would do two separate joins to the modx_site_tmplvar_contentvalues tabe:
SELECT tOne.value, tThree.value
FROM modx_site_tmplvar_contentvalues tOne
INNER JOIN modx_site_content c ON tOne.contentid = c.id
INNER JOIN modx_site_tmplvar_contentvalues tThree ON tThree.contentid = c.id
WHERE c.published = 1
AND tOne.tmplvarid = 1
AND tThree.tmplvarid = 3 AND tThree.date > NOW()
SQL Fiddle: http://sqlfiddle.com/#!2/a4031/2
I figured it out. Amazing what you can do if you just read the docs ;)
select tv.contentid, tv.value as eventdate, sc.id, sc.pagetitle, tvv.value from
(
select * from modx_site_tmplvar_contentvalues cv
where cv.tmplvarid = 3
and cv.value >= curdate()
) as tv
left join modx_site_content sc on sc.id = tv.contentid
left join modx_site_tmplvar_contentvalues tvv on tvv.contentid = sc.id
where (tvv.tmplvarid = 1)
order by value asc

sql query that went it runs it repeats the same result by the number of users

Hi hope someone can advise
I have a sql query that went it runs it repeats the same result by the number of users (entries) made
for example:
post_id
20
20
19
19
18
18
Here is the query it takes no arguments, could someone explain why this is happening please?
Thanks
SELECT DISTINCT post_look.post_id, post_look.look_id, post_look.date_posted, looks.title, looks.item_id, user.user_id, user.first_name, user.last_name, user_account.profile_image, user_account.account_status, add_profile_images.image_name
FROM post_look
JOIN looks ON looks.look_id = post_look.look_id
JOIN add_look_item ON add_look_item.look_id = looks.look_id
JOIN item ON item.item_id = add_look_item.item_id
JOIN add_images ON add_images.item_id = item.item_id
JOIN user_item ON user_item.item_id = item.item_id
JOIN user_account ON user_account.account_id = user_item.account_id
JOIN user ON user.user_id = user_account.user_id
JOIN users_profile_images ON users_profile_images.account_id = user_account.account_id
JOIN add_profile_images ON add_profile_images.image_id = users_profile_images.image_id
ORDER BY post_look.post_id DESC
LIMIT 0 , 30
SELECT DISTINCT c1, c2, c3
means that {c1, c2, c3} will be distinct.
You should consider adding GROUP BY post_look.post_id to your query.
See the difference here:
DISTINCT
GROUP BY
Would you please try it?
SELECT post_look.post_id, post_look.look_id, post_look.date_posted, looks.title, looks.item_id, user.user_id, user.first_name, user.last_name, user_account.profile_image, user_account.account_status, add_profile_images.image_name
FROM post_look
JOIN looks ON looks.look_id = post_look.look_id
JOIN add_look_item ON add_look_item.look_id = looks.look_id
JOIN item ON item.item_id = add_look_item.item_id
JOIN add_images ON add_images.item_id = item.item_id
JOIN user_item ON user_item.item_id = item.item_id
JOIN user_account ON user_account.account_id = user_item.account_id
JOIN user ON user.user_id = user_account.user_id
JOIN users_profile_images ON users_profile_images.account_id = user_account.account_id
JOIN add_profile_images ON add_profile_images.image_id = users_profile_images.image_id
GROUP BY post_look.post_id
ORDER BY post_look.post_id DESC
LIMIT 0 , 30