Counting the duplicate and setting the record in calculated column in SQL - sql

I have a table Student_Information, with columns and data like:
ID StudentName FatherName NIC No_of_Childrens Date_of_Birth Date_of_Admission
1 Mark John 85 2010-04-01 2015-04-19
2 Akbar Aslam 89 2009-05-01 2015-04-19
3 Percul John 85 2010-04-01 2015-04-19
4 Ali Aslam 89 2009-05-01 2015-04-19
5 Diglor John 85 2010-04-01 2015-04-19
6 Sabi Aslam 89 2009-05-01 2015-04-19
I want to count the NIC column for duplicates and give numbers to no of childs column. Like this:
ID StudentName FatherName NIC No_of_Childrens Date_of_Birth Date_of_Admission
1 Mark John 85 1 2010-04-01 2015-04-19
2 Akbar Aslam 89 1 2009-05-01 2015-04-19
3 Percul John 85 2 2010-04-01 2015-04-19
4 Ali Aslam 89 2 2009-05-01 2015-04-19
5 Diglor John 85 3 2010-04-01 2015-04-19
6 Sabi Aslam 89 3 2009-05-01 2015-04-19

Try the below snippet -
SELECT ID, StudentName, FatherName, NIC,No_of_Childrens,Date_of_Birth, Date_of_Admission
FROM
(
SELECT ID, StudentName, FatherName, NIC,Date_of_Birth, Date_of_Admission,No_of_Childrens = RANK() OVER(PARTITION BY NIC ORDER BY ID)
FROM Student_Information) A ORDER BY ID

Related

SQL Server: Two Level Sort (Order/Group By??)

Everyone:
I have the following code which produced the below table:
SELECT DISTINCT a.[Date]
,a.[ID]
,a.[Account]
,a.[First_Last]
FROM [Table] AS a
WHERE [First_Last] = 1 OR
[First_Last] = (
SELECT MAX([First_Last])
FROM [Table] AS b
WHERE a.[ID] = b.[ID] AND a.[Account] = b.[Account]
)
ORDER BY [ID], [Account], [Date]
Date ID Account First_Last
10/31/2018 1111 45 1
1/29/2021 1111 45 4
9/29/2017 1111 753 1
9/28/2018 1111 753 2
9/29/2017 2222 481 1
1/31/2018 2222 481 2
10/31/2017 2222 488 1
1/31/2018 2222 488 2
11/30/2017 2222 582 1
1/31/2019 2222 582 3
2/28/2017 2222 621 1
2/28/2018 2222 621 2
6/30/2017 2222 1007 1
6/29/2018 2222 1007 2
But I need it to be ordered this way:
Date ID Account First_Last
9/29/2017 1111 753 1
9/28/2018 1111 753 2
10/31/2018 1111 45 1
1/29/2021 1111 45 4
2/28/2017 2222 621 1
2/28/2018 2222 621 2
6/30/2017 2222 1007 1
6/29/2018 2222 1007 2
9/29/2017 2222 481 1
1/31/2018 2222 481 2
10/31/2017 2222 488 1
1/31/2018 2222 488 2
11/30/2017 2222 582 1
1/31/2019 2222 582 3
Notice that the table I need is not sorted by Account. It is sorted by Date for each ID-Account combination. For example, for ID = 1111, Account 753 comes before Account 45 because 753's first date is 9/29/2017 and 45's first date is 10/31/2018. Since I do not want Account to be sorted, I tried to remove Account from the ORDER BY, but that put the Account numbers in random lines because of Date instead of grouping them together.
What am I missing?
Thank you.
You can use window function to find the "first date" by ID and Account.
order by ID,
min([Date]) over(partition by ID, Account),
[Date]

How to change the Row Number behavior in my T-SQL Query?

