sql top N value - sql

How can I make a SQL query and have a parameter the top N value. For example the first person wants to see the top 10 values, the next perhaps the top 50, maybe the top 100. Would I say something like SELECT TOP =#Value from Table?
Thanks
Yes this is for SQL Server. Standard Query, showing everything, but id like to limit the number of rows returned based on input from the user.

SELECT TOP(cast(#N as integer)) COLUMN1 ,Column2 from table1
That works...

Do you mean the top clause? If your using MySQL you can just use LIMIT to restrict the number of results.
http://www.w3schools.com/sql/sql_top.asp

I am assuming that this is in regards to SQL Server.
You can use set rowcount.
Check out details on how to use this on:
http://msdn.microsoft.com/en-us/library/ms188774.aspx

I think you'll have to restrict it by ROW_NUMBER in the WHERE clause.

Related

Unexpected SQL Behaviour with "SELECT TOP" Query

I'm using Microsoft SQL Server 2019 and when I execute:
SELECT TOP 10 *
FROM WideWorldImporters.Sales.Invoices
SELECT TOP 10 CustomerID
FROM WideWorldImporters.Sales.Invoices
It gives results:
Which is incorrect because those aren't the "top 10" customer IDs as displayed by the first query.
Full Screenshot:
Edit: The behaviour I expected above matches what actually happens in SQL Sever 2014. I suspect they changed the underlying implementation in SQL Server 2019, although it still satisfies the documented behaviour.
A TOP without ORDER BY is unpredictable. This is documented by Microsoft. From Microsoft docs:
When you use TOP with the ORDER BY clause, the result set is limited to the first N number of ordered rows. Otherwise, TOP returns the first N number of rows in an undefined order.
...
In a SELECT statement, always use an ORDER BY clause with the TOP clause. Because, it's the only way to predictably indicate which rows are affected by TOP.
See also how does SELECT TOP works when no order by is specified?
You have no ORDER BY so the top 10 results by an indeterminate order are returned. This ordering can change, from one execution to the next.
Tables in SQL represent unordered sets. If you want particular rows using TOP, you need to have an ORDER BY.
This is too long for a comment.
In SQL, table records are unordered. For this reason, a query like yours:
SELECT TOP 10 * FROM WideWorldImporters.Sales.Invoices
... will produce inconsistent results, because it is missing an ORDER BY clause. You need to tell your RDBMS which column should be used to order the records so in can define which TOP records should be returned. For example, something like:
SELECT TOP 10 * FROM WideWorldImporters.Sales.Invoices ORDER BY InvoiceID DESC
This result is absolutely normal, as your query doesn't specify an order. The top 10 returns the first 10 results.
If you don't specify any ordering clause, the results will be returned according to the previous operations of the SQL engine, which might not always be the same, and surely not what you expect them to be.

SQL Select, different than the last 10 records

I have a table called "dutyroster". I want to make a random selection from this table's "names" column, but, I want the selection be different than the last 10 records so that the same guy is not given a second duty in 10 days. Is that possible ?
Create a temporary table with only one column called oldnames which will have no records initially. For each select, execute a query like
select names from dutyroster where dutyroster.names not in (select oldnamesfrom temporarytable) limit 10
and when execution is done add the resultset to the temporary table
The other answer already here is addressing the portion of the question on how to avoid duplicating selections.
To accomplish the random part of the selection, leverage newid() directly within your select statement. I've made this sqlfiddle as an example.
SELECT TOP 10
newid() AS [RandomSortColumn],
*
FROM
dutyroster
ORDER BY
[RandomSortColumn] ASC
Keep executing the query, and you'll keep getting different results. Use the technique in the other answer for avoiding doubling a guy up.
The basic idea is to use a subquery to get all but users from the last ten days, then sort the rest randomly:
select dr.*
from dutyroster dr
where dr.name not in (select dr2.name
from dutyroster dr2
where dr2.datetimecol >= date_sub(curdate(), interval 10 day)
)
order by rand()
limit 1;
Different databases may have different syntax for limit, rand(), and for the date/time functions. The above gives the structure of the query, but the functions may differ.
If you have a large amount of data and performance is a concern, there are other (more complicated) ways to take a random sample.
you could use TOP function for SQL Server
and for MYSQL you could use LIMIT function
Maybe this would help...
SELECT TOP number|percent column_name(s)
FROM table_name;
Source: http://www.w3schools.com/sql/sql_top.asp

Difference between Top and Limit Keyword in SQL

A quick Question. Suppose I have the following two queries:
SELECT TOP 2 * FROM Persons;
and
SELECT * FROM Persons limit 2;
I want to know the difference between the execution of the above 2 queries?
Basically, I want to know when should I use the limit keyword and when it is appropriate to use the top keyword.
Also, How does the database return results based on the above 2 queries.
If you are using SQL Server use TOP.
if you are using MySQL or PostgreSQL use LIMIT!
AFAIK there is no product that currently supports both. Here's one list of current implementations and here's another (covers more products but in less detail)
As stated in my comment for Martin Smith's answer above, there are products that support both, LIMIT and TOP (as you can see here). The difference is that TOP only selects the first n records, but LIMIT allows the definition of an offset to retrieve a specific range of records:
SELECT * FROM ... LIMIT 5 OFFSET 10
This statement selects the 5 records, after skipping 10 records and this isn't possible with TOP.
The example I posted is only checked against the DBS I linked above. I didn't check a SQL standard, because of a lack of time.
TOP & LIMIT both work on amazon Redshift
limit works on MySQL and PostgreSQL, top works on SQL Server, rownum works on Oracle.
There is no difference. The TOP and LIMIT keywords function identically, and will return the same thing.
The DISTINCT command and the TOP command can't work together.
The DISTINCT command and the LIMIT command do work together.
So if you are using DISTINCT you must use LIMIT.
The difference between top and limit is, top only work with single table where as limit can work with join as well
one big mistake, LIMIT is slowly because select is return full and then database server return only limited data. When it is posible used to TOP.

When is LIMIT applied? Will it select all results before limiting?

I'm concerned about the performance of a query such as SELECT * FROM user LIMIT 5 on a very large user table. Will it select all records then limit to 5?
More specifically will the following query select all assetids before limiting...
SELECT * FROM assets WHERE asset_id IN(1,2,3,4,5,6,7,8,9,10) LIMIT 5
I realize it doesn't make sense to include all ids in the IN() clause if I'm limiting but I'd like to know how mysql behaves in this situation.
Thanks.
This depends on your query. See this page for more explanations of how LIMIT is applied:
http://dev.mysql.com/doc/refman/5.0/en/limit-optimization.html
For that specific query, the following would apply:
"As soon as MySQL has sent the required number of rows to the client, it aborts the query unless you are using SQL_CALC_FOUND_ROWS."
Hope that helps.
Your query will have to scan all rows by asset_id column, so you better have an index on it. In my experience, you would always want to set an order by clause also, since the result set will be internally (i.e. order unknown), and you would not know why the returned 5 results were the ones you actually wanted.

SQL Query: Which one should i use? count("columnname") or count(1)

In my SQL query I just need to check whether data exists for a particular userid.
I always only want one row that will be returned when data exist.
I have two options
1. select count(columnname) from table where userid=:userid
2. select count(1) from tablename where userid=:userid
I am thinking second one is the one I should use because it may have a better response time as compared with first one.
There can be differences between count(*) and count(column). count(*) is often fastest for reasons discussed here. Basically, with count(column) the database has to check if column is null or not in each row. With count(column) it just returns the total number of rows in the table which is probably has on hand. The exact details may depend on the database and the version of the database.
Short answer: use count(*) or count(1). Hell, forget the count and select userid.
You should also make sure the where clause is performing well and that its using an index. Look into EXPLAIN.
I'd like to point out that this:
select count(*) from tablename where userid=:userid
has the same effect as your second solution, with th advantage that count(*) it unambigously means "count all rows".
The * in COUNT(*) will not expand into all columns - that is to say, the * in SELECT COUNT(*) is not the same as in SELECT *. So you need not worry about performance when writing COUNT(*)
The disadvantage of writing COUNT(1) is that it is less clear: what did you mean? A literal one (1) may look like a lower case L (this: l) in some fonts.
Will give different results if columnname can be NULL, otherwise identical performance.
The optimiser (SQL Server at least) realises COUNT(1) is trivial. You can also use COUNT(1/0)
It depends what you want to do.
The first one counts rows with non-null values of columnname. The second one counts ALL rows.
Which behaviour do you want? From the way your question is worded, I guess that you want the second one.
To count the number of records you should use the second option, or rather:
select count(*) from tablename where userid=:userid
You could also use the exists() function:
select case when exists(select * from tablename where userid=:userid) then 1 else 0 end
It might be possible for the database to do the latter more efficiently in some cases, as it can stop looking as soon as a match is found instead of comparing all records.
Hey how about Select count(userid) from tablename where userid=:userid ? That way the query looks more friendly.