Is there a way to add ROW_NUMBER() without using OVER (ORDER BY ...) in SQL - sql

Is there a way to add ROW_NUMBER() simply based on the default row order without using OVER (ORDER BY ...)?

There is no implicit ordering to rows in a table, it is a logical unordered set.
however you can do row_number() over (order by (select null))
As suggested by Itzik Ben-Gan from his book on window functions.

For PostgreSQL and MYSQL 8.0
row_number()over()
For SQL Server and oracle it will be:
row_number()over(order by (select null))
But this without mentioning proper order by clause it's not guaranteed to have same row number for a column everytime.

Related

How can we implement First() function used in Informatica in SQL?

I have an aggregate transformation in Informatica where Description1 column=First(Description).
I want to implement the same in SQL query.Can anyone suggest how to do this?
Sample Dataset
Table name-ABC
Name Expression
ID ID
DESCRIPTION
DESCRIPTION1 FIRST(DESCRIPTION1)
INSERT_DATE
INSERT_DATE1 FIRST(INSERT_DATE)
RANK
RANK1 FIRST(RANK)
Please use below query,
select max(Description1) from Router_Transform;
If you are using sorter transformation in your Mapping, please use order by clause,
select max(Description1) from Router_Transform order by column_name;
If you want the row with the smallest id, then you can sort the resultset and retain just one row. In standard SQL, you would typically use a row-limiting clause for this:
select t.*
from mytable
order by id
fetch first row only
Note that all databases support this syntax (but almost all have alternatives for that).
On the other hand, if you want to add more columns to each row that display the "first" value for each column, then you would use window function first_value():
select
t.*,
first_value(description) over(order by id) description1,
first_value(insert_date) over(order by id) insert_date1,
first_value(rank) over(order by id) rank1
from mytable

How do i access the "ID" in MS SQL Server Mangement Studio

I need to access the red marked "id". There is no id in the query. How do i access it ?
I want to access it via a Select statement, of course.
You cannot exactly "access" it. You can calculate it using row_number().
Tables represent unordered sets. So there is no inherent ordering. I cannot tell if any columns specify the ordering. But you can do the calculation as:
select row_number() over (order by uid) as id, t.*
from t;
If you want insertion order for the table, you should add an identity() column to capture the insertion order. To be accurate, you should recreate the table.
You don't have to specify a column if you use:
select row_number() over (order by (select null)) as id, t.*
from t;
In this case, the result is indeterminate.

ROW_NUMBER Without ORDER BY

