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

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

Related

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)

How to find the Effective end Date for the below table using select statement only

How to find the Effective end Date for the below table using select statement only
This is the actual table:
EMID ENAME DEPT_NO EFDT
101 ANUJ 10 1/1/2018
101 ANUJ 11 1/1/2020
101 ANUJ 12 5/1/2020
102 KUNAL 12 1/1/2019
102 KUNAL 14 1/1/2020
102 KUNAL 15 5/1/2020
103 AJAY 11 1/1/2018
103 AJAY 12 1/1/2020
104 RAJAT 10 1/1/2018
104 RAJAT 12 1/1/2020
This is desired output:
EMID ENAME DEPTNO EFDT EF_ENDT
101 ANUJ 10 1/1/2018 12/31/2019
101 ANUJ 11 1/1/2020 4/30/2020
101 ANUJ 12 5/1/2020 NULL
102 KUNAL 12 1/1/2019 12/31/2019
102 KUNAL 14 1/1/2020 4/30/2020
102 KUNAL 15 5/1/2020 NULL
103 AJAY 11 1/1/2018 12/31/2019
103 AJAY 12 1/1/2020 NULL
104 RAJAT 10 1/1/2018 12/31/2019
104 RAJAT 12 1/1/2020 NULL
The EF_ENDT needs to be populated using the statement only.
How can we do this?
This code can be generic for all Database
Basically, you want a lead and then to subtract one day. The standard SQL for this is:
select t.*,
lead(efdt) over (partition by emid order by efdt) - interval '1 day' as ef_enddt
from t;
Date/time function vary significantly among databases. All provide some method for subtracting one day. You'll probably have to adapt this to your particular (unstated) database.

How to use the value in one table to count results in another table?

I want to add a new column on my SQL query that will count the number of times a value on the row appears in a different table.
For example, let's say I have these two separate tables.
Table Name: Table_A
Id | Coach | Team_Color | Team_Number
------------------------------------------
001 | Jane | Orange | 121
002 | Frank | Purple | 232
003 | Tim | Red | 343
Table Name: Table_B
Id | Team_Number | Player_Name
----------------------------------
901 | 121 | Jimmy
902 | 121 | Wesley
903 | 121 | Samantha
904 | 121 | Wendy
905 | 232 | Tim
906 | 232 | Sean
907 | 343 | Andrew
908 | 343 | Erik
909 | 343 | Sarah
910 | 343 | Allison
911 | 343 | Desmond
912 | 343 | Kathryn
I want to end up with something like this:
Id | Coach | Team_Color | Team_Number | Player Count
--------------------------------------------------------
001 | Jane | Orange | 121 | 4
002 | Frank | Purple | 232 | 2
003 | Tim | Red | 343 | 6
The new column called "Player Count" is referencing the Team_Number value in Table_A, and counting the number of instances found on Table_B. How would I compose this into one query?
Solution to your Problem:
SELECT A.Id, A.Coach, A.Team_Color,A.Team_Number,Count(B.Id) AS Player_Count
FROM Table_A AS A
INNER JOIN Table_B B
ON A.Team_Number = B.Team_Number
GROUP BY A.Id, A.Coach, A.Team_Color,A.Team_Number;
OUTPUT:
Id Coach Team_Color Team_Number Player_Count
1 Jane Orange 121 4
2 Frank Purple 232 2
3 Tim Red 343 6
Follow the link to the demo:
http://sqlfiddle.com/#!9/9c6da4/1
EXPLAINATION:
In your problem, you have to use JOIN to join the two tables on a common Column i.e.Team_Number. Now after Joining you will get a result like this:
Id Coach Team_Color Team_Number Id Team_Number Player_Name
1 Jane Orange 121 901 121 Jimmy
1 Jane Orange 121 902 121 Wesley
1 Jane Orange 121 903 121 Samantha
1 Jane Orange 121 904 121 Wendy
2 Frank Purple 232 905 232 Tim
2 Frank Purple 232 906 232 Sean
3 Tim Red 343 907 343 Andrew
3 Tim Red 343 908 343 Erik
3 Tim Red 343 909 343 Sarah
3 Tim Red 343 910 343 Allison
3 Tim Red 343 911 343 Desmond
3 Tim Red 343 912 343 Kathryn
Now Use aggregate function COUNT on above Result to get the final result.

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

Counting the duplicate and setting the record in calculated column in 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