I have this rather complex query that grabs data from three tables, and now I want it to be even more complicated (Oh dear)!
I'd like the last posted feature to be displayed in it's own section of the page, and that's pretty easy by selecting the last entry in the table. However, for the complex query (the main page of the site), I'd like to be able to NOT have this feature displayed.
I'd like to union the following query to my previous query, but it isn't returning the correct results:
SELECT
features.featureTitle AS title,
features.featureSummary AS body,
features.postedOn AS dummy,
DATE_FORMAT( features.postedOn, '%M %d, %Y' ) AS posted,
NULL,
NULL,
staff.staffName,
features.featureID
FROM
features
LEFT JOIN staff ON
features.staffID = staff.staffID
WHERE features.postedOn != MAX(features.postedOn)
ORDER BY dummy DESC LIMIT 0,15
This query returns the following error:
MySQL error: #1111 - Invalid use of group function
Is there any way around this?
The max query needs to be in its own subquery, so your final SQL should be::
SELECT features.featureTitle AS title,
features.featureSummary AS body,
features.postedOn AS dummy,
DATE_FORMAT( features.postedOn, '%M %d, %Y' ) AS posted,
NULL,
NULL,
staff.staffName,
features.featureID
FROM
features
LEFT JOIN staff ON
features.staffID = staff.staffID
WHERE
features.postedOn != (select max(features.postedOn) from features)
the problem you have is that is that you need to find the max (latest) feature from the table, while going over each row, but MAX() is a group function - you have to group all rows to use it.
you can use a sub-select to get the id of the last feature:
WHERE featureId <> (SELECT featureId From features ORDER BY postedOn DESC LIMIT1)
there is a problem with this approach - the subselect is run for every row, but it is not that expensive.
You could also order by the PostedOn field in descending order and add OFFSET 1, which will display your results starting from the second row.
SELECT features.featureTitle AS title,
features.featureSummary AS body,
features.postedOn AS dummy,
DATE_FORMAT(features.postedOn, '%M %d, %Y') AS posted,
NULL,
NULL,
staff.staffName,
features.featureID
FROM
features
LEFT JOIN staff ON
features.staffID = staff.staffID
ORDER BY features.postedOn DESC
OFFSET 1;
Related
I have rows that get updated automatically. Sometimes rows are updated (via a new insert - an almost duplicate row) where some columns remain the same - and other columns have new values. I want to pull the most recent up to date row; all the values. Here's what I've got
SELECT * FROM
(SELECT * FROM
(SELECT * FROM entries
WHERE dataset_id = xxx
ORDER BY time_added DESC
) alias1 GROUP BY title
) alias2 ORDER BY timestamp
Work backwards on this list:
SELECT #1 > Reorders these to be displayed based on the timestamp initially created (not added)
SELECT #2 > Filters Select #3 to select distinct title values (most recent title)
SELECT #3 > First query actually executed. Gets the dataset orderd by timestamp added
Is there a more efficient way to do this? I get serious code bad smell from it.
Use a group by and join:
select e.*
from entries e join
(select title, max(time_added) as maxta
from entries e
where dataset_id = xxx
group by title
) emax
on emax.title = e.title and e.time_added = emax.maxta
where dataset_id = xxx
order by e.timestamp;
Your method uses a MySQL extension to group by, where you have columns in the select list that are not in the group by. This is explicitly documented to return indeterminate results. Don't use features that are documented not to work, even if they seem to under some circumstances.
I have the below query and it works fine at returning results based on the set timestamp.
SELECT * FROM catalog WHERE part IN (SELECT part FROM query_data WHERE timestamp >= '2015-02-02') LIMIT 10
What I would like to do is get the results from the above but ORDER BY timestamp in DESC order. Something like this, but it doesn't work. The same values are returned, but not in DESC order based on the timestamp.
SELECT * FROM catalog WHERE part IN (SELECT part FROM query_data WHERE timestamp >= '2015-02-02' ORDER BY timestamp DESC) LIMIT 10
Thoughts? The timestamp column is only found in the query_data table. Not sure if this is causing the issue or not?
I believe this will work:
SELECT * FROM catalog c INNER JOIN query_data q ON c.part = q.part WHERE q.timestamp >= '2015-02-02' ORDER BY timestamp DESC;
The main problem with your approach is that you are ordering the subquery. Using a join and "order by" outside should fix it.
I would encourage you to watch this link (subselect order timestamp) The problem you have is as you thought, even if the subselect is ordered then it gets out of place on the main query, a Join would be useful for this cases.
Hope it helps you.
I've been searching for a while and couln't find an example that worked. Hopefully you can spot the glaring mistake!
SELECT
Timestamp
, i_currency.Code AS Code
, Conversion
FROM
i_convert(
SELECT
Timestamp
, Conversion
FROM
i_convert
ORDER BY Timestamp DESC
)
JOIN i_currency
ON i_convert.CurrencyID = i_currency.CurrencyID
GROUP BY Code
I'm not sure wherer the JOIN should be, should it be in the parentheses, outside or both? I've tried all three with no luck, keep getting:
You have an error... ...near '( SELECT Timestamp , Conversion FROM i_convert ORDER '
The original query doesn't make sense. It is using GROUP BY, but attempting to select columns that are neither grouping columns nor aggregate functions of the groups. Which Timestamp and which Conversion are expected for any given result row?
I suppose the objective is to select the most recent conversion for each currency. That might look more like this:
SELECT
latest.Timestamp AS Timestamp
, i_currency.Code AS Code
, i_convert.Conversion AS Conversion
FROM i_currency
JOIN i_convert
ON i_convert.CurrencyID = i_currency.CurrencyID
JOIN (
SELECT MAX(Timestamp) as Timestamp, CurrencyId
FROM i_convert
GROUP BY CurrencyId
) latest
ON i_convert.Timestamp = latest.Timestamp
AND i_convert.CurrencyId = latest.CurrencyId
Getting an error that I'm not grouping properly or what I am grouping isnt allowed but I searched around a bit and didn't see a case like this. All the other posts that had this error had an aggregate function in the where clause. Nothing changes unless I completely remove the grouping. Using an actual date in the where clause rather than
>= NOW() - INTERVAL 30 DAY
doesnt change the result.
Im looking for an support agent's name, a label that was applied to a case that they were on, the average rating for that agent on that label, and the count of how many tickets they worked on with that label applied.
This is the query I'm running:
select a.public_name, 'settings', format(avg(r.rating),2) as 'average',
count(label_name), pk_case_id
from bi.support_agents_list a
join bi.support_ratings_agents sra
on a.desk_id = sra.agent_desk_id
join bi.support_ratings r
on sra.response_id = r.response_id
and r.survey_id = sra.survey_id
join bizdw.support_labels_assigned_v2 l
on l.fk_case_id = r.pk_case_id
where r.date_submitted >= NOW() - INTERVAL 30 DAY
and a.start_date < '2014-01-22'
and a.end_date is null
and lower(l.label_name) in ('settings',
'settings-contributor'
'settings-socialaccount')
group by a.public_name, 'settings', format(avg(r.rating),2), pk_case_id
order by a.public_name, format(avg(r.rating),2), label_name desc
This is your group by clause:
group by a.public_name, 'settings', format(avg(r.rating),2), pk_case_id
The constant 'settings' is unnecessary (allowed but it doesn't do anything). The format(avg(r.rating),2) is causing the error. The clause can simply be:
group by a.public_name, pk_case_id
You are doing group by based on format(avg(r.rating),2) along with other columns even avg(r.rating) itself will be calculated based on either for whole table or based on group by, so you can't include a computed column in group by, which is not logical correct.
If it is your requirement then first you have to get avg(rating) in derived query based on productname and other required columns then you can join this derived table with your main table and you can include avg(rating) column also in group by clause along with other columns like productnames etc.
This is actually part of a Massive SQL query, but I had this code working, and now I cant seem to figure out why its not finding the last appointment record.
What I am trying to do is join all the other appointments onto themselves to find out which one is the last one. And all my results appear to be null. But this is not correct because my data definitely have appointments. So I think there is something wrong with my select query. Any help would be great.
SELECT `animal_id`,
FROM_UNIXTIME(`lastappointment`.`appointmentdata_starttime`,'%D %M %Y') AS 'Last Appointment'
FROM `animal`
LEFT JOIN (
SELECT `lAppointment`.*
FROM `appointment` AS `lAppointment`
LEFT JOIN `appointment` AS `nlAppointment`
ON `nlAppointment`.`appointmentdata_starttime` <= NOW()
AND `nlAppointment`.`appointmentdata_starttime` > `lAppointment`.`appointmentdata_starttime`
AND `nlAppointment`.`appointmentdata_animal` = `lAppointment`.`appointmentdata_animal`
WHERE `lAppointment`.`appointmentdata_starttime` <= NOW()
AND `nlAppointment`.`appointment_id` IS NULL
) AS `lastappointment`
ON `animal_id` = `lastappointment`.`appointmentdata_animal`
WHERE `animaldata_active` IS NOT NULL
GROUP BY animal_id;
Using LEFT JOINs to get the MAX() is the slowest method you can think of. I recommend you to change the inner query like this (using GROUP BY):
SELECT `animal_id`,
FROM_UNIXTIME(`lastappointment`.`last_appointment`, '%D %M %Y') AS 'Last Appointment'
FROM `animal`
LEFT JOIN (
SELECT MAX(appointmentdata_starttime) AS last_appointment,
appointmentdata_animal
FROM appointment
WHERE appointmentdata_starttime <= NOW()
GROUP BY appointmentdata_animal
) AS `lastappointment`
ON `animal_id` = `lastappointment`.`appointmentdata_animal`
WHERE `animaldata_active` IS NOT NULL
-- GROUP BY animal_id; --BTW, this group_by is not needed