MySQL - getting from random column but specifying amounts - sql

I would like to do this
SELECT *
FROM Thoughts
ORDER BY RAND()
LIMIT 1 WHERE ups > 5
...but it is returning an error. Do you know an alternative around that? I'm a bit new to MySQL, thanks.

The order of the clauses is important. Do
SELECT * FROM Thoughts WHERE ups > 5 ORDER BY RAND() LIMIT 1
Also, in the future, post the error you that you're getting. "An error" is amazingly unspecific.

order by rand() may cause performance issue, instead try to do in following way:
// what NOT to do:
$r = mysql_query("SELECT * FROM Thoughts WHERE ups > 5 ORDER BY RAND() LIMIT 1");
// much better:
$r = mysql_query("SELECT count(*) FROM Thoughts WHERE ups > 5 ");
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] - 1);
$r = mysql_query("SELECT * FROM Thoughts WHERE ups > 5 LIMIT $rand, 1");

Related

offset and limit syntax error

What is wrong here
phpMyAdmin
update posts set pos = 'right' where pos = 'below' limit 4 offset 10;
I also tried:
update posts set pos = 'right' where pos = 'below' offset 10 limit 4;
update posts set pos = 'right' limit 4 offset 10;
update posts set pos = 'right' offset 10 limit 4;
Always the same error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'offset 10' at line 1
Like Barmar said in the comments you can't make use of a OFFSET with LIMIT in UPDATE queries.
The best method to replace
update posts set pos = 'right' where pos = 'below' limit 4 offset 10;
Assuming you have a id column with PRIMARY KEY and auto_increment option.. this should work like using limit 4 offset 10 or limit 10. 4
p.s Please note that the id's must be incremental from 11 until 14 without anny deleted id('s).
update posts set pos = 'right' where pos = 'below' and (id > 10 and id <= 14)
p.s this query will work when there are deleted id('s)
update posts set pos = 'right' where pos = 'below' and id > 10 LIMIT 4
Assuming your posts table has an id primary key, you could:
update posts
set pos = 'right'
where id in
(
select id
from (
select id
from posts
where pos = 'below'
order by
id
limit 4
offset 10
) sub
)
Example at DB Fiddle. The double subquery is required to work around MySQL's doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' error. Like
Raymond Nijland commented, MySQL usually returns rows in the primary key order, but you can't strictly rely on that without an order by.
LIMIT can be used with UPDATE but with the row count only.
So here below query will work fine without limit
update posts set pos = 'right' where pos = 'below'
Please check below links there are some good points for the same.
MySQL - UPDATE query with LIMIT
As suggest by #Barmar, please check syntex and search little on this before asking here. :)

Round in SQL Server

I'm trying to figure out away to do this in SQL:
100000 % 1000 = 0
1150000%1000000 = 150000
I don't know if there is anything like that in SQL. Or even if there is, I don't know what it is called.
Any idea?
SELECT 1150000 / 1000000 AS result, 1150000 % 1000000 AS reminder;
Wich gives : result = 1 & reminder = 150000

Rank over multiple columns executed by the server?

How can I implement the RANK() function taking into account two columns for the ranking? The main column does not have unique values. This is the query:
select *, RANK() over (order by score, posteddate desc) as rank from Post
I need to implement pagination without the offset limit pattern and I thought a kind of ranking function would be ok. I have a partial implementation which only works with uniques, using the '>' or '<' operands on the key used for pagination.
Any idea? I cannot find a solution online.
Cheers.
Edit upon request: I am using c#.
We do paging with .Skip(pageIndex * pageSize) and .Take(pageSize). You just need to make sure you have ordered the data first. This will all execute on the server.
For example, if you want the content for page 4 and each page should contain 20 results:
var pageIndex = 4;
var pageSize = 20;
var pageContent = db.Post
.OrderBy(p => p.score)
.ThenByDescending(p => p.posteddate)
.Skip(pageIndex * pageSize)
.Take(pageSize);
The generated SQL here automatically includes the addition of ROW_NUMBER() and TOP. It works pretty well up to a couple hundred thousand records.
Not exactly an answer, but I found a better approach as described in http://use-the-index-luke.com/sql/partial-results/fetch-next-page
SELECT *
FROM ( SELECT *
FROM sales
WHERE sale_date <= ?
AND NOT (sale_date = ? AND sale_id >= ?)
ORDER BY sale_date DESC, sale_id DESC
)
WHERE rownum <= 10

Codeigniter SQL Join with multiple ON clauses?

This is the SQL query displayed by codeigniter:
SELECT * FROM (status_updates) JOIN friend_connections ON ((
status_updates.userid=friend_connections.userid) OR
(status_updates.userid=friend_connections.friend_id)) WHERE
status_updates.enabled = "1" AND friend_connections.enabled = "1"
ORDER BY status_updates.date desc, status_updates.time desc LIMIT 20
The Codeigniter commands i used were:
$this->db->from('status_updates');
$this->db->order_by("status_updates.date", "desc");
$this->db->order_by("status_updates.time", "desc");
$this->db->limit(20);
$this->db->join('status_updates', '((status_updates.userid=friend_connections.userid) OR (status_updates.userid=friend_connections.friend_id))');
What i'm trying to do is select everything in two tables, status_updates and friend_connections. status_updates has the one column userid which i want to match with either userid or friend_id from friend_connections. Can someone tell me how i can do this please?
Also i noticed that codeigniter removes the two opening parentheses after the ON command in the above sql query.
Copy of your own answer in order to remove this from the unanswered stack:
$sql = "SELECT * FROM (status_updates) JOIN friend_connections ON ((status_updates.userid=friend_connections.userid) OR (status_updates.userid=friend_connections.friend_id)) WHERE status_updates.enabled = "1" AND friend_connections.enabled = "1" ORDER BY status_updates.date desc, status_updates.time desc LIMIT 20";
$status = $this->db->query($sql);
Please don't upvote. It's not my answer.

LINQ to SQL Every Nth Row From Table

Anybody know how to write a LINQ to SQL statement to return every nth row from a table? I'm needing to get the title of the item at the top of each page in a paged data grid back for fast user scanning. So if i wanted the first record, then every 3rd one after that, from the following names:
Amy, Eric, Jason, Joe, John, Josh, Maribel, Paul, Steve, Tom
I'd get Amy, Joe, Maribel, and Tom.
I suspect this can be done... LINQ to SQL statements already invoke the ROW_NUMBER() SQL function in conjunction with sorting and paging. I just don't know how to get back every nth item. The SQL Statement would be something like WHERE ROW_NUMBER MOD 3 = 0, but I don't know the LINQ statement to use to get the right SQL.
Sometimes, TSQL is the way to go. I would use ExecuteQuery<T> here:
var data = db.ExecuteQuery<SomeObjectType>(#"
SELECT * FROM
(SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS [__row]
FROM [YourTable]) x WHERE (x.__row % 25) = 1");
You could also swap out the n:
var data = db.ExecuteQuery<SomeObjectType>(#"
DECLARE #n int = 2
SELECT * FROM
(SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS [__row]
FROM [YourTable]) x WHERE (x.__row % #n) = 1", n);
Once upon a time, there was no such thing as Row_Number, and yet such queries were possible. Behold!
var query =
from c in db.Customers
let i = (
from c2 in db.Customers
where c2.ID < c.ID
select c2).Count()
where i%3 == 0
select c;
This generates the following Sql
SELECT [t2].[ID], [t2]. --(more fields)
FROM (
SELECT [t0].[ID], [t0]. --(more fields)
(
SELECT COUNT(*)
FROM [dbo].[Customer] AS [t1]
WHERE [t1].[ID] < [t0].[ID]
) AS [value]
FROM [dbo].[Customer] AS [t0]
) AS [t2]
WHERE ([t2].[value] % #p0) = #p1
Here's an option that works, but it might be worth checking that it doesn't have any performance issues in practice:
var nth = 3;
var ids = Table
.Select(x => x.Id)
.ToArray()
.Where((x, n) => n % nth == 0)
.ToArray();
var nthRecords = Table
.Where(x => ids.Contains(x.Id));
Just googling around a bit I haven't found (or experienced) an option for Linq to SQL to directly support this.
The only option I can offer is that you write a stored procedure with the appropriate SQL query written out and then calling the sproc via Linq to SQL. Not the best solution, especially if you have any kind of complex filtering going on.
There really doesn't seem to be an easy way to do this:
How do I add ROW_NUMBER to a LINQ query or Entity?
How to find the ROW_NUMBER() of a row with Linq to SQL
But there's always:
peopleToFilter.AsEnumerable().Where((x,i) => i % AmountToSkipBy == 0)
NOTE: This still doesn't execute on the database side of things!
This will do the trick, but it isn't the most efficient query in the world:
var count = query.Count();
var pageSize = 10;
var pageTops = query.Take(1);
for(int i = pageSize; i < count; i += pageSize)
{
pageTops = pageTops.Concat(query.Skip(i - (i % pageSize)).Take(1));
}
return pageTops;
It dynamically constructs a query to pull the (nth, 2*nth, 3*nth, etc) value from the given query. If you use this technique, you'll probably want to create a limit of maybe ten or twenty names, similar to how Google results page (1-10, and Next), in order to avoid getting an expression so large the database refuses to attempt to parse it.
If you need better performance, you'll probably have to use a stored procedure or a view to represent your query, and include the row number as part of the stored proc results or the view's fields.