I am looking for how many number of columns I can use in "order by" clause, for e.g. I have a column NAME asc, START_DATE asc, SKU_GROUP asc and want to add SKU_NAME asc in order clause. I am currently using 1 group by but for curiosity how many can be used within MySQL?
SELECT pop.SUB_ELEMENT, pop.NAME, sub_element.LDESC AS SUB_NAME, DATE_FORMAT(journey_visits.START_DATE, '%b %d %Y %h:%i %p' ) AS START_DATE, visit_sku.IS_CHECK,visit_sku.TYPE AS `SKU_TYPE`,brand.LDESC AS `SKU_GROUP`,sku.LDESC AS `SKU_NAME`,sku.SKU AS `MATERIAL` FROM visit_sku
LEFT JOIN journey_visits ON journey_visits.VISIT_ID = visit_sku.VISIT_ID
LEFT JOIN pop ON journey_visits.POP_ID = pop.POPID
LEFT JOIN sub_element ON sub_element.SubElementID=pop.SUB_ELEMENT
LEFT JOIN sku ON visit_sku.SKU_ID = visit_sku.SKU_ID AND visit_sku.SKU_ID = sku.SKU
LEFT JOIN brand ON sku.brandid = brand.BRANDID
WHERE DATE(journey_visits.START_DATE) BETWEEN '2016-04-01' AND '2016-04-03'
ORDER BY NAME, START_DATE, SKU_NAME
There is no limit, you can order by or group by all columns in a result set, although the latter would be useless.
Related
I am trying to do a regular join but select the latest entry from the history_items table using a where clause.
SELECT h.history_id,
Date_format(From_unixtime(h.timestamp), '%d %m %Y') AS 'date',
h.status,
h.product_id,
p.serial_number,
p.product_name,
p.site_name,
p.site_postcode,
Date_format(From_unixtime(i.timestamp), '%d %m %Y') AS 'last_update',
i.feedback
FROM history h
LEFT JOIN products p
ON h.product_id = p.product_id
LEFT JOIN history_items i
ON h.history_id = i.history_id
WHERE i.timestamp = (SELECT Max(i.timestamp)
FROM history_items)
GROUP BY i.history_id
ORDER BY h.timestamp DESC
I am selecting Max(i.timestamp) - this is still not returning the latest entry from the history_items table.
I think your problem is here:
WHERE i.timestamp = (SELECT Max(i.timestamp)
FROM history_items)
The i should not be there, it should be Max(timestamp) not Max(i.timestamp).
Else Mysql will really select the value of the i.timestamp row. So if your timestamp is 1 it will evaluate to this:
WHERE 1 =(SELECT Max(1) FROM hsitory_items)
Which basically will be
WHERE i.timestamp = i.timestamp
I bet you get the idea now. That's why all rows are returned.
Since you are anyways sorting on timestamp saying ORDER BY h.timestamp DESC you actually don't need the below pointed WHERE condition at all. Also the subquery in below pointed code is wrongly referring the column as already mentioned in other answer
WHERE i.timestamp = (SELECT Max(i.timestamp)
FROM history_items)
Good day! I want to add fields "duration and dials"
Here is my mysql query:
select
u.dialer_display_name,
u.dialer_ext,
sum(dl.duration/60) as duration,
count(dl.dial_id) as dials
from leads.dial_log as dl
left join leads.users as u on u.user_id=dl.user_id
where date(dl.dial_date) = date(now())
and u.dialer_display_name != ''
group by dl.user_id order by dials DESC
So what I want to achieve is to add duration and dials and alias them as mets.
Something like:
select sum(duration+dials) as mets
How to build the query? Thanks!
Just add the two terms making the respective columns:
SELECT u.dialer_display_name,
u.dialer_ext,
SUM(dl.duration/60) AS duration,
COUNT(dl.dial_id) AS dials,
SUM(dl.duration/60) + COUNT(dl.dial_id) AS mets -- here is your column
FROM leads.dial_log AS dl
LEFT JOIN leads.users AS u
ON u.user_id = dl.user_id
WHERE DATE(dl.dial_date) = DATE(NOW()) AND
u.dialer_display_name != ''
GROUP BY dl.user_id
ORDER BY dials DESC
You need to repeat the logic, because you cannot re-use the aliases:
select u.dialer_display_name, u.dialer_ext,
sum(dl.duration/60) as duration,
count(dl.dial_id) as dials,
(sum(dl.duration/60) + count(dl.dial_id) ) as mets
from leads.dial_log dl join
leads.users u
on u.user_id = dl.user_id
where dl.dial_date >= curdate() and
dl.dial_date < date_add(curdate(), interval 1 day) and
u.dialer_display_name <> ''
group by u.dialer_display_name, u.dialer_ext
order by dials DESC;
Notes:
The comparison in the where using date() has been replaced with two comparisons. This allows the use of an index (if available).
date(now()) has been replaced with curdate().
The group by has been modified to match the columns in the select.
The left join has been replaced with an inner join. The where clause undoes the left join, so don't be misleading.
The new column has been added.
I will also say that count(dl.dial_id) seems strange. I suspect you want one of the following:
count(distinct dl.dial_id)
count(*)
SELECt
qst_id,qst_title,ans_date,ans_text
FROM
(
SELECT
a.Question_Id as qst_id,a.Question_Title as qst_title,a.Question_Text as qst_text,DATE_FORMAT(a.LastActivity_Date,'%d %b %Y %T') as qst_date,b.UserForum_Image as qst_prof,b.ScreenName as qst_scname
FROM
tblforumquestion a, tblregistration2_2 b
WHERE a.RegistrationId=b.RegistrationId and a.LastActivity_Date between '2014-0-01 00:00:00' and '2015-05-01 00:00:00'
ORDER BY a.LastActivity_Date desc limit 5
outer join
SELECT
DATE_FORMAT(c.Answer_Date,'%d %b %Y %T') as ans_date,c.Answer_Text as ans_text,d.UserForum_Image as ans_prof,d.ScreenName as ans_scname
FROM
tblforumanswer c ,tblregistration2_2 d
where c.Answer_Id in
(
SELECT MAX(Answer_Id)
FROM tblforumanswer
GROUP BY Question_Id
)
and c.RegistrationId=d.RegistrationId
order by c.Answer_Date desc limit 5
)
I am trying to get latest 5 question and answers from my post.if any question without answer is there,it should also display as question details in one row with null answer details.But the above code is getting error.Any help is appreciable.my database is mysql.
tblquest
tblans
result
I think we've finally extracted enough detail to arrive at an answer:
select q.qstid, q.qsttext, a.anstext
from tblquest q
left join tblans a
on q.qstid = a.qstid
left join tblans a2
on a.qstid = a2.qstid and a.ansdate < a2.ansdate
where a2.ansdate is null
order by q.qdate desc limit 5;
demo here
We left join the answers to the questions, in order to ensure we have keep all questions, including those without answers.
We then left join to the answers again, but this time on a range condition in order to just pick off the most recent answer to the question. If there is no a2 with a date greater than a, then that a must be the most recent answer - this is filtered for by the where a2.ansdate is null clause.
That could also be accomplished with a subquery if you preferred.
Finally, we just order and limit our results in order to get the 5 most recent questions.
Problem with your outer join syntax. Check the comment and sample data.
SELECT
qst_id,qst_title,ans_date,ans_text
FROM
(
SELECT
a.Question_Id as qst_id,a.Question_Title as qst_title,a.Question_Text as qst_text,DATE_FORMAT(a.LastActivity_Date,'%d %b %Y %T') as qst_date,b.UserForum_Image as qst_prof,b.ScreenName as qst_scname
FROM
tblforumquestion a, tblregistration2_2 b
WHERE a.RegistrationId=b.RegistrationId and a.LastActivity_Date between '2014-0-01 00:00:00' and '2015-05-01 00:00:00'
ORDER BY a.LastActivity_Date desc limit 5
outer join --Error comes here
SELECT
DATE_FORMAT(c.Answer_Date,'%d %b %Y %T') as ans_date,c.Answer_Text as ans_text,d.UserForum_Image as ans_prof,d.ScreenName as ans_scname
FROM
tblforumanswer c ,tblregistration2_2 d
where c.Answer_Id in
(
SELECT MAX(Answer_Id)
FROM tblforumanswer
GROUP BY Question_Id
)
and c.RegistrationId=d.RegistrationId
order by c.Answer_Date desc limit 5
)
--This is example of outer join
SELECT
A.*, B.*
FROM
TableA a outer join TableB b on a.RegistrationId = b.RegistrationId
Refer link for more detail:
Full Outer Join in MySQL
https://dev.mysql.com/doc/refman/5.0/en/outer-join-simplification.html
http://www.w3schools.com/sql/sql_join_full.asp
SELECT
GROUP_CONCAT(CONCAT(user_firstname,' ', user_lastname)) fullname,
workour_day,
GROUP_CONCAT(distinct timetable_start) starttime,
GROUP_CONCAT(timetable_end) endtime
FROM doctors_timetable
INNER JOIN doctors ON user_id = doctor_id
INNER JOIN workours ON timetable_day = workour_id GROUP BY workour_day
ORDER BY timetable_id ASC
before Thursday everything works good and than it's mixing:
http://s24.postimg.org/w827dxclh/Capture.png
MYSQL results order is mixing. How can I fix it?
As what i understand from your comment you need the starttime and endtitme values to be in ascending order if thats the case you can use ORDER BY in GROUP_CONCAT to tell in what order to concatenate values
SELECT
GROUP_CONCAT(CONCAT(user_firstname,' ', user_lastname)) fullname,
workour_day,
GROUP_CONCAT(distinct timetable_start ORDER BY timetable_start ASC) starttime,
GROUP_CONCAT(timetable_end ORDER BY timetable_end) endtime
FROM doctors_timetable
INNER JOIN doctors ON user_id = doctor_id
INNER JOIN workours ON timetable_day = workour_id
GROUP BY workour_day
ORDER BY timetable_id ASC
Note you are using GROUP_CONCAT function which has a default limit of 1024 characters set by default,if your output exceeds this limit the result will be truncated to increase the limit you can see steps mentioned in the manual
timetable_id is still a mystery, but it's what you're ordering by. Order by starttime, endtime if you want to enforce ordering on those.
I need to perform a sort before the GROUP BY clause, but MySQL does not want to cooperate.
SELECT `article`, `date`, `aip`
FROM `official_prices`
WHERE `article` = 2003
GROUP BY `article`
ORDER BY `date` ASC
The row that should be picked is the one with the earliest date (2013-07-15) but instead it picks the date that comes first in table order. Changing to DESC does no difference.
First image shows both rows, ungrouped. Second image is them being grouped.
This table is being joined to by a main query, so (I think) any solutions involving LIMIT 1 won't be useful to me.
Full query:
SELECT `articles`.*, `official_prices`.`aip`
FROM `articles`
LEFT JOIN `official_prices`
ON (`official_prices`.`article` = `articles`.`id`)
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `official_prices`.`date` ASC, `articles`.`name`
You can't use group by and order like that. The order will only apply to the complete record set being returned and not in the group itself. This will work:
select o1.*
from official_prices o1
inner join
(
SELECT `article`, min(`date`) as mdate
from `official_prices`
WHERE `article` = 2003
GROUP BY `article`
) o2 on o1.article = o2.article and o1.date = o2.mdate
What you are trying to do is simply incorrect. The ordering before the group by does not have a (guaranteed) effect on the results.
My guess is that you want to get the most recent date and aip for that date. Here is a better approach:
SELECT `article`, max(`date`),
substring_index(group_concat(`aip` order by date desc), ',', 1) as lastAip
FROM `official_prices`
WHERE `article` = 2003
GROUP BY `article`;
The only downside is that the group_concat() will convert any value to a string. If it is some other type (and a string poses problems), then convert it back to the desired type.
Actually, an even better approach is to skip the group by entirely, because you are already filtering down to one article:
select article, `date`, aip
from official_prices
where article = 2003
order by `date` desc
limit 1;
The first approach works for multiple articles.
EDIT:
Your full query is:
SELECT `articles`.*, `official_prices`.`aip`
FROM `articles` LEFT JOIN
`official_prices`
ON `official_prices`.`article` = `articles`.`id`
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `official_prices`.`date` ASC, `articles`.`name`;
You are looking for more than one article, so the second approach won't work. So, use the first:
SELECT `articles`.*,
substring_index(group_concat(`official_prices`.`aip` order by `official_prices`.`date` desc),
',', 1) as lastAIP
FROM `articles` LEFT JOIN
`official_prices`
ON `official_prices`.`article` = `articles`.`id`
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `articles`.`name`;