When I try this query:
SELECT *
FROM sds_posts
WHERE topic_id = '2439'
AND author = ANY (SELECT mid
FROM sds_actions
WHERE whoami = '710' AND type = 'block')
AND status = '1'
AND deleted = '0'
ORDER BY
id ASC
LIMIT 50
it is working correctly.
But I need this one:
SELECT *
FROM sds_posts
WHERE topic_id = '2439'
AND author <> ANY (SELECT mid
FROM sds_actions
WHERE whoami = '710' AND type = 'block')
AND status = '1'
AND deleted = '0'
ORDER BY
id ASC
LIMIT 50
This time query have to select opposite of first query, but it is just select all author. I tried != and also NOT IN, but result is same.
So why? Why does <> not work as expected?
I would think that changing
and author = any...
to
and NOT author = any...
would work... But if that does not, then I would try doing as a left-join and looking for null. Since the author is the "mid" from the sds_actions, I would write it as...
SELECT
sp.*
FROM
sds_posts sp
LEFT JOIN sds_actions sa
on sp.author = sa.mid
AND sa.whoami = '710'
AND sa.type = 'block'
WHERE
sp.topic_id = '2439'
AND sp.status = '1'
AND sp.deleted = '0'
AND sa.mid IS NULL
ORDER by
sp.id ASC
LIMIT 50
You can try change author = any(...) to author IN (...)
and change author <> any(...) to author NOT IN (...)
Related
I am working on a project where I need to update 2 tables in a query.
I am doing this
UPDATE ward_beds a, ipd_patient_list b
SET
a.occupation_status = 'empty',
b.patient_status = 'Discharged'
WHERE
a.ward_id = b.ward_id AND b.patient_id = '4'
AND
b.appointment_id = '6' AND b.ward_id = '1'
so far it is working, now I want to update this
b.patient_status = 'Discharged'
on the row which is the last in all matching rows. I tried to put this
ORDER BY b.row_id DESC LIMIT 1
but it shows
#1221 - Incorrect usage of UPDATE and ORDER BY
error. How should I do it?
You can't use limit in this kind of update
but you could seach for the correct id using a subquery and join to the others tables
UPDATE ward_beds a
INNER JOIN (
select ward_id, max(row_id) last_id
from ipd_patient_list
group by ward_id
) t on t.ward_id = a.ward_id
INNER JOIN ipd_patient_list b ON a.ward_id = b.ward_id
AND b.patient_id = '4'
AND b.appointment_id = '6'
AND b.ward_id = '1'
AND b.row_id = t.last_id
SET a.occupation_status = 'empty',
b.patient_status = 'Discharged'
Here is my query:
SELECT *
FROM messages
WHERE status = 1
AND (
poster IN (SELECT thing FROM follows WHERE follower = :uid AND type = 3)
OR
topic_id IN (SELECT thing FROM follows WHERE follower = :uid AND type = 1)
)
ORDER BY post_date DESC LIMIT 0, 20
I want to know which clause the rows come from. From the poster IN (...) part or the topic_id IN (...) part? How can I do that?
A straightforward way:
SELECT *
, CASE WHEN poster IN (SELECT thing FROM follows WHERE follower = :uid AND type = 3) THEN 'poster'
ELSE 'topic_id' END AS from_clause
FROM messages <..>
Another way :
SELECT m.*
, CASE WHEN t1.thing IS NULL THEN 'topic_id' ELSE `poster` END AS from_clause
FROM messages m
LEFT JOIN (SELECT thing FROM follows WHERE follower = :uid AND type = 3) t1 ON m.poster = t1.thing
LEFT JOIN (SELECT thing FROM follows WHERE follower = :uid AND type = 1) t2 ON m.topic_id = t2.thing
WHERE m.status = 1 AND (t1.thing IS NOT NULL OR t2.thing IS NOT NULL)
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)
)
I currently have the following queries (and some surrounding vB code). I was hoping I could slim this up into a single SELECT statement versus having to run 10 more on each page to get that names of individuals.
$results = $db->query_read_slave("
SELECT user.id AS steam, user.skills AS level
FROM wcsp.wcgousers AS user
WHERE race = '_wcs_'
ORDER BY ABS(user.skills) DESC LIMIT 10
");
$rank = 1;
while ($user = $db->fetch_array($results)) {
$result = $db->query_first("
SELECT old.name AS name
FROM wcsp.warn_oldnames AS old
WHERE id = '$user[steam]'
ORDER BY lasttime
DESC LIMIT 1
");
$listing[] = array("id" => $user['steam'], "level" => $user['level'], "name" => $result['name'], "rank" => $rank);
$rank += 1;
}
I have tried LEFT JOIN but the issue I run into is that I would need a subquery in the LEFT JOIN similar to:
SELECT user.id AS steam, user.skills AS level, names.name AS name
FROM wcsp.wcgousers AS users
LEFT JOIN
(
SELECT names.name
FROM wcsp.warn_oldnames AS names
WHERE id = wcsp.wcgousers.id
ORDER BY lasttime DESC LIMIT 1
) AS names
ON names.id = users.id
WHERE users.race = '_wcs_'
Which won't work due to the different database check inside the subquery.
If I understand you correctly, you want to get the latest Name for every users.
SELECT a.id AS steam,
a.skills AS level,
b.name
FROM wcgousers a
INNER JOIN warn_oldnames b
ON a.ID = b.ID
INNER JOIN
(
SELECT ID, MAX(lasttime) max_date
FROM warn_oldnames
GROUP BY ID
) c ON b.ID = c.ID AND
b.lastTime = c.max_date
WHERE a.race = '_wcs_'
-- ORDER BY ABS(a.skills) DESC
-- LIMIT 10
I have this MySQL Query (working)
First query:
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
SELECT *
FROM user_counter
WHERE users.id = user_counter.publisher_id
)
The MySQL query above is to find the user id from two table
Now I want to compared again using this second MySQL query (working)
Second query:
SELECT users.id, publisher_amount, publisher_now, publisher_max, counter
FROM users
INNER JOIN user_counter ON users.id = user_counter.publisher_id
WHERE no = 08123456789
AND counter < publisher_amount
But when I join all the query like this:
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
SELECT *
FROM user_counter
WHERE users.id = user_counter.publisher_id
)
AND (
SELECT users.id, publisher_amount, publisher_now, publisher_max, counter
FROM users
INNER JOIN user_counter ON users.id = user_counter.publisher_id
WHERE no =08123456789
AND counter < publisher_amount
)
I get this error:
Operand should contain 1 column(s)
Then, I try using 1 column, but the result is not what I wanted.
My question is How to join first and second query ? and produce no error.
I have tried google it and after many "try-and-error" this is the far I can get to make the query work.
I think you just miss an EXISTS on your second subquery. Anyway, if I understand your query correctly, I think you could write your query as this:
SELECT
u.id
FROM
users u inner join user_counter uc
on u.id=uc.publisher_id
and no=08123456789
and counter < publisher_amount
WHERE
u.publisher_set = '1'
AND u.publisher_status = '1'
AND u.publisher_content != ''
AND u.publisher_amount != '0'
AND u.publisher_now < publisher_max
You could change the first EXISTS clause to:
and users.id in (select user_counter.publisher_id from user_counter)
and use EXISTS on the final query.
You could also do this:
AND EXISTS (
SELECT user_counter.publisher_id
FROM user_counter
WHERE users.id = user_counter.publisher_id
PS: SQLFIDDLE doesn't work in my end for some reason. Else would have been happy to give you a demonstration ;)
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
select 1 from user_counter where users.id = user_counter.publisher_id
and no =08123456789
AND counter < publisher_amount
)
Assuming no and counter are on table user_counter. A bit hard to tell without a schema.