I've to add row number in my existing query so that I can track how much data has been added into Redis. If my query failed so I can start from that row no which is updated in other table.
Query to get data start after 1000 row from table
SELECT * FROM (SELECT *, ROW_NUMBER() OVER (Order by (select 1)) as rn ) as X where rn > 1000
Query is working fine. If any way that I can get the row no without using order by.
What is select 1 here?
Is the query optimized or I can do it by other ways. Please provide the better solution.
There is no need to worry about specifying constant in the ORDER BY expression. The following is quoted from the Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions written by Itzik Ben-Gan (it was available for free download from Microsoft free e-books site):
As mentioned, a window order clause is mandatory, and SQL Server
doesn’t allow the ordering to be based on a constant—for example,
ORDER BY NULL. But surprisingly, when passing an expression based on a
subquery that returns a constant—for example, ORDER BY (SELECT
NULL)—SQL Server will accept it. At the same time, the optimizer
un-nests, or expands, the expression and realizes that the ordering is
the same for all rows. Therefore, it removes the ordering requirement
from the input data. Here’s a complete query demonstrating this
technique:
SELECT actid, tranid, val,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM dbo.Transactions;
Observe in the properties of the Index Scan iterator that the Ordered
property is False, meaning that the iterator is not required to return
the data in index key order
The above means that when you are using constant ordering is not performed. I will strongly recommend to read the book as Itzik Ben-Gan describes in depth how the window functions are working and how to optimize various of cases when they are used.
Try just order by 1. Read the error message. Then reinstate the order by (select 1). Realise that whoever wrote this has, at some point, read the error message and then decided that the right thing to do is to trick the system into not raising an error rather than realising the fundamental truth that the error was trying to alert them to.
Tables have no inherent order. If you want some form of ordering that you can rely upon, it's up to you to provide enough deterministic expression(s) to any ORDER BY clause such that each row is uniquely identified and ordered.
Anything else, including tricking the system into not emitting errors, is hoping that the system will do something sensible without using the tools provided to you to ensure that it does something sensible - a well specified ORDER BY clause.
You can use any literal value
ex
order by (select 0)
order by (select null)
order by (select 'test')
etc
Refer this for more information
https://exploresql.com/2017/03/31/row_number-function-with-no-specific-order/
What is select 1 here?
In this scenario, the author of query does not really have any particular sorting in mind.
ROW_NUMBER requires ORDER BY clause so providing it is a way to satisfy the parser.
Sorting by "constant" will create "undeterministic" order(query optimizer is able to choose whatever order it found suitable).
Easiest way to think about it is as:
ROW_NUMBER() OVER(ORDER BY 1) -- error
ROW_NUMBER() OVER(ORDER BY NULL) -- error
There are few possible scenarios to provide constant expression to "trick" query optimizer:
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) -- already presented
Other options:
ROW_NUMBER() OVER(ORDER BY 1/0) -- should not be used
ROW_NUMBER() OVER(ORDER BY ##SPID)
ROW_NUMBER() OVER(ORDER BY DB_ID())
ROW_NUMBER() OVER(ORDER BY USER_ID())
db<>fiddle demo

selecting first result from output of a subquery

i want to select first and last outcome from a subquery in oracle.
i cant use "rownum" since i am using "order by" which completely changes the sequence of "rownum".
pls suggest some solutions.
thanx fr help.
Use keep if you have an aggregation query. That is what it is designed for. It looks something like this:
select x,
max(outcome) keep (dense_rank first order by datetime asc) as first_outcome,
max(outcome) keep (dense_rank first order by datetime desc) as last_outcome,
from t
group by x;
Use first_value() and last_value() if there is no aggregation:
select t.*,
first_value(outcome) over (partition by x order by datetime) as first_outcome,
last_value(outcome) over (partition by x order by datetime) as last_outcome
from t;
You can't use "rownum" because you want both the first and the last values - otherwise you could use rownum by putting your code in a subquery and selecting from it and filtering by rownum in the outer query. As it is, you need to use ROW_NUMBER() analytic function and such (both with order by ... and with order by ... desc, so you can get both the first and the last outcome in one single outer query.
If ties are possible you may prefer DENSE_RANK to get all rows tied for first (or for last); instead, ROW_NUMBER() will return "one of" the rows tied for first (or for last); which one, specifically, is random.
If you want to see an example, provide sample data for your problem.
I solved this by using ROW_NUMBER() function with OVER(order by..).

Sql server ROW_NUMBER() & Rank() function detail....how it works

i never use sql server ROW_NUMBER() function. so i read some article regarding ROW_NUMBER(),PARTITION & RANK() etc but still not clear to me.
i found the syntax is like
SELECT top 10 ROW_NUMBER() OVER(ORDER BY JID DESC) AS 'Row Number',
JID,Specialist, jobstate, jobtype FROM bbajobs
SELECT top 10 ROW_NUMBER() OVER(PARTITION BY JID ORDER BY JID DESC) AS 'Row Number',
JID,Specialist, jobstate, jobtype FROM bbajobs
i have few question
1) what over() function does. why we need to specify column name in over function like OVER(ORDER BY JID DESC)
2) i saw sometime people use PARTITION keyword. what it is?
it is also used in over function like OVER(PARTITION BY JID ORDER BY JID DESC)
3) in what type of situation we have to use PARTITION keyword
4) when we specify PARTITION keyword in over then also we need to specify order by also why. only PARTITION keyword can not be used in over clause.
5) what type of situation one should use RANK function
6) what is CTE and what is the advantage of using CTE. it is just like temporary view.
anyone get any performance boost if he/she use CTE other than reusability?
please discuss my points in detail. it will be very much helpful if some one make me understand with small & easy example for all the keyword like ROW_NUMBER(),PARTITION & RANK(). thanks
OVER Clause (Transact-SQL)
Ranking Functions (Transact-SQL)
ROW_NUMBER (Transact-SQL)
RANK (Transact-SQL)
You need ORDER BY because sets have no order otherwise. You need it for a standard SELECT
PARTITION BY resets the COUNT per partition
Many
See point 1. You can use PARTITION by itself for SUM, COUNT etc
See MSDN
Separate question