I use a MySQL variable that got incremented conditionally per row. This variable is only required for the HAVING
clause, but by force also selected for incrementation.
Is it possible to increment the variable for each row without selecting it value back to the client?
The VBulletin forum software stores thread replys in a post
table with a column visible
. 0 means waiting for unlock, 1 visible and 2 soft deleted. I'm working on a MySQL query that fetches the posts of a page (typical 10). Users should only see posts with visible = 1
but moderators also the others.
First I want to filter based on usergroup. But this would make up my paging chaotic since a post could be on e.g. page 2 for guests, where it is on page 3 for moderators since deleted/not approved posts exists before this page.
For this reason, my concept is to select all post ids and limit only the ones to 10 per page where visible = 1
. If the first page contains 10 visible posts and 2 deleted posts, then mods would get 12 posts and regular users only 10. But paging is the same for both, since deleted posts doesn't change it.
Inspirated from this question I build the following query:
SET @visible_sum = 0;
SELECT postid, visible, @visible_sum := @visible_sum + IF(visible = 1, 1, 0)
FROM post
WHERE threadid = 38325
GROUP BY postid
HAVING @visible_sum < 10
ORDER BY dateline;
As you can see, I get 10 non deleted posts and additionally 4 deleted ones (highlighted). With less modifications, this query can be re-used for non moderative users:
SELECT postid, visible, @visible_sum := @visible_sum + 1
...
HAVING @visible_sum < 10 AND visible = 1
So this generally works as required. But I don't like the fact that I always get the counter. Only post ids are used in my application, which means SELECT postid FROM posts ...
would be enough. I don't know a way how it's possible to calculate the variable without using the SELECT
part, which automatically results in a field of the returned rows to the client. I'm using MySQL, currently on MariaDB 10.1.
Move your query into a subquery.
SELECT postid, visible
FROM (
SELECT postid, visible, @visible_sum := @visible_sum + IF(visible = 1, 1, 0)
FROM post
CROSS JOIN (SELECT @visible_sum := 0) AS vars
WHERE threadid = 38325
HAVING @visible_sum < 10
ORDER BY dateline
) AS x
You also shouldn't have GROUP BY postid
when you don't have any aggregation functions.