Simple SQL query - sql

I have a table, with these columns:
ID | Data
How to find out which record has highest ID?

To get the largest ID:
select max(ID) from myTable
To get a record that has the largest ID:
select *
from MyTable
where ID = (Select max(ID) from myTable)

select *
from YourTable
where ID = (select max(ID) from YourTable)

select max(ID) from tablename

As well as max, you can use TOP on SQL Server
select TOP 1 * from myTable order by id desc
For joint top
select TOP 1 WITH TIES * from myTable order by id desc
Other engines have LIMIT not TOP. This can give the whol record without a separate MAX sub-query too

Related

Select more columns with MAX function

Need to find in databse max value, but then i need read other values in columns.
Can this be done with one SQL command or I have to use this two commands?
SELECT MAX(id) FROM Table;
SELECT * FROM Table WHERE id = $value;
where $value is variable from 1st command
select * from your_table
where id = (select max(id) from your_table)
or
select t1.* from your_table t1
inner join
(
select max(id) as mid
from your_table
)
t2 on t1.id = t2.mid
Probably the simplest way is:
select *
from t
order by id
limit 1
Or use top 1 or where rownum = 1 or whatever is the right logic for your database.
Note: this only returns one row. If you have duplicate such rows, then comparison to the maximum will give you all of them.
Also, if you are using a database that supports window functions:
select *
from (select t.*, row_number() over (order by id desc) as seqnum
from t
) t
where seqnum = 1;

SQL how to select a group of records based on some statistics of this group?

Example, I have a record set with three columns:
id,week,count
1,1,10;
1,2,20;
1,3,30;
2,1,3;
2,2,2;
2,3,15;
What I want is just the data of IDs whose average count is > 10. Then, in this example data, the data of id=1 will be selected.
Thanks.
SELECT id FROM YourTable GROUP BY id HAVING AVG(count) > 10
SELECT *
FROM YourTable
WHERE id IN (SELECT id FROM YourTable GROUP BY id HAVING AVG(count) > 10)
Or if you are using an access database (where IN happens to have horrendous performance for whatever reason) you can use:
SELECT t2.*
FROM (SELECT id FROM YourTable GROUP BY id HAVING AVG(count) > 10) AS t1
INNER JOIN YourTable AS t2 ON t1.id = t2.id
In most databases, you can also do this with window functions:
select t.*
from (select t.*, avg(count) over (partition by id) as avgcount
from t
) t
where avgcount > 10

get id value when max is on other column

is this the best way to get the id value of the most recent date?
table1
id,entrydate
1,8/23/2012
2,8/24/2012
3,8/23/2012
select id from table1 where entrydate = ( select MAX(entrydate) from table1 )
Assuming you're using SQL-Server, you can use ORDER BY and then take one row:
SELECT TOP 1 id
FROM table
ORDER BY entrydate DESC
In MySql it is LIMIT:
SELECT id
FROM table
ORDER BY entrydate DESC
LIMIT 1
In Oracle:
SELECT id
FROM (SELECT id FROM table ORDER BY entrydate DESC)
WHERE ROWNUM = 1
You already have a good way there. I'd watch out for ties:
select top id from table1 where entrydate = ( select MAX(entrydate) from table1 )
This, of course, assuming you are using SQL Server.
SELECT id FROM table1 ORDER BY entrydate DESC LIMIT 1
You should be able to do SELECT id FROM table1 ORDER BY entrydate DESC LIMIT 1
Not exactly, you want to do this:
For SQL Server:
SELECT TOP 1 id, MAX(entrydate) FROM table1 GROUP BY id
For MySQL:
SELECT id, MAX(entrydate) FROM table1 GROUP BY id LIMIT 1

How can I get the n-th row in the Query results?

How can I get the n-th row of a TSQL query results?
Let's say, I want to get the 2nd row of this SELECT:
SELECT * FROM table
ORDER BY 2 ASC
What version of SQL Server are you targeting? If 2005 or greater, you can use ROW_NUMBER to generate a row number and select using that number. http://msdn.microsoft.com/en-us/library/ms186734.aspx
WITH orderedtable AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY <your order here>) AS 'RowNumber'
FROM table
)
SELECT *
FROM orderedtable
WHERE RowNumber = 2;
You can use a trick combining TOP with ORDER BY ASC/DESC to achieve an effect similar to MySQL's LIMIT:
SELECT TOP 2 * INTO #temptable FROM table
ORDER BY 2 ASC
SELECT TOP 1 * FROM #temptable
ORDER BY 2 DESC
or without temptable, but nested statements:
SELECT TOP 1 * FROM
(
SELECT TOP 2 * FROM table
ORDER BY 2 ASC
) sub
ORDER BY 2 DESC
The first time you select all rows up to the one you want to actually have, and in the second query you select only the first of the remaining when ordering them reversely, which is exactly the one you want.
Source: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=850&lngWId=5
One way;
;with T(rownumber, col1, colN) as (
select
row_number() over (order by ACOLUMN) as rownumber,
col1,
colN
from
atable
)
select * from T where rownumber = 2

Select top and bottom rows

I'm using SQL Server 2005 and I'm trying to achieve something like this:
I want to get the first x rows and the last x rows in the same select statement.
SELECT TOP(5) BOTTOM(5)
Of course BOTTOM does not exist, so I need another solution. I believe there is an easy and elegant solution that I'm not getting. Doing the select again with GROUP BY DESC is not an option.
Using a union is the only thing I can think of to accomplish this
select * from (select top(5) * from logins order by USERNAME ASC) a
union
select * from (select top(5) * from logins order by USERNAME DESC) b
Check the link
SQL SERVER – How to Retrieve TOP and BOTTOM Rows Together using T-SQL
Did you try to using rownumber?
SELECT *
FROM
(SELECT *, ROW_NUMBER() OVER (Order BY columnName) as TopFive
,ROW_NUMBER() OVER (Order BY columnName Desc) as BottomFive
FROM Table
)
WHERE TopFive <=5 or BottomFive <=5
http://www.sqlservercurry.com/2009/02/select-top-n-and-bottom-n-rows-using.html
I think you've two main options:
SELECT TOP 5 ...
FROM ...
ORDER BY ... ASC
UNION
SELECT TOP 5 ...
FROM ...
ORDER BY ... DESC
Or, if you know how many items there are in the table:
SELECT ...
FROM (
SELECT ..., ROW_NUMBER() OVER (ORDER BY ... ASC) AS intRow
FROM ...
) AS T
WHERE intRow BETWEEN 1 AND 5 OR intRow BETWEEN #Number - 5 AND #Number
Is it an option for you to use a union?
E.g.
select top 5 ... order by {specify columns asc}
union
select top 5 ... order by {specify columns desc}
i guess you have to do it using subquery only
select * from table where id in (
(SELECT id ORDER BY columnName LIMIT 5) OR
(SELECT id ORDER BY columnName DESC LIMIT 5)
)
select * from table where id in (
(SELECT TOP(5) id ORDER BY columnName) OR
(SELECT TOP(5) id ORDER BY columnName DESC)
)
EDITED
select * from table where id in (
(SELECT TOP 5 id ORDER BY columnName) OR
(SELECT TOP 5 id ORDER BY columnName DESC)
)
No real difference between this and the union that I'm aware of, but technically it is a single query.
select t.*
from table t
where t.id in (select top 5 t2.id from table t2 order by MyColumn)
or
t.id in (select top 5 t2.id from table t2 order by MyColumn desc);
SELECT *
FROM (
SELECT x, rank() over (order by x asc) as rown
FROM table
) temp
where temp.rown = 1
or temp.rown = (select count(x) from table)
Then you are out - doing the select again IS the only option, unless you want to pull in the complete result set and then throwing away everything in between.
ANY sql I cna think of is the same way - for the bottom you need to know first either how many items you have (materialize everything or use count(*)) or a reverse sort order.
Sorry if that does not suit you, but at the end.... reality does not care, and I do not see any other way to do that.
I had to do this recently for a very large stored procedure; if your query is quite large, and you want to minimize the amount of queries you could declare a #tempTable, insert into that #tempTable then query from that #tempTable,
DECLARE #tempTable TABLE ( columns.. )
INSERT INTO #tempTable
VALUES ( SELECT.. your query here ..)
SELECT TOP(5) columns FROM #tempTable ORDER BY column ASC -- returns first to last
SELECT TOP(5) columns FROM #tempTable ORDER BY column DESC -- returns last to first