Dynamically numbering distinct sql rows in select statement - sql

How would I dynamically number rows in a query similar to this:
Select distinct name from #table where %rules
When I add ROW_NUMBER() OVER() I lose my distinct property, and it returns every element in table, with a unique row number.
Select distinct ROW_NUMBER OVER(order by name), name from #table where %rules
I don't want to create a temporary table, otherwise I would make a primary key for the temporary table and have it insert row numbers that way.
Thanks in advance!

Use like this.
select ROW_NUMBER() OVER(order by name), * from
(Select distinct name from #table where %rules) as mytable

Related

Remove duplicates from table in bigquery

I found duplicates in my table by doing below query.
SELECT name, id, count(1) as count
FROM [myproject:dev.sample]
group by name, id
having count(1) > 1
Now i would like to remove these duplicates based on id and name by using DML statement but its showing '0 rows affected' message.
Am i missing something?
DELETE FROM PRD.GPBP WHERE
id not in(select id from [myproject:dev.sample] GROUP BY id) and
name not in (select name from [myproject:dev.sample] GROUP BY name)
I suggest, you create a new table without the duplicates. Drop your original table and rename the new table to original table.
You can find duplicates like below:
Create table new_table as
Select name, id, ...... , put our remaining 10 cols here
FROM(
SELECT *,
ROW_NUMBER() OVER(Partition by name , id Order by id) as rnk
FROM [myproject:dev.sample]
)a
WHERE rnk = 1;
Then drop the older table and rename new_table with old table name.
Below query (BigQuery Standard SQL) should be more optimal for de-duping like in your case
#standardSQL
SELECT AS VALUE ANY_VALUE(t)
FROM `myproject.dev.sample` AS t
GROUP BY name, id
If you run it from within UI - you can just set Write Preference to Overwrite Table and you are done
Or if you want you can use DML's INSERT to new table and then copy over original one
Meantime, the easiest way is as below (using DDL)
#standardSQL
CREATE OR REPLACE TABLE `myproject.dev.sample` AS
SELECT * FROM (
SELECT AS VALUE ANY_VALUE(t)
FROM `myproject.dev.sample` AS t
GROUP BY name, id
)

How to add a column with specific values to an existing database table

I needed an advice regarding a SQL statement that has to run with DB2 and Oracle.
Some time ago a database table has been set up without an ID column. Adding the ID column is not the problem but I absolutely need to fill it with the row number of each row.
I found out, that rank() would be perfect but here I'm not able to select for specific values because then I always get the value '1'.
When I set up an intermediate table as described below, I output all data, that I need
WITH MY_TEMP_TABLE AS
(
SELECT RANK() OVER (ORDER BY CODE ASC) MY_ROW, CODE, LAND
FROM SECOND_TABLE
)
SELECT *
FROM SECOND_TABLE
INNER JOIN MY_TEMP_TABLE ON SECOND_TABLE.CODE=MY_TEMP_TABLE.CODE
How is it possible to update the ID column in the database table (here: SECOND_TABLE) with the values in MY_ROW?
Thanks a lot...
Use row_number() instead of rank():
WITH MY_TEMP_TABLE AS
(
SELECT row_number() OVER (ORDER BY CODE ASC) MY_ROW, CODE, LAND
FROM SECOND_TABLE
)
SELECT *
FROM SECOND_TABLE
INNER JOIN MY_TEMP_TABLE ON SECOND_TABLE.CODE=MY_TEMP_TABLE.CODE

Assign ID to each row in Microsoft sql server view

Lets say I have a table like this:
create table MyTable (
Myname varchar (10) primary key not null
)
and a few row of data like:
insert into MyTable values ('john');
insert into MyTable values ('Brad');
insert into MyTable values ('James');
insert into MyTable values ('Anna');
insert into MyTable values ('Eric');
insert into MyTable values ('Hossein');
I want to create a view that assign an ID to each row,
I have used the select statement below :
select rank() OVER (ORDER BY Myname) as ID, MyTable.Myname
from MyTable
order by ID
The results is quite acceptable, But the problem come out when I try to create view
create view myview as
select rank() OVER (ORDER BY Myname) as ID, MyTable.Myname
from MyTable
order by ID
My questions are:
1- how can I create the view from the select statement mentioned above?
2- Is there any alternative way that I can use?
order by is not allowed in a view unless you use top. As per the documentation:
The SELECT clauses in a view definition cannot include the following:
An ORDER BY clause, unless there is also a TOP clause in the select list of the SELECT statement
So, your statement is fine without the order by:
create view myview as
select rank() OVER (ORDER BY Myname) as ID, MyTable.Myname
from MyTable ;
Even if you include the order by with a top, the results are not guaranteed in a particular order. You can only guarantee that by using order by the outer query.

How to retrieve specific rows from SQL Server table?

I was wondering is there a way to retrieve, for example, 2nd and 5th row from SQL table that contains 100 rows?
I saw some solutions with WHERE clause but they all assume that the column on which WHERE clause is applied is linear, starting at 1.
Is there other way to query a SQL Server table for a specific rows in case table doesn't have a column whose values start at 1?
P.S. - I know for a solution with temporary tables, where you copy your select statement output and add a linear column to the table. I am using T-SQL
Try this,
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ColumnName ASC) AS rownumber
FROM TableName
) as temptablename
WHERE rownumber IN (2,5)
With SQL Server:
; WITH Base AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM YourTable
)
SELECT *
FROM Base WHERE RN IN (2, 5)
The id that you'll have to replace with your primary key or your ordering, YourTable that is your table.
It's a CTE (Common Table Expression) so it isn't a temporary table. It's something that will be expanded together with your query.
There is no 2nd or 5th row in the table.
There is only the 2nd or 5th result in a resultset that you return, as determined by the order you specify in that query.
If you are on SQL Server 2005 or above, you could use Row_Number() function. Ex:
;With CTE as (
select col1, ..., row_number() over (order by yourOrderingCol) rn
from yourTable
)
select col1,...
from cte
where rn in (2,5)
Please note that yourOrderingCol will decide the value of row number (i.e. rn).

MSSQL Select statement with incremental integer column... not from a table

I need, if possible, a t-sql query that, returning the values from an arbitrary table, also returns a incremental integer column with value = 1 for the first row, 2 for the second, and so on.
This column does not actually resides in any table, and must be strictly incremental, because the ORDER BY clause could sort the rows of the table and I want the incremental row in perfect shape always.
The solution must run on SQL Server 2000
For SQL 2005 and up
SELECT ROW_NUMBER() OVER( ORDER BY SomeColumn ) AS 'rownumber',*
FROM YourTable
for 2000 you need to do something like this
SELECT IDENTITY(INT, 1,1) AS Rank ,VALUE
INTO #Ranks FROM YourTable WHERE 1=0
INSERT INTO #Ranks
SELECT SomeColumn FROM YourTable
ORDER BY SomeColumn
SELECT * FROM #Ranks
Order By Ranks
see also here Row Number
You can start with a custom number and increment from there, for example you want to add a cheque number for each payment you can do:
select #StartChequeNumber = 3446;
SELECT
((ROW_NUMBER() OVER(ORDER BY AnyColumn)) + #StartChequeNumber ) AS 'ChequeNumber'
,* FROM YourTable
will give the correct cheque number for each row.
Try ROW_NUMBER()
http://msdn.microsoft.com/en-us/library/ms186734.aspx
Example:
SELECT
col1,
col2,
ROW_NUMBER() OVER (ORDER BY col1) AS rownum
FROM tbl
It is ugly and performs badly, but technically this works on any table with at least one unique field AND works in SQL 2000.
SELECT (SELECT COUNT(*) FROM myTable T1 WHERE T1.UniqueField<=T2.UniqueField) as RowNum, T2.OtherField
FROM myTable T2
ORDER By T2.UniqueField
Note: If you use this approach and add a WHERE clause to the outer SELECT, you have to added it to the inner SELECT also if you want the numbers to be continuous.