I'm really blocked at an advanced query, if someone can help me
I have a table mysql that looks like:
customers(id, appointment_date1, appointment_date2, appointment_date3, appointment_date4)
I'm looking for a query that list me what is the next most recent appointment
Before I do this query :
SELECT CASE
WHEN (customers.appointment_date1 != '0000-00-00' AND DATE(customers.appointment_date1) >= CURDATE()) THEN customers.appointment_date1
WHEN (customers.appointment_date2 != '0000-00-00' AND DATE(customers.appointment_date2) >= CURDATE()) THEN customers.appointment_date2
WHEN (customers.appointment_date3 != '0000-00-00' AND DATE(customers.appointment_date3) >= CURDATE()) THEN customers.appointment_date3
WHEN (customers.appointment_date4 != '0000-00-00' AND DATE(customers.appointment_date4) >= CURDATE()) THEN customers.appointment_date4
END as appointment
ORDER BY appointment ASC
But it's wrong, it doesn't work correctly.
Anyone can help?
Thanks
I'd use nested mysql if() functions in select clause, like :
select *
from(
select if(date1<date2&&date1>curdate(),date1,
if(date2<date3&&date2>curdate(),date2,
if(date3>curdate(),date3, 'nothing')
)
) as date
from dates
) as dates
order by dates.date desc;
EDIT : as per Zika's comment
SELECT IF(LEAST(
IFNULL(date1,'0000-00-00'),
IFNULL(date2,'0000-00-00'),
IFNULL(date3,'0000-00-00')
)!='0000-00-00',
LEAST(
IFNULL(date1,'0000-00-00'),
IFNULL(date2,'0000-00-00'),
IFNULL(date3,'0000-00-00')
),
'aucune date'
)
FROM dates;
Related
I am trying to do what seems like a simple query.. I have a query which works fine until I try to add a subquery to the select clause. I am trying to add a column by querying a second table with the dates I get from the first. I don't know if a join might be better. If you look at my first sample it returns every record in my second table instead of using the date range from the outer select statement.
SELECT `sales`.`date` as 'newdate', `sales`.`material`,
`customer_logs`.`name`, `sales`.`billingqty` ,
(select count(*) from iis_logs where datetime > (select
Date_add(date_format(newdate, "%Y-%m-%d 00:00:00"), interval - 1 day))
and datetime < date_format(newdate, '%Y-%m-%d 00:00:00' and url like
CONCAT('%',material,'%') limit 1) as tr
FROM `sales`
JOIN `customer_logs` ON `customer_logs`.`customer_number` =
`sales`.`soldtopt`
WHERE `date` >= '2017-09-01'
AND `date` <= '2017-09-30'
ORDER BY `date` DESC
LIMIT 10;
If I just type the string as a date in like this it returns within a second:
SELECT `sales`.`date` as 'newdate', `sales`.`material`,
`customer_logs`.`name`, `sales`.`billingqty` ,
(select count(*) from iis_logs where datetime > '2017-09-01 00:00:00'
and datetime < '2017-09-03 00:00:00' and url like
CONCAT('%',material,'%') limit 1) as tr
FROM `sales`
JOIN `customer_logs` ON `customer_logs`.`customer_number` =
`sales`.`soldtopt`
WHERE `date` >= '2017-09-01'
AND `date` <= '2017-09-30'
ORDER BY `date` DESC
LIMIT 10;
It is not taking the value of newdate I am trying to get in select statement, instead it is returning every row in iis_logs table...
This looks like a perfect candidate for a join. FWIW, mysql query optimizer typically does better on joins that subqueries anyway.
Please could someone help me?
I am trying to get the last 10 winners for a photo of the month competition with most recent first excluding the current month, here is what I have so far:-
SELECT
*,
MAX(total_score)
FROM
comp_images
WHERE
date_added BETWEEN DATE_SUB(curdate(),Interval 10 Month) AND curdate()
AND
CONCAT(MONTH(curdate()),'',YEAR(curdate())) != CONCAT(MONTH(date_added),'',YEAR(date_added))
AND
url != ''
AND
hide = '0'
GROUP BY
MONTH(date_added)
ORDER BY
total_score DESC
LIMIT 10
Any help with would be greatly appreciated.
Thanks
My guess is you are getting all images back, with the max total score. The problem here is you are separately selecting all rows (with *) and the MAX(total_score) but have not bound them together.
What you could do to solve this is using the HAVING keyword of MySQL. You can give criteria to your select all rows statement. So for example:
SELECT * FROM comp_images..... HAVING MAX(total_score);
Just in case anyone else has the same issue here is the solution I found:
SELECT
* , CONCAT(MONTHNAME(date_added),' ',YEAR(date_added)) as win_month
FROM (select * from comp_images order by total_score desc) x
WHERE
date_added BETWEEN DATE_SUB(curdate(),Interval 10 Month) AND curdate()
AND
CONCAT(MONTH(curdate()),'',YEAR(curdate())) != CONCAT(MONTH(date_added),'',YEAR(date_added))
AND
url != ''
AND
hide = '0'
GROUP BY
MONTH(date_added)
LIMIT 10
After searching a while, I found no "good" solution to get the upcoming birthdays from a MySQL database with just one single select statement. I found many different strategies in the web but none of them worked really fine especially at the change of the year.
Now I want to share my final solution:
SELECT mem_id, mem_dateBirth, MONTH(mem_dateBirth), DAY(mem_dateBirth)
FROM rs_mem
WHERE mem_dateBirth IS NOT NULL AND
mem_dateBirth > '1900-01-01'
ORDER BY (date_format(NOW(), '%m%d') >= date_format(mem_dateBirth, '%m%d')),
date_format(mem_dateBirth, '%m%d');
The result will be a list with all the upcoming birthdays (also if the birthday is after the year change).
Your query is fine, here is another way to order your result using a CASE statement:
SELECT M.mem_id
, M.mem_dateBirth
, MONTH(mem_dateBirth) AS month
, DAY(mem_dateBirth) AS day
FROM rs_mem M
WHERE IFNULL(M.mem_dateBirth, '1900-01-01') > '1900-01-01'
ORDER BY CASE
WHEN DATE_FORMAT(M.mem_dateBirth, '%m%d') >= DATE_FORMAT(NOW(), '%m%d') THEN 1
ELSE 0
END DESC, date_format(mem_dateBirth, '%m%d');
I also modified your WHERE clause in order to make it shorter (use of IFNULL).
Hope this will help you.
MSSQL : TOP 10 is first 10 record, you can remove it for all records.
SELECT TOP 10 mem_id, mem_dateBirth, MONTH(mem_dateBirth), DAY(mem_dateBirth)
FROM rs_mem
WHERE mem_dateBirth IS NOT NULL AND
mem_dateBirth > '1900-01-01' AND
mem_dateBirth > DATE()
ORDER BY mem_dateBirth
MYSQL : limit 0,10 is first 10 record, you can remove it for all records.
SELECT mem_id, mem_dateBirth, MONTH(mem_dateBirth), DAY(mem_dateBirth)
FROM rs_mem
WHERE NOT isnull(mem_dateBirth) AND
mem_dateBirth > '1900-01-01' AND
mem_dateBirth > CURDATE()
ORDER BY mem_dateBirth limit 0,10
I'm try to use the result of a subquery in the query's WHERE clause. The attribute I am wishing to use is last_contact. See below.
SELECT forename, surname, type,
( SELECT MAX(completed_date)
FROM tblTasks
WHERE prospect_id = tblProspects.prospect_id AND completed = '1'
) AS last_contact,
created_at
FROM tblProspects
WHERE hidden != '1' AND type='Prospect' AND last_contact > DATE_ADD(CURDATE(), INTERVAL -90 DAY)
ORDER BY last_contact ASC
I get the SQL Error: #1054 - Unknown column 'last_contact' in 'where clause'
Any help would be greatly appreciated.
Thanks.
You need to use HAVING clause in order to refine your results by custom aliased coulmn they cannot be used in where clause
SELECT
forename,
surname,
type,
(SELECT MAX(completed_date) FROM tblTasks WHERE prospect_id = tblProspects.prospect_id AND completed = '1') AS last_contact,
created_at
FROM tblProspects
WHERE hidden != '1' AND type='Prospect'
HAVING (
last_contact > DATE_ADD(CURDATE(), INTERVAL -90 DAY)
OR last_contact IS NULL
)
ORDER BY last_contact ASC
In our database, instead of making empty dates NULL, they are '0000-00-00' (I know, it sucks). How can I order these so that dates that are not '0000-00-00' are first and ordered ASC, and then the empty dates of '0000-00-00' come after?
Thanks!
...
ORDER BY CASE WHEN YourDateColumn = '0000-00-00' THEN 2 ELSE 1 END,
YourDateColumn
Try Below :
SELECT * FROM your_table ORDER BY (date_column='0000-00-00'), date_column ASC
OR
select * from your_table
order by if(date_column='0000-00-00',1,0),date_column;
You can use a CASE WHEN
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
... ORDER BY (CASE WHEN date = '0000-00-00' THEN 1 ELSE 0 END) ASC, otherColumns asc, ...
ORDER BY (DateColumn = 0)
, DateColumn