Biggest/Longest records in varchar table - sql

We recently noticed that in one of our biggest tables some of the rows are a few times bigger than others. By "bigger" I mean longer and taking more storage space.
How to display top 1000 biggest rows in the table?
Almost all columns are varchar so it would be great if the query could sum up the size of the data in each row and show the biggest rows.
I tried to modify this:
select MyVarcharColumnName
from MyTableName
where len(MyVarcharColumnName) =
(select max(len(MyVarcharColumnName)) from MyTableName)
and this:
select max(len(Desc)) from table_name
but
I get an error
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'Desc'.

How about this?
select top 1000 t.*
from MyTableName t
order by len(MyVarcharColumnName) desc;
If you have multiple columns, you can add them to the order by:
order by (len(col1) + len(col2) + . . . ) desc
I have used len() for this calculation, because that is what you are using in your question. You might also be interested in [DATALENGTH()][1].

It thinks that Desc is a keyword rather than an identifier. Try to enclose it in angle brackets ([]), like this:
select max(len([Desc])) from table_name

Related

Syntax error near 0

What's wrong with the following statement? I'm using SQL Server 2008.
use Demo;
SELECT * FROM users
limit 0 , 30
I got:
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near '0'.
That's really weird. I tried Google but didn't find much info.
LIMIT is a MySQL keyword. Use the TOP or ROWCOUNT keywords in MS SQL Server.
Note that TOP can accept a variable, e.g. SELECT TOP( #NumberOfRows ) * FROM Foo;
See: How to use LIMIT keyword in SQL Server 2005? (also valid for 2008)
Depending on how LIMIT is used, there is an important difference between LIMIT and TOP (ranges/pages of data versus just capping the number of results). In that case, the MS SQL syntax is more verbose; usually the ROW_NUMBER() function does the trick combined with some simple logic to calculate the values which are valid for the desired page.
Simple Range Selection Example
SELECT * FROM
(
SELECT
ROW_NUMBER() OVER( ORDER BY SomeColumn ASC ) AS RowNumber,
AnotherColumn
FROM dbo.MyTable
) Q
WHERE RowNumber BETWEEN 20 AND 30; -- these integers can be variables
select top 30 * from users
SQL Server uses that syntax rather than the limit form.
SQL Server doesn't support the limit clause (that is the MySQL and PostgreSQL syntax). You should use top like this:
select top 30 * from users

Access Database LIMIT keyword

I'm trying to get my page listing function working in ASP with an Access database, but I don't know the alternative to LIMIT in Microsoft SQL. I have tried TOP but this doesn't seem to be working.
Here is the statement am using with MySQL:
SELECT * FROM customers ORDER BY customerName DESC LIMIT 0, 5
How can I convert this to work with Access Database?
According to ms-access view:
SELECT TOP(5) * FROM customers ORDER BY customerName;
will fetch an error "The SELECT statement includes a reserved word",
the correct syntax is:
SELECT TOP 5 * FROM customers ORDER BY customerName;
(note the brackets)..
Top(5) is deceptive. Internally the database returns all records, then Access just shows the Top 5 rows. I'd use the LIMIT keyword instead of Top(n).
There is no direct equivalent in access for LIMIT, but the TOP statement can be manipulated into working in a similar fashion to say, "... LIMIT BY 50, 250" etc,. I found out by experiment that if you wanted to get the "next 50" records at an offset of 250 you could try the following
SELECT * FROM (SELECT TOP 50 tab2.* FROM (SELECT TOP 300 tab1.* FROM my_table AS tab1 ORDER BY column_name ASC) AS tab2 ORDER BY column_name DESC) ORDER BY column_name ASC;
This should return the records from row 250 to 300, in ascending order (provided they exist.) with or without a unique index. A WHERE clause could tidy the results further if need be.
A little convoluted but I hope it helps.

Most efficient way to select 1st and last element, SQLite?

What is the most efficient way to select the first and last element only, from a column in SQLite?
The first and last element from a row?
SELECT column1, columnN
FROM mytable;
I think you must mean the first and last element from a column:
SELECT MIN(column1) AS First,
MAX(column1) AS Last
FROM mytable;
See http://www.sqlite.org/lang_aggfunc.html for MIN() and MAX().
I'm using First and Last as column aliases.
if it's just one column:
SELECT min(column) as first, max(column) as last FROM table
if you want to select whole row:
SELECT 'first',* FROM table ORDER BY column DESC LIMIT 1
UNION
SELECT 'last',* FROM table ORDER BY column ASC LIMIT 1
The most efficient way would be to know what those fields were called and simply select them.
SELECT `first_field`, `last_field` FROM `table`;
Probably like this:
SELECT dbo.Table.FirstCol, dbo.Table.LastCol FROM Table
You get minor efficiency enhancements from specifying the table name and schema.
First: MIN() and MAX() on a text column gives AAAA and TTTT results which are not the first and last entries in my test table. They are the minimum and maximum values as mentioned.
I tried this (with .stats on) on my table which has over 94 million records:
select * from
(select col1 from mitable limit 1)
union
select * from
(select col1 from mitable limit 1 offset
(select count(0) from mitable) -1);
But it uses up a lot of virtual machine steps (281,624,718).
Then this which is much more straightforward (which works if the table was created without WITHOUT ROWID) [sql keywords are in capitals]:
SELECT col1 FROM mitable
WHERE ROWID = (SELECT MIN(ROWID) FROM mitable)
OR ROWID = (SELECT MAX(ROWID) FROM mitable);
That ran with 55 virtual machine steps on the same table and produced the same answer.
min()/max() approach is wrong. It is only correct, if the values are ascending only. I needed something liket this for currency rates, which are random raising and falling.
This is my solution:
select st.*
from stats_ticker st,
(
select min(rowid) as first, max(rowid) as last --here is magic part 1
from stats_ticker
-- next line is just a filter I need in my case.
-- if you want first/last of the whole table leave it out.
where timeutc between datetime('now', '-1 days') and datetime('now')
) firstlast
WHERE
st.rowid = firstlast.first --and these two rows do magic part 2
OR st.rowid = firstlast.last
ORDER BY st.rowid;
magic part 1: the subselect results in a single row with the columns first,last containing rowid's.
magic part 2 easy to filter on those two rowid's.
This is the best solution I've come up so far. Hope you like it.
We can do that by the help of Sql Aggregate function, like Max and Min. These are the two aggregate function which help you to get last and first element from data table .
Select max (column_name ), min(column name) from table name
Max will give you the max value means last value and min will give you the min value means it will give you the First value, from the specific table.

how to select first N rows from a table in T-SQL?

Is there any way to select, for example, first 10 rows of a table in T-SQL (working MSSQL)?
I think I saw something in Oracle defined as rownum meta variable, used in a following way
select * from Users where rownum<=10
But what about MSSQL?
select top(#count) * from users
If #count is a constant, you can drop the parentheses:
select top 42 * from users
(the latter works on SQL Server 2000 too, while the former requires at least 2005)
You can use Microsoft's row_number() function to decide which rows to return. That means that you aren't limited to just the top X results, you can take pages.
SELECT *
FROM (SELECT row_number() over (order by UserID) AS line_no, *
FROM dbo.User) as users
WHERE users.line_no < 10
OR users.line_no BETWEEN 34 and 67
You have to nest the original query though, because otherwise you'll get an error message telling you that you can't do what you want to in the way you probably should be able to in an ideal world.
Msg 4108, Level 15, State 1, Line 3
Windowed functions can only appear in the SELECT or ORDER BY clauses.
SELECT TOP 10 *
FROM Users
Note that if you don't specify an ORDER BY clause then any 10 rows could be returned, because "first 10 rows" doesn't really mean anything until you tell the database what ordering to use.
You can also use rowcount, but TOP is probably better and cleaner, hence the upvote for Mehrdad
SET ROWCOUNT 10
SELECT * FROM dbo.Orders
WHERE EmployeeID = 5
ORDER BY OrderDate
SET ROWCOUNT 0
Try this.
declare #topval int
set #topval = 5 (customized value)
SELECT TOP(#topval) * from your_database
SELECT TOP 10 * FROM TABLE_NAME ORDER BY ORDERED_UNIQUE_COLUMN
DESC
ORDERED_UNIQUE_COLUMN could be your incrementing primary key or a timestamp
Try this:
SELECT * FROM USERS LIMIT 10;

How to use LIMIT keyword in SQL Server 2005?

I have found a way to select random rows from a table in this post. A suggestion is to use the following query:
SELECT * FROM employee ORDER BY RAND() LIMIT 1
But when I run this query in MS SQL 2005, I get the following error message
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'LIMIT'.
Can anyone tell me where am I wrong? Doesn't MS SQL support LIMIT? If so, then how can I do this?
If you take a look at the SELECT statement in SQL Server Books Online, then you'll see that you can limit the resultset by using the TOP keyword.
SELECT TOP 1 * FROM employee
SELECT TOP 1 * FROM Employee ORDER BY newid()
You have to use newid() for it to be evaluated once per row.
I'm using this fairly simple one (SQL2005) to limit the number of rows returned, which will work with a value provided by a stored procedure parameter as well.
DECLARE #Limit int
SET #Limit = 10
SELECT TOP (#Limit) Col1, Col2 FROM SomeTable