I am using SQL Server 2014 and I have the following T-SQL query running against a table (tbl1).
Extract of tbl1:
emp_code Name Address Company
---------------------------------------
100 Peter London ABC
125 Allan Cambridge DCE
125 Allan Cambridge DCE
115 John Suffolk ABC
115 John Suffolk XYZ
154 Mary Highlands ABC
154 Mary Bristol ABC
124 Mary Chester ABC
My T-SQL query stands as follows:
SELECT
[ID],
[Name],
[Address],
[Company],
ROW_NUMBER() OVER (PARTITION BY [emp_code] ORDER BY [Address]) AS RowNumber
FROM
[tbl1]
Output from above query:
emp_code Name Address Company RowNumber
--------------------------------------------------------
100 Peter London ABC 1
125 Allan Cambridge DCE 1
125 Allan Cambridge DCE 2
115 John Suffolk ABC 1
115 John Suffolk XYZ 2
154 Mary Highlands ABC 1
154 Mary Bristol ABC 2
154 Mary Chester ABC 3
Output I'm after:
emp_code Name Address Company RowNumber
---------------------------------------------------------
100 Peter London ABC 1
125 Allan Cambridge DCE 1
125 Allan Cambridge DCE 1
115 John Suffolk ABC 1
115 John Suffolk XYZ 1
154 Mary Highlands ABC 1
154 Mary Bristol ABC 2
154 Mary Chester ABC 3
I want my RowNumber (or change the column name if need be) to change based on the [Address] column for each [emp_code]. If the employee has the SAME address, it should have the same value (that is, 1). Else, it should give the values as in the case of employee "Mary" (above output).
I am assuming the Row_Number() function is not the right one to be used for what I'm after.
Any help would be appreciated.
I think you want DENSE_RANK here rather than ROW_NUMBER():
SELECT [ID], [Name], [Address], [Company],
DENSE_RANK() OVER (PARTITION BY [emp_code]
ORDER BY [Address]) AS DenseRank
FROM [tbl1];
Demo

Getting an element and the next from a table

I have a table with ids, cities and some sequence number, say:
ID CITY SEQ_NO
1 Milan 123
2 Paris 124
1 Rome 125
1 Naples 126
1 Strasbourg 130
3 London 129
3 Manchester 132
2 Strasbourg 128
3 Rome 131
2 Rome 127
4 Moscow 135
5 New York 136
4 Helsinki 137
I want to get the city that comes after Rome for the same id, in this case, I can order them by doing something like:
SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY SEQ_NO) as rownum,
id,
city,
seq_no
FROM mytable
I get:
rownum ID CITY SEQ_NO
1 1 Milan 123
2 1 Rome 125
3 1 Naples 126
4 1 Strasbourg 130
1 2 Paris 124
2 2 Rome 127
3 2 Strasbourg 128
1 3 London 129
2 3 Rome 131
3 3 Manchester 132
1 4 Moscow 135
2 4 Helsinki 137
1 5 New York 136
and, I want to get
ID CITY SEQ_NO
1 Rome 125
1 Naples 126
2 Rome 127
2 Strasbourg 128
3 Rome 131
3 Manchester 132
How do I proceed?
Hmmm . . . I might suggest window functions:
select t.*
from (select t.*,
lag(city) over (partition by id order by seq_no) as prev_city
from mytable t
) t
where 'Rome' in (city, prev_city)

grouping a table with different dates

I have a table like below,
SalesId ItemId DateSale USDVal
ABC 01A 2018-04-01 52
ABC 01B 2018-04-01 300
ABC 01C 2018-04-01 12
ABC 01D 2018-04-01 62
ABC 01A 2018-03-23 66
MNB 01A 2018-01-01 584
MNB 01A 2018-02-20 320
MNB 01F 2018-02-20 5
I want to write a query that selects the last date for each SalesId and shows those records so the result would look something like below.
Result
SalesId ItemId DateSale USDVal
ABC 01A 2018-04-01 52
ABC 01B 2018-04-01 300
ABC 01C 2018-04-01 12
ABC 01D 2018-04-01 62
MNB 01A 2018-02-20 320
MNB 01F 2018-02-20 5
In SQL Server, the fastest way is often a correlated subquery:
select t.*
from t
where t.datesale = (select max(t2.datesale) from t t2 where t2.salesid = t.salesid);

SQL server select from 3 tables

I have three tables in my database Books, Borrowers and Movement:
Books
BookID Title Author Category Published
----------- ------------------------------ ------------------------- --------------- ----------
101 Ulysses James Joyce Fiction 1922-06-16
102 Huckleberry Finn Mark Twain Fiction 1884-03-24
103 The Great Gatsby F. Scott Fitzgerald Fiction 1925-06-17
104 1984 George Orwell Fiction 1949-04-19
105 War and Peace Leo Tolstoy Fiction 1869-08-01
106 Gullivers Travels Jonathan Swift Fiction 1726-07-01
107 Moby Dick Herman Melville Fiction 1851-08-01
108 Pride and Prejudice Jane Austen Fiction 1813-08-13
110 The Second World War Winston Churchill NonFiction 1953-09-01
111 Relativity Albert Einstein NonFiction 1917-01-09
112 The Right Stuff Tom Wolfe NonFiction 1979-09-07
121 Hitchhikers Guide to Galaxy Douglas Adams Humour 1975-10-27
122 Dad Is Fat Jim Gaffigan Humour 2013-03-01
131 Kick-Ass 2 Mark Millar Comic 2012-03-03
133 Beautiful Creatures: The Manga Kami Garcia Comic 2014-07-01
Borrowers
BorrowerID Name Birthday
----------- ------------------------- ----------
2 Bugs Bunny 1938-09-08
3 Homer Simpson 1992-09-09
5 Mickey Mouse 1928-02-08
7 Fred Flintstone 1960-06-09
11 Charlie Brown 1965-06-05
13 Popeye 1933-03-03
17 Donald Duck 1937-07-27
19 Mr. Magoo 1949-09-14
23 George Jetson 1948-04-08
29 SpongeBob SquarePants 1984-08-04
31 Stewie Griffin 1971-11-17
Movement
MoveID BookID BorrowerID DateOut DateIn ReturnCondition
----------- ----------- ----------- ---------- ---------- ---------------
1 131 31 2012-06-01 2013-05-24 good
2 101 23 2012-02-10 2012-03-24 good
3 102 29 2012-02-01 2012-04-01 good
4 105 7 2012-03-23 2012-05-11 good
5 103 7 2012-03-22 2012-04-22 good
6 108 7 2012-01-23 2012-02-12 good
7 112 19 2012-01-12 2012-02-10 good
8 122 11 2012-04-14 2013-05-01 poor
9 106 17 2013-01-24 2013-02-01 good
10 104 2 2013-02-24 2013-03-10 bitten
11 121 3 2013-03-01 2013-04-01 good
12 131 19 2013-04-11 2013-05-23 good
13 111 5 2013-05-22 2013-06-22 poor
14 131 2 2013-06-12 2013-07-23 bitten
15 122 23 2013-07-10 2013-08-12 good
16 107 29 2014-01-01 2014-02-14 good
17 110 7 2014-01-11 2014-02-01 good
18 105 2 2014-02-22 2014-03-02 bitten
What is a query I can use to find out which book was borrowed by the oldest borrower?
I am new to SQL and am using Microsoft SQL Server 2014
Here are two different solutions:
First using two sub querys and one equi-join:
select Title
from Books b , Movement m
where b.BookID = m.BookID and m.BorrowerID = (select BorrowerID
from Borrowers
where Birthday = (select MIN(Birthday)
from Borrowers))
Using two equi-joins and one sub query:
select Title
from Books b, Borrowers r, Movement m
where b.BookID = m.BookID
and m.BorrowerID = r.BorrowerID
and Birthday = (select MIN(Birthday) from Borrowers)
Both above queries give the following answer:
Title
------------------------------
Relativity