I have created a select query which shows me the correct lines that I need to update:
SELECT `subject`,`ticket_messages`.`ticket_ID` as t,
(SELECT `date` from `ticket_messages` where `ticket_ID`=t ORDER BY `date` DESC LIMIT 1) as d
from `ticket_messages`
LEFT JOIN `tickets` on `ticket_messages`.`ticket_ID`=`tickets`.`ticket_ID`
GROUP BY t
HAVING d<date_sub(curdate(), interval 5 day)
ORDER BY t
I will be using php but working out the query first in phpmyadmin
Right the above query works and gives me the correct lines.
Basically it is listing anything over 5 days old. Don't worry that I am selecting subject and date, that was only so I knew I was getting the correct lines.
The question is how do I turn this into an update query?
It took me a few hours to get this working already.
What I will be updating is this:
UPDATE `tickets` SET `status`=?
Basically it will be looking in the ticket_messages and finding the last message. Which is what my select query does, and then it will update in my "tickets" table the status, if the last date is over 5 days old. The tables are referentially linked.
So I need an Update with a subquery, and I have no idea to go about this.
Ok going to add a bit more. I tried this
UPDATE `tickets` SET `status`=8
WHERE
(
SELECT `subject`,`ticket_messages`.`ticket_ID` as t,
(SELECT `date` from `ticket_messages` where `ticket_ID`=t ORDER BY `date` DESC LIMIT 1) as d
from `ticket_messages`
LEFT JOIN `tickets` on `ticket_messages`.`ticket_ID`=`tickets`.`ticket_ID`
GROUP BY t
HAVING d<date_sub(curdate(), interval 5 day)
ORDER BY t)!=null
I thought the where clause would work if it did not equal null.
Your first query, i don't like it because I really don't see why you use a subSelect, why you use a group by. What do you want for the date ?
Anyways you said you want only the tickets older than 5 days,
SELECT tm.ticket_ID, MAX(`date`) as d
FROM `ticket_messages` as tm
GROUP BY tm.ticket_ID
HAVING d < date_sub(curdate(), interval 5 day)
And that's all for you first query. Tell me if you get the same ID.
Now for the update, you just have to JOIN :
UPDATE `tickets`
INNER JOIN
(SELECT tm.ticket_ID, MAX(`date`) as d
FROM `ticket_messages` as tm
GROUP BY tm.ticket_ID
HAVING d < date_sub(curdate(), interval 5 day)) AS T
ON T.ticket_ID = `tickets`.ticket_ID
SET`status`=?
Related
I have been struggling with this problem for about month..
Have been searching and reading many posts, but still can't figure out, how to make this work..
Basically: I got 2 database tables fun_posts and fun_post_upvotes And I want to
SELECT *
FROM fun_posts
ORDER BY (HOTTEST POSTS(MOST UPVOTED THIS WEEK))
This is my latest code, that won't work
SELECT *
FROM fun_posts
ORDER BY (SELECT count(*), image_id, date
FROM fun_post_upvotes
GROUP BY image_id
ORDER BY DATE(date) > (NOW() - INTERVAL 7 DAY) DESC,
count(*) DESC,
date DESC)
If I divide this line into 2 different SELECT functions, they work. I can select simple posts and I can select upvotes count ordered like I want.
But If I make them into one line like that, I get following error:
#1241 - Operand should contain 1 column(s)
EDIT NR 1:
fun_posts table
fun_post_upvotes table
Problem with Answer that I checked:
Here, look how posts are ordered in my select function. (It selects like I want) 10->134->132->2->13
And here with given code (It selects image, but not in that order) 10->122->39->8->110
You can use a join to do this
SELECT fp.*, fpu.`cnt`
FROM fun_posts fp
LEFT JOIN ( SELECT image_id, COUNT(*) AS cnt
FROM fun_post_upvotes
WHERE `date` > (NOW() - INTERVAL 7 day)
GROUP BY image_id
) fpu ON ( fpu.image_id = fp.id )
ORDER BY fpu.cnt DESC, fp.`date` DESC, fp.`id` DESC;
It selects a list from fun_post_upvotes grouped by image_id and counts the amount of rows. That list is returned to the main query and matches (LEFT JOIN) on fp.id. The query will first show the item with the most upvotes in the past 7 days, than the least. If no upvotes are found, the result will still return them, but at the bottom in no specific order.
You can edit the order by, to obtain the items in the order you like.
Here a sqlfiddle.com
Have 3 Tables... Need to select users that haven't booked a lesson for the next week, and send an email.
Think I'm looking at
WHERE `LESSONS`.`DATE` > CURDATE()
AND `LESSONS`.`DATE` <= (CURDATE() + INTERVAL 7 DAY)
That works to select the range of dates... However I'm then having a problem joining that to the bookings to see if they have booked, and if they HAVEN'T then I need to grab their email address... I'd rather not use PHP to loop through and query data. I obviously just want to run the single query.
As you can probably tell I'm not in the know when it comes to MYSQL.
Help appreciated. Thanks.
USERS
-----------
ID | EMAIL, ETC
LESSONS
-----------
ID | DATE, ETC
BOOKINGS
-----------
ID | LESSON_ID | USER_ID, ETC
You can try something like
SELECT u.*
FROM USERS u LEFT JOIN
Bookings b ON u.ID = b.USER_ID LEFT JOIN
LESSONS l ON b.LESSON_ID = l.ID
AND l.DATE > CURDATE() AND l.DATE <= (CURDATE() + INTERVAL 7 DAY)
WHERE l.ID IS NULL
This should get all users that do not have any bookings for lessons for next week.
Have a look at Introduction to JOINs – Basic of JOINs
This is a nive visual representation of joins.
use in or exists?
SELECT users.* FROM users
WHERE users.id NOT IN
(SELECT Bookings.user_id FROM Bookings JOIN Lessons ON Bookings.lesson_id = lessons.id
WHERE lessons.date > CURDATE() AND lessons.date <= (CURDATE()+INTERVAL7 7 DAY)
There may be syntactical differences in MySQL opposed to SQL server, that I'm more familiar with.
I have a MySQL query with a calculated column in it.
For some reason on the first run, the query returns NULL in the calculated column.
On refresh (i.e. a second run), it returns the calculated value correctly.
How can I get rid of that lag?
Please see the query below:
SELECT #P0:=MAX(CASE WHEN t2.date IS NULL THEN t1.price ELSE NULL END),
#P1:=MAX(CASE WHEN t3.date IS NULL THEN t1.price ELSE NULL END),
ROUND(100*(#P1-#P0)/#P0,1) AS 'r1y'
/* The r1y above is the calculated column that is returned with lag*/
FROM (SELECT date, price FROM mytable
WHERE ticker='XYZ'
AND date>=#t1:=(SELECT DATE_SUB((SELECT MAX(date) FROM mytable),
INTERVAL 1 YEAR))) AS t1
LEFT OUTER JOIN (SELECT date FROM mytable
where ticker='XYZ'
AND date>=#t1) AS t2
ON (t1.date>t2.date)
LEFT OUTER JOIN (SELECT date FROM mytable
WHERE ticker='XYZ'
AND date>=#t1) AS t3
ON (t1.date<t3.date)
When I move the calculation of 'r1y' out of MySQL and into the PHP part of the code, there is no lag of course. Still, it would be good to have all the calculations in MySQL.
UPDATE
Here's the query that's easier and returns the same results with no lag (execution time is roughly the same):
SELECT
#d1:=(SELECT MAX(date) FROM mytable WHERE ticker='XYZ' AND current=1),
#d2:=(SELECT MIN(date) FROM mytable WHERE ticker='XYZ'
AND date>=DATE_SUB(#d1, INTERVAL 1 YEAR)),
#m1:=(SELECT price FROM mytable WHERE ticker='XYZ' AND date=#d1),
#m2:=(SELECT price FROM mytable WHERE ticker='XYZ' AND date=#d3),
ROUND(100*(#m1-#m2)/#m2, 1) as r1y
It would still be good to know the nature of the above mentioned lag, but this suggested solution works fine for me.
You are setting the value of #t1 here:
FROM (SELECT date, price
FROM mytable
WHERE ticker='XYZ' AND
date>=#t1:=(SELECT DATE_SUB((SELECT MAX(date) FROM mytable
), INTERVAL 1 YEAR
)
)
) AS t1
You are then using it in the subsequent subqueries.
SQL does not guarantee the join processing order. And neither does MySQL. The reason your query is not working the first time is because the first subquery is not being executed first.
Probably the simplest fix is to repeat the subquery in each part of the original query -- but be sure there is an index on date so it evaluates very quickly.
In one table I have
ID, PAGE_ID, DATE
Each time a page is loaded, the DATE, PAGE_ID [from the page table below] are loaded into the table above.
I am trying to calculate and sort pages by popularity. The page table contains:
ID [PAGE_ID], DESCRIPTION, DATE
I have no idea where to start.
select L.PAGE_ID, P.DESCRIPTION, count(L.ID) from LOADED_PAGE L
inner join PAGE P on P.ID = L.PAGE_ID
where L.DATE > :sevenDaysAgo
group by L.PAGE_ID, P.DESCRIPTION
order by count(L.ID) desc
will give you the list of loaded pages, from the most popular to the least one.
select
id_page,
count(*) as popularity
from table
where date >= curdate() - interval 7 day
group by id_page
order by popularity desc
I'm kind of new to SQL and I can't find the solution to my problem. I have two tables. In table A, I'm storing a lot of comments, each with a unique ID.
In table B, I'm storing every vote (like=1 and dislike=0) for every comment with a datetime. There will be an entry for every vote, so there will be tons of rows for each comment in table A.
I need to retrieve all the comments and sort them such that the weekly most liked comments are at the top, but I'm not sure how.
Here's what I have so far, but not sure how to continue:
SELECT * FROM comment INNER JOIN logs ON comment.c_id=logs.c_id WHERE logs.daterate >= DATE_SUB(CURDATE(), INTERVAL 8 DAY) AND logs.rated=1
To clarify, I need to get all entries from logs with rated = 1 in the past week and sort them by the most frequent c_id in descending order, and get distinct c_id for each row... if that makes sense
Please ask questions if I didn't make it clear enough, thanks!!
SELECT *
FROM comment
INNER JOIN (SELECT comment.c_id,
COUNT(*) AS cnt
FROM comment
INNER JOIN logs ON comment.c_id=logs.c_id
WHERE logs.daterate >= DATE_SUB(CURDATE(), INTERVAL 8 DAY)
AND logs.rated=1
GROUP BY comment.c_id) x ON x.c_id = comment.c_id
ORDER BY x.cnt DESC
Try this -
I have first queried all records from logs table which are rated 1 and are from 7 days from current date and also are ordered based on the count of c_id. Then joined this with the COmments table.
SELECT Comment.* FROM comment C
INNER JOIN (SELECT logs.c_id as c_id,count(logs.c_id) as logcount FROM logs
WHERE logs.rated=1
AND logs.daterate BETWEEN GETDATE() AND DATEADD(day,-7,getdate())
Group by logs.c_id
order by count(logs.c_id) desc) X
ON C.c_id = X.c_id
ORDER BY X.logcount DESC