MySQL Query Deletion - mysql

I want to delete records from tbl_Billing and I want to use LIMIT while performing this function. Please suggest if it's possible using INNER JOIN or LEFT JOIN. The query is below
DELETE
FROM tbl_Billing
WHERE `aCreated` > '2011-01-09'
AND `aStatus` ='2'
AND `aUserUnique`
IN (
SELECT aUserUnique
FROM tbl_Users AS user
WHERE user.`aBillingRenew` < date_sub( now( ) , INTERVAL 60 DAY )
AND user.aActive =1
)

I got the answer. We have to use EXISTS instead of the IN operator:
DELETE
FROM tbl_Billing
WHERE `aCreated` > '2011-01-09'
AND `aStatus` ='2'
AND EXISTS
(
SELECT aUserUnique
FROM tbl_Users AS users
WHERE users.`aBillingRenew` < date_sub( now( ) , INTERVAL 60 DAY )
AND users.aActive ='1'
)
limit 10

Related

Inaccurate New User Query

SELECT COUNT( uid ) AS `Records` , DATE( FROM_UNIXTIME( 'since` ) ) AS `Date`
FROM `accounts` WHERE FROM_UNIXTIME(since) >= FROM_UNIXTIME($tstamp)
GROUP BY WEEK( FROM_UNIXTIME( `since` ) )
LIMIT 200
Was using this to try to get the New user signups daily from a specified date but its turning out to be incredibly inaccurate. Which means either my query is off or possibly there is some issue involving timezones?Below is a example result I got from a example data set I loaded in as well as a page worth of timestamps so you can see what the results should be.
It is suggested to use HAVING instead of WHERE with GROUP BY clause.
Also the backtick(`) operator is not used properly in this code.
So change this query:
SELECT COUNT( uid ) AS Records , DATE( FROM_UNIXTIME( 'since` ) ) AS `Date`
FROM `accounts` WHERE FROM_UNIXTIME(since) >= FROM_UNIXTIME($tstamp)
GROUP BY DATE( FROM_UNIXTIME( `since` ) )
LIMIT 200
to this one:
SELECT COUNT(`uid`) AS Records , DATE( FROM_UNIXTIME(`since`) ) AS Date
FROM accounts
GROUP BY DATE( FROM_UNIXTIME( `since` ) )
HAVING FROM_UNIXTIME(`since`) >= FROM_UNIXTIME($tstamp)
LIMIT 200

MySQL Distinct Active Users for the last month query

Alright I have tried alot and this looks just about right for me , but its def not:
SELECT COUNT( DISTINCT 'uid' ) AS `Records` , DATE( FROM_UNIXTIME( `epoch_timestamp` ) ) AS `Date`
FROM `log`
GROUP BY DATE( FROM_UNIXTIME( `epoch_timestamp` ) )
LIMIT 0 , 30
For w.e reason it returns a 1 next to each date. If I take out the distinct it appears to give a total records for that day count.
Seems like your sql is incorrect, try replacing the single quotation marks around 'uid' with `.
SELECT COUNT( DISTINCT `uid` ) AS `Records` , DATE( FROM_UNIXTIME( `epoch_timestamp` ) ) AS `Date`
FROM `log`
GROUP BY DATE( FROM_UNIXTIME( `epoch_timestamp` ) )
LIMIT 0 , 30

MySQL Update with same table subquery

I have a table (EMP_ID, START_DATE, END_DATE) that contains a series of date ranges. What I want to do is ensure that they are all contiguous, so the END_DATE should be one less than the next START_DATE for any given EMP_ID.
I have the following query that lets me identify the records that are not contiguous:
SELECT H.EMP_ID,
H.START_DATE,
H.END_DATE,
DATE(
( SELECT MIN(START_DATE)
FROM TSRHierarchy I
WHERE I.START_DATE > H.START_DATE
AND I.EMP_ID = H.EMP_ID
)
) AS NEXT_DATE
FROM TSRHierarchy H
HAVING END_DATE <> DATE_ADD(NEXT_DATE, INTERVAL -1 DAY)
ORDER BY H.EMP_ID, H.START_DATE;
What I can't do is figure out how to turn this into an UPDATE statement? The MySQL documentation states 'Currently, you cannot update a table and select from the same table in a subquery.' which may be part of my problem.
Any suggestions for a work-around?
Try this UPDATE query using JOIN
UPDATE TSRHierarchy t
JOIN
( SELECT H.EMP_ID,
H.START_DATE,
H.END_DATE,
DATE((SELECT MIN(START_DATE)
FROM TSRHierarchy I
WHERE I.START_DATE > H.START_DATE
AND I.EMP_ID = H.EMP_ID
)) AS NEXT_DATE
FROM TSRHierarchy H
HAVING END_DATE <> DATE_ADD(NEXT_DATE, INTERVAL -1 DAY)
) AS t2
ON t.EMP_ID = t2.EMP_ID
SET t.END_DATE = t2.NEXT_DATE

MySQL join with AVG calculation

Is this possible?
I have a table which stores articles
I have another table which stores users ratings of the articles, each row is a rating which references the article
I want to get the average rating score for articles in the past 30 days:
SELECT `ex`.`article_id` , `ex`.`date` , `ex`.`title` , `r`.AVG(`rating`)
FROM `exclusive` `ex`
JOIN `ratings` `r` ON `ex`.`article_id` = `r`.`article_id`
WHERE `ex`.`date` > NOW( ) - INTERVAL 30 DAY
As you can see I'm trying to reference the 'rating' with the AVG function which is causing the issue. I think the issue is that the rating needs to be calculated before the select is made some I'm beginning to doubt if it's possible?
You have to indicate how the data should be grouped, to indicate which groups to use for the average calculation, e.g.:
SELECT `ex`.`article_id` , `ex`.`title` , AVG(r.rating)
FROM `exclusive` `ex`
JOIN `ratings` `r` ON `ex`.`article_id` = `r`.`article_id`
WHERE `ex`.`date` > NOW( ) - INTERVAL 30 DAY
GROUP BY ex.article_id
Keep in mind that in order to average the rating you should aggregate itÅ› dimensions, mainly by date, say grouping the last 30 days as you request, but to do so you should avoid aggregating by each review (title) and each date. Try this:
SELECT `ex`.`article_id` , AVG( case when `ex`.`date` ` > NOW( ) - INTERVAL 30 DAY
then `r`.`rating` else 0 end) as 30_day_rating_average FROM `exclusive` `ex` JOIN `ratings` `r` ON `ex`.`article_id` = `r`.`article_id` group by 1
You can also get a column with article name, instead of just article id.
Your syntax is a little off:
Change
..., r.AVG(rating)
To
..., AVG(r.rating)
And add a group by clause at the end of your query:
...
GROUP BY 1, 2, 3
It should look like:
SELECT `ex`.`article_id` , `ex`.`date` , `ex`.`title` , AVG(`r`.`rating`)
FROM `exclusive` `ex`
JOIN `ratings` `r` ON `ex`.`article_id` = `r`.`article_id`
WHERE `ex`.`date` > NOW( ) - INTERVAL 30 DAY
GROUP BY 1, 2, 3

MySQL Specialists: Delete all rows older than x days but not the latest one

first of all, this is the query which creates the "player history"
it can be executed as often as you want and it will only create new history rows for the players if there is no history row for yesterday or if the values changed since the latest history entry in the past.
INSERT INTO `player_history` (`player_id`, `date`, `races`, `maps`, `playtime`, `points`)
SELECT `p`.`id`, DATE_SUB(NOW(), INTERVAL 1 DAY), `p`.`races`, `p`.`maps`, `p`.`playtime`, `p`.`points`
FROM `player` `p`
WHERE `p`.`playtime` IS NOT NULL
AND `p`.`playtime` > 0
AND (
SELECT `player_id`
FROM `player_history`^
WHERE `player_id` = `p`.`id`
AND (
`date` = DATE_SUB(NOW(), INTERVAL 1 DAY)
OR (
`date` < DATE_SUB(NOW(), INTERVAL 1 DAY)
AND `races` = `p`.`races`
AND `points` = `p`.`points`
AND `maps` = `p`.`maps`
AND `playtime` = `p`.`playtime`
)
)
ORDER BY `date` DESC
LIMIT 1
) IS NULL;
now the problem is i also want to cleanup the history table using a single query. this already selects all history entries older than 10 days but the latest. but i cant just like do DELETE instead of SELECT *.
SELECT *
FROM `player_history` `ph`
WHERE `date` < DATE_SUB(NOW(), INTERVAL 10 DAY)
AND `date` != (SELECT `date`
FROM `player_history`
WHERE `player_id` = `ph`.`player_id`
ORDER BY `date` DESC
LIMIT 1);
so is tehre a way to do what i want using a single delete query?
Your query looks right in my eyes but you don't have the interval in the subquery.
I would do this:
DELETE FROM player_history
WHERE date < DATE_SUB(NOW(), INTERVAL 10 DAY)
AND date != (
SELECT MAX(date) FROM player_history
WHERE date < DATE_SUB(NOW(), INTERVAL 10 DAY)
)
What's the error message from mysql?
Probably you can't do this in a single query because the documentation states:
Currently, you cannot delete from a table and select from the same table in a subquery.
As a workaround you could select the ids of the rows that have to be deleted into a temporary table and then use a multi-table delete statement to delete the records from the original table.