Update mysql table using CASE subquery with limit - mysql

I want to run below query to update Vouchers table
UPDATE vouchers SET status = 6 WHERE voucher_id IN
(
select a.voucher_code from products a
JOIN order b ON a.order_id = b.id
WHERE a.voucher_code != '' LIMIT 10
)
but when running the query, I am getting below mysql error :
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Thanks in advance.

Try moving your subquery into an update join:
UPDATE vouchers v
INNER JOIN
(
SELECT a.voucher_code
FROM products a
INNER JOIN order b
ON a.order_id = b.id
WHERE a.voucher_code != ''
LIMIT 10
) t
ON v.voucher_id = t.voucher_code
SET v.status = 6;
LIMIT should be allowed in this case.

Related

1066 - Not unique table/alias:

Can you please help me out. I have this SQL query:
SELECT `a`.`UNIQ_CODE`, `b`.`JUDUL_BERITA`, `b`.`THUMNAIL`, `c`.`NAMA`,
`a`.`TAG`, `a`.`CREATED_DATE`, `a`.`GLOBAL`, `a`.`VERIFIKASI`
FROM (`q_master_berita` a)
JOIN `q_master_berita` a ON `b`.`UNIQ_CODE` = `a`.`UNIQ_CODE`
RIGHT JOIN `q_daftar_user` c ON `a`.`ID_UPLOADER` = `c`.`ID`
WHERE ( a.FLAG = 'DRAFT' AND a.ID_SEKOLAH = '3824' )
ORDER BY `b`.`JUDUL_BERITA` asc
LIMIT 10
And somehow it says
Not unique table/alias: 'a'
That's because you are using same alias a twice for table q_master_berita. You need to use different aliases.
SELECT `a`.`UNIQ_CODE`, `b`.`JUDUL_BERITA`, `b`.`THUMNAIL`, `c`.`NAMA`,
`a`.`TAG`, `a`.`CREATED_DATE`, `a`.`GLOBAL`, `a`.`VERIFIKASI`
FROM (`q_master_berita` a)
JOIN `q_master_berita` b ON `b`.`UNIQ_CODE` = `a`.`UNIQ_CODE`
RIGHT JOIN `q_daftar_user` c ON `a`.`ID_UPLOADER` = `c`.`ID`
WHERE ( a.FLAG = 'DRAFT' AND a.ID_SEKOLAH = '3824' )
ORDER BY `b`.`JUDUL_BERITA` asc
LIMIT 10

Join between sub-queries in SQLAlchemy

In relation to the answer I accepted for this post, SQL Group By and Limit issue, I need to figure out how to create that query using SQLAlchemy. For reference, the query I need to run is:
SELECT t.id, t.creation_time, c.id, c.creation_time
FROM (SELECT id, creation_time
FROM thread
ORDER BY creation_time DESC
LIMIT 5
) t
LEFT OUTER JOIN comment c ON c.thread_id = t.id
WHERE 3 >= (SELECT COUNT(1)
FROM comment c2
WHERE c.thread_id = c2.thread_id
AND c.creation_time <= c2.creation_time
)
I have the first half of the query, but I am struggling with the syntax for the WHERE clause and how to combine it with the JOIN. Any one have any suggestions?
Thanks!
EDIT: First attempt seems to mess up around the .filter() call:
c = aliased(Comment)
c2 = aliased(Comment)
subq = db.session.query(Thread.id).filter_by(topic_id=122098).order_by(Thread.creation_time.desc()).limit(2).offset(2).subquery('t')
subq2 = db.session.query(func.count(1).label("count")).filter(c.id==c2.id).subquery('z')
q = db.session.query(subq.c.id, c.id).outerjoin(c, c.thread_id==subq.c.id).filter(3 >= subq2.c.count)
this generates the following SQL:
SELECT t.id AS t_id, comment_1.id AS comment_1_id
FROM (SELECT count(1) AS count
FROM comment AS comment_1, comment AS comment_2
WHERE comment_1.id = comment_2.id) AS z, (SELECT thread.id AS id
FROM thread
WHERE thread.topic_id = :topic_id ORDER BY thread.creation_time DESC
LIMIT 2 OFFSET 2) AS t LEFT OUTER JOIN comment AS comment_1 ON comment_1.thread_id = t.id
WHERE z.count <= 3
Notice the sub-query ordering is incorrect, and subq2 somehow is selecting from comment twice. Manually fixing that gives the right results, I am just unsure of how to get SQLAlchemy to get it right.
Try this:
c = db.aliased(Comment, name='c')
c2 = db.aliased(Comment, name='c2')
sq = (db.session
.query(Thread.id, Thread.creation_time)
.order_by(Thread.creation_time.desc())
.limit(5)
).subquery(name='t')
sq2 = (
db.session.query(db.func.count(1))
.select_from(c2)
.filter(c.thread_id == c2.thread_id)
.filter(c.creation_time <= c2.creation_time)
.correlate(c)
.as_scalar()
)
q = (db.session
.query(
sq.c.id, sq.c.creation_time,
c.id, c.creation_time,
)
.outerjoin(c, c.thread_id == sq.c.id)
.filter(3 >= sq2)
)

how to join correlated subquery with outer table?

I have a query like this -
UPDATE ACTION a
INNER JOIN subscriberinfo s ON a.subscriberId = s.id AND a.subscriberId=118
INNER JOIN ticket t ON t.subscriberId = s.id AND s.id=118
SET a.exceedusage = (SELECT FORMAT(((SUM(dataVolumeDownLink + dataVolumeUpLink))/1048576),2)
FROM cdr c
WHERE c.msisdn =12424474969
AND c.msisdn = s.msisdn
AND c.eventDate>t.cdrEventDate
AND c.eventDate < a.actionTakenOn)
WHERE a.remark='Reason : Data limit crossed'
AND a.exceedusage IS NULL;
I want to update action tables column, am I doing something wrong in this query?
Please explain me with an example that how to perform such kind of update,if possible.
Please, use group by where aggregate function is there:
UPDATE ACTION a
INNER JOIN subscriberinfo s ON a.subscriberId=118
INNER JOIN ticket t ON s.id=118
SET a.exceedusage = (SELECT FORMAT(((SUM(dataVolumeDownLink + dataVolumeUpLink))/1048576),2)
FROM cdr c
WHERE c.msisdn =12424474969
AND c.eventDate>t.cdrEventDate
AND c.eventDate < a.actionTakenOn group by c.msisdn )
WHERE a.remark='Reason : Data limit crossed'
AND a.exceedusage IS NULL;

MySQL limit inside of the subquery produces error

I'm receiving:
[Err] 1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
While executing the following query:
UPDATE account.account
SET STATUS = 'BLOCK'
WHERE
id IN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY
log.`who`
HAVING
COUNT(log.who) > 2
LIMIT 10
);
Is there a posibility to rewrite this query so MySQL could execute it?
The solution is to join against a subquery rather than use an IN(). The INNER JOIN will only return rows in account matching ids from the limited subquery. It is then possible to do the UPDATE without a WHERE clause.
Update
account.account AS account
INNER JOIN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY log.`who`
HAVING COUNT(log.who) > 2
LIMIT 10
) subq ON account.id = subq.id
SET STATUS='BLOCK'
To verify the rows that would be modified, use a SELECT first:
SELECT
account.*
FROM
account.account
INNER JOIN (
SELECT
p.account_id
FROM
log.log
LEFT JOIN player.player p ON (p.id = log.who)
WHERE
vnum = 71054
AND how = 'BUY'
GROUP BY log.`who`
HAVING COUNT(log.who) > 2
LIMIT 10
) subq ON account.id = subq.id

MySQL sum of sub queries

I have quite a long query that is causing me some problems. For the first sub-query I keep getting the error: "MySQL server version for the right syntax to use near 'SELECT project.project_total_num_hours_quoted FROM project inner join time_recor' at line 5".
The subquery in question is:
sum(SELECT
project.project_total_num_hours_quoted
FROM
project inner join time_recording using(project_id)
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01' AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
group by project_id
) AS hours_quoted,
This returns a set of results. In the larger query I simply want to have the sum.
SELECT
SUM((unix_timestamp(time_recording.time_recording_event_stop_datetime)-unix_timestamp(time_recording.time_recording_event_start_datetime))/3600) AS total_time,
company.company_label,
sum(SELECT
project.project_total_num_hours_quoted
FROM
project inner join time_recording using(project_id)
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01' AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
group by project_id
) AS hours_quoted,
(SELECT SUM(project.project_total_num_hours_quoted)
FROM project
INNER JOIN time_recording ON project.project_id = time_recording.project_id
WHERE time_recording.time_recording_event_start_datetime>='2011-01-01'
AND project_is_retainer!=1
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
AND project.company_id!=1
) AS total_hours_quoted,
(
SELECT
SUM((unix_timestamp(time_recording.time_recording_event_stop_datetime)-unix_timestamp(time_recording.time_recording_event_start_datetime))/3600)
FROM time_recording
INNER JOIN project ON time_recording.project_id = project.project_id
WHERE project.company_id!=1
AND project_is_retainer!=1
AND time_recording.time_recording_event_start_datetime>='2011-01-01'
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
)
AS total_hours
FROM time_recording
INNER JOIN project ON time_recording.project_id = project.project_id
INNER JOIN company ON project.company_id = company.company_id
WHERE company.company_id!=1
AND project_is_retainer!=1
AND time_recording.time_recording_event_start_datetime>='2011-01-01'
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
GROUP BY company.company_id
ORDER BY total_time desc
LIMIT 7
In your first subquery, you don't need the group by if you sum it in the outer query. And you are missing the ON clause.
SELECT project.project_total_num_hours_quoted
FROM project inner join time_recording
ON project.id=time_recording.project_id
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01'
AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
I would strongly recommend scrapping this and starting again.
Several, if not all, the subselects could be merged into a single SELECT statement. The outer SELECT is an aggregate operation which selects non-aggregated values not included in the GROUP BY clause. MySQL does not optimize push-predicates. And you've got redundant joins in the query.