Add Ordinal/Consecutive Value for similar values in table - sql

OK - I have a table with the following columns - what I need to do, is in instances where there is a same visit_no, I need to populate a int field with an ordinal number (priority) for each code - e.g. - so the "Priority" field is what I am looking to have populated - a new successive number for each "Code" value within the each similar "visit_no"
Visit_no Code Priority
123456 97110 1
445566 85025 1
445566 71402 2
445566 71020 3
789888 80053 1
789888 97110 2
111111 85025 1

Dense_Rank is a function which increments the rank only when the value your ordering on changes.
http://msdn.microsoft.com/en-ca/library/ms173825.aspx
Select Visit_no, Code, Priority = DENSE_RANK() OVER (Partition by Visit_No order by Code)
From YourTable

Related

SQL - Query to split original sort

I hope my title is ok as I really don’t know how to call it.
Anyway, I have a table with the following :
ID - Num (Primary Key)
Category - VarChar
Name - VarChar
DateForName - Date
Data looks like that :
1 100 111 31/12/2017
2 101 210 30/12/2017
3 100 112 29/12/2017
4 101 203 27/12/2017
5 100 117 20/12/2017
6 103 425 08/12/2017
To generate this table, I just sorted by date DESC.
Is there a way to add a new column with the order per Category like :
1 100|1
2 101|1
3 100|2
4 101|2
5 100|3
6 103|1
Max
You want analytical function row_number():
select t.*
from (select *, row_number() over (partition by Category order by date desc) Seq
from table
) t
order by id;
Yes, SQL has a couple options for you to add a column that is populated with a ranking of the rows based on the category and id columns.
If you just want to add a column to the select statement, I recommend using the RANK() function.
See more details here:
https://learn.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql?view=sql-server-2017
For your current table, try the following select statement:
SELECT
[ID],
[Category],
[Name],
[DateForName],
RANK() OVER (PARTITION BY [Category] ORDER BY [DateForName] DESC) AS [CategoryOrder]
FROM [TableName]
Alternatively, if you want to add a permanent column (aka a field) to the existing table, I recommend treating this as a calculated column. See more information here:
https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-2017
Because the new column would be completely based on two pre-existing columns and only those two columns. SQL can do a great job maintaining this for you.
Hope this helps!

Need to result of column based on available column in SQL

I am having one view which is returning the following result:
I need to put identifier just like below image
Required output:
Explanation of Output: If you can see the image 1 and in that image release 1 has 3 dates. From that I need to get 1 as an identifier for the MAX(IMPL_DATE).In RELEASE_ID = 1, We are having 08/20/2016, 08/09/2016 and 10/31/2016. From This 10/31/2016 is the largest date. So, Need Identifier as 1 and other 2 are going to be 0. Same thing with the RELEASE_ID 2 we have 2 dates and from them 01/13/2017 is the largest date so, need 1 in that row and other's going to be 0.
Thanks In advance...
You can do this with window functions:
select t.*,
(case when rank() over (partition by portfolio_id, release_id
order by impl_date desc
) = 1
then 1 else 0
end) as indentifier
from t;
The above will assign "1" to all rows with the maximum date. If you want to ensure that only one row is assigned a value (even when there are ties), then use row_number() instead of rank().

Oracle: how to group by 1st value in row?

Table has 3 columns in a table: ITEM, SUB_ITEM, DATE_CREATED.
ITEM - item id (string)
SUB_ITEM - item id (int)
DATE_CREATE - date the SUB_ITEM was created (date)
Scenario:
There are 3 Different item's (AAA1, AAB2, ABB3)
All 3 of these item's have multiple sub-items.
Each item has a sub-item that is the same for each of them (eg. All 3 of the item's have a SUB_ITEM = 101010)
I am trying to do something like:
select *
from table
group by ITEM, SUB_ITEM, DATE_CREATED
How do you make it display only 1 row? I don't care if it chooses AAA1 or AAB2 or ABB3, I just want it to pick 1 and remove the rest so it will show 1 row per SUB_ITEM, but still displays at least one of the parent items.
Edit:
Thank you to mathguy for answering the above question.
Question 2:
Is it possible to group by the 1st 2 letters of the item in addition to the sub_item? So instead of returning 1 row, return 2 rows: AAA1 and AAB2 will cascade in to 1 row, and ABB3 will be the 2nd row because 'AA' and 'AB' are different.
Edit 2: See Main Answer comments for answer to question 2
One way is to group by sub_item, and take the max or min over another column (let's say max over date_created) and whatever is in the remaining column IN THE SAME ROW.
select min(item) keep (dense_rank last order by date_created) as item,
sub_item, max(date_created) as date_created
from table_name
group by sub_item
;

Access SQL how to make an increment in SELECT query

I Have an SQL query giving me X results, I want the query output to have a coulmn called
count making the query somthing like this:
count id section
1 15 7
2 3 2
3 54 1
4 7 4
How can I make this happen?
So in your example, "count" is the derived sequence number? I don't see what pattern is used to determine the count must be 1 for id=15 and 2 for id=3.
count id section
1 15 7
2 3 2
3 54 1
4 7 4
If id contained unique values, and you order by id you could have this:
count id section
1 3 2
2 7 4
3 15 7
4 54 1
Looks to me like mikeY's DSum approach could work. Or you could use a different approach to a ranking query as Allen Browne described at this page
Edit: You could use DCount instead of DSum. I don't know how the speed would compare between the two, but DCount avoids creating a field in the table simply to store a 1 for each row.
DCount("*","YourTableName","id<=" & [id]) AS counter
Whether you go with DCount or DSum, the counter values can include duplicates if the id values are not unique. If id is a primary key, no worries.
I frankly don't understand what it is you want, but if all you want is a sequence number displayed on your form, you can use a control bound to the form's CurrentRecord property. A control with the ControlSource =CurrentRecord will have an always-accurate "record number" that is in sequence, and that will update when the form's Recordsource changes (which may or may not be desirable).
You can then use that number to navigate around the form, if you like.
But this may not be anything like what you're looking for -- I simply can't tell from the question you've posted and the "clarifications" in comments.
The only trick I have seen is if you have a sequential id field, you can create a new field in which the value for each record is 1. Then you do a running sum of that field.
Add to your query
DSum("[New field with 1 in it]","[Table Name]","[ID field]<=" & [ID Field])
as counterthing
That should produce a sequential count in Access which is what I think you want.
HTH.
(Stolen from Rob Mills here:
http://www.access-programmers.co.uk/forums/showthread.php?p=160386)
Alright, I guess this comes close enough to constitute an answer: the following link specifies two approaches: http://www.techrepublic.com/blog/microsoft-office/an-access-query-that-returns-every-nth-record/
The first approach assumes that you have an ID value and uses DCount (similar to #mikeY's solution).
The second approach assumes you're OK creating a VBA function that will run once for EACH record in the recordset, and will need to be manually reset (with some VBA) every time you want to run the count - because it uses a "static" value to run its counter.
As long as you have reasonable numbers (hundreds, not thousands) or records, the second approach looks like the easiest/most powerful to me.
This function can be called from each record if available from a module.
Example: incrementingCounterTimeFlaged(10,[anyField]) should provide your query rows an int incrementing from 0.
'provides incrementing int values 0 to n
'resets to 0 some seconds after first call
Function incrementingCounterTimeFlaged(resetAfterSeconds As Integer,anyfield as variant) As Integer
Static resetAt As Date
Static i As Integer
'if reset date < now() set the flag and return 0
If DateDiff("s", resetAt, Now()) > 0 Then
resetAt = DateAdd("s", resetAfterSeconds, Now())
i = 0
incrementingCounterTimeFlaged = i
'if reset date > now increments and returns
Else
i = i + 1
incrementingCounterTimeFlaged = i
End If
End Function
autoincrement in SQL
SELECT (Select COUNT(*) FROM table A where A.id<=b.id),B.id,B.Section FROM table AS B ORDER BY B.ID Asc
You can use ROW_NUMBER() which is in SQL Server 2008
SELECT ROW_NUMBER() OVER (ORDER By ID DESC) RowNum,
ID,
Section
FROM myTable
Then RowNum displays sequence of row numbers.

Oracle Partitioned Sequence

I'm trying to see if exists something to create a sequence with partition logic.
I need a sequence number that depend on other primary key ex:
id_person sequence id
1 | 1
1 | 2
2 | 1
3 | 1
1 | 3
so the sequence must depend on the id_person partition. Is there something like this on oracle or i must implement it by myself on the application level?
thank you.
Hi have create this PLSQL package one function and procedure:
PROCEDURE INIT_SEQUENCE(NAME varchar2, pkColumnNameList PARTITIONED_SEQUENCE_PK_COLUMN);
FUNCTION GET_NEXT_SEQUENCE_VALUE(NAME varchar2, pkPartitionColValue PARTITIONED_SEQUENCE_COL_VALUE) RETURN NUMBER;
INIT_SEQUENCE - get in input the name to associate at the sequence and a list of column name that are the fixed primary key part that vincolate the sequence Ex:'ID_PERSON'
the work of this procedure is to create the table that will manage the increment of sequence according to pkColumnNameList column.
GET_NEXT_SEQUENCE_VALUE- get the name of sequence to increment and the value of pkColumnNameList primary key and make the next step:
1) Create dynamically the sql to work
2) dbms_lock.allocate_unique(); to lock the table
3) check if is present a record in the table for pk value in input
4) if a record is present update the record with max + 1 in the sequence column
5) if a record is not present insert the new record with the 1 in the sequence column
6) return new id;
i would like to receive comment about this thanks in advance...
Is the actual requirement that the secondary sequence be gap free? If so, you've got a giant serialization/scalability issue.
If you need to present a gap-free sequence for human consumption, you could use an actual sequence (or a timestamp, for that matter) as Nick Pierpont suggests and preserve scalability, you could use analytic functions.
Dataset (t1):
ID_PERSON SEQUENCE_ID
---------- -----------
1 1
2 2
3 3
1 4
1 5
1 6
2 7
3 8
1 9
SQL:
select *
from
(select id_person,
sequence_id as orig_sequence_id,
rank ()
over (partition by id_person
order by sequence_id)
as new_sequence_id
from t1
)
order by id_person, new_sequence_id;
Result:
ID_PERSON ORIG_SEQUENCE_ID NEW_SEQUENCE_ID
---------- ---------------- ---------------
1 1 1
1 4 2
1 5 3
1 6 4
1 9 5
2 2 1
2 7 2
3 3 1
3 8 2
I'm afraid you have to do it like this:
INSERT INTO t
(
id_person,
sequence_id
)
VALUES
(
<your_person_id>,
( SELECT 1 + NVL( MAX( sequence_id ), 0 )
FROM t
WHERE t.id_person = <your_person_id>
)
)
What you are looking for is not a sequence, as the Oracle Documentation claims: "The sequence generator provides a sequential series of numbers".
You are looking for a calculated field depending on another, in this case the primary key. As other suggested you need to add the logic on your code. It means in a procedure or in the insert sentence.