How to list items and count(*) in PostgreSQL - sql

I'm not sure if it's even possible. Let's say, I have a table A having 100 records. I want to select top five records and also return a total number of elements in this table in one query. How can I do this?

You can add the count as an additional column using window functions:
select a.*, count(*) over () as records_in_table
from a
order by <whatever> -- however you define "top five"
fetch first 5 rows only;

Related

SQL Select top 100 columns be specific column names or indices

This works to select top 100 columns, but it gives me all of the columns
select top 100 * from dw.test
This works, but it gives me endless rows,
select Slot, ID from dw.test
I need to select top 100 rows that only show these two columns Slot, ID
I cannot get it to work no matter how I try to combine them,
Please help create this query. Thank you
try it
select TOP(100) Slot, ID from dw.test ORDER BY Slot, ID DESC
It's not clear to me which RDBMS is being used, but one of the following should work:
SELECT TOP(100) Slot, ID FROM dw.test;
Limit instead?
SELECT Slot, ID FROM dw.test LIMIT 100;

How could I query from the first n rows using SQL?

For example, I would like to query from the first 10 rows, how could I achieve that. (Not get the first 10 of the query results).
I tried using 'limit' first then 'where' but it doesn't work.
If I understand correctly you first want to fetch 10 rows of one query, then search within those 10 rows for data. To do that you can use a subquery:
SELECT *
FROM (SELECT *
FROM YOUR_TABLE yt
ORDER BY yt.SOME_COLUMN
LIMIT 10) sq
WHERE sq.SOME_OTHER_COLUMN > 25;
Best of luck.
Based on your sort criteria you can create a SQL like this
SELECT column1, column2, ...
FROM your table
ORDER BY sort column
LIMIT 10
This will give you the top 10 rows from your table based on your sort column

Teradata - limiting the results using TOP

I am trying to fetch a huge set of records from Teradata using JDBC. And I need to break this set into parts for which I'm using "Top N" clause in select.
But I dont know how to set the "Offset" like how we do in MySQL -
SELECT * FROM tbl LIMIT 5,10
so that next select statement would fetch me the records from (N+1)th position.
RANK and QUALIFY I beleive are your friends here
for example
SEL RANK(custID), custID
FROM mydatabase.tblcustomer
QUALIFY RANK(custID) < 1000 AND RANK(custID) > 900
ORDER BY custID;
RANK(field) will (conceptually) retrieve all the rows of the resultset,
order them by the ORDER BY field and assign an incrementing rank ID to them.
QUALIFY allows you to slice that by limiting the rows returned to the qualification expression, which now can legally view the RANKs.
To be clear, I am returning the 900-1000th rows in the query select all from cusotmers,
NOT returning customers with IDs between 900 and 1000.
You can also use the ROW_NUMBER window aggregate on Teradata.
SELECT ROW_NUMBER() OVER (ORDER BY custID) AS RowNum_
, custID
FROM myDatabase.myCustomers
QUALIFY RowNum_ BETWEEN 900 and 1000;
Unlike the RANK windows aggregate, ROW_NUMBER will provide you a sequence regardless of whether the column you are ordering over the optional partition set is unique or not.
Just another option to consider.

How do you Select TOP x but still get a COUNT of the whole query?

I'm writing a webpage to interactively filter results based on filter criteria as it is specified by the user. I only want to return from SQL the TOP 20 rows but I want to know how many rows met the criteria (Count). I want to be able to tell the user: "here are the top 20 rows matching your criteria, and BTW, there were 2,000 additional rows I'm not showing here".
I know I could simply run the query twice but EWWWW that's expensive and wasteful. How can I achieve what I want without over taxing the database?
You can use COUNT(*) OVER()
SELECT TOP 20 *,
COUNT(*) OVER() AS TotalMatchingRows
FROM master..spt_values
WHERE type='P'
ORDER BY number
Doing two queries may work out more efficient however especially if you have narrower indexes that can be used in determining the matching row count but don't cover the entire SELECT list.
select COUNT(*) from Process_Master where dt_time=(select top 1 (dt_time) from Process_Master order by DT_TIME desc)

total number of rows of a query

I have a very large query that is supposed to return only the top 10 results:
select top 10 ProductId from .....
The problem is that I also want the total number of results that match the criteria without that 'top 10', but in the same time it's considered unaceptable to return all rows (we are talking of roughly 100 thousand results.
Is there a way to get the total number of rows affected by the previous query, either in it or afterwords without running it again?
PS: please no temp tables of 100 000 rows :))
dump the count in a variable and return that
declare #count int
select #count = count(*) from ..... --same where clause as your query
--now you add that to your query..of course it will be the same for every row..
select top 10 ProductId, #count as TotalCount from .....
Assuming that you're using an ORDER BY clause already (to properly define which the "TOP 10" results are), then you could add a call of ROW_NUMBER also, with the opposite sort order, and pick the highest value returned.
E.g., the following:
select top 10 *,ROW_NUMBER() OVER (order by id desc) from sysobjects order by ID
Has a final column with values 2001, 2000, 1999, etc, descending. And the following:
select COUNT(*) from sysobjects
Confirms that there are 2001 rows in sysobjects.
I suppose you could hack it with a union select
select top 10 ... from ... where ...
union
select count(*) from ... where ...
For you to get away with this type of hack you will need to add fake columns to the count query so it returns the same amount of columns as the main query. For example:
select top 10 id, first_name from people
union
select count(*), '' as first_name from people
I don't recommend using this solution. Using two separate queries is how it should be done
Generally speaking no - reasoning is as follows:
If(!) the query planner can make use of TOP 10 to return only 10 rows then RDBMS will not even know the exact number of rows that satisfy the full criteria, it just gets the TOP 10.
Therefore, when you want to find out count of all rows satisfying the criteria you are not running it the second time, but the first time.
Having said that proper indexes might make both queries execute pretty fast.
Edit
MySQL has SQL_CALC_FOUND_ROWS which returns the number of rows that query would return if there was no LIMIT applied - googling for an equivalent in MS SQL points to analytical SQL and CTE variant, see this forum (even though not sure that either would qualify as running it only once, but feel free to check - and let us know).