Vous êtes sur la page 1sur 64

What is the difference between inner and outer join? Explain with example.

Inner Join
Inner join is the most common type of Join which is used to combine the rows from two tables
and create a result set containing only such records that are present in both the tables based on
the joining condition (predicate).
Inner join returns rows when there is at least one match in both tables
If none of the record matches between two tables, then INNER JOIN will return a NULL set.
Below is an example of INNER JOIN and the resulting set.
SELECT dept.name DEPARTMENT, emp.name EMPLOYEE
FROM DEPT dept, EMPLOYEE emp
WHERE emp.dept_id = dept.id
Department

Employee

HR

Inno

HR

Privy

Engineering

Robo

Engineering

Hash

Engineering

Anno

Engineering

Darl

Marketing

Pete

Marketing

Meme

Sales

Tomiti

Sales

Bhuti

Outer Join
Outer Join can be full outer or single outer

Outer Join, on the other hand, will return matching rows from both tables as well as any
unmatched rows from one or both the tables (based on whether it is single outer or full outer join
respectively).
Notice in our record set that there is no employee in the department 5 (Logistics). Because of this
if we perform inner join, then Department 5 does not appear in the above result. However in the
below query we perform an outer join (dept left outer join emp), and we can see this department.
SELECT dept.name DEPARTMENT, emp.name EMPLOYEE
FROM DEPT dept, EMPLOYEE emp
WHERE dept.id = emp.dept_id (+)
Department

Employee

HR

Inno

HR

Privy

Engineering

Robo

Engineering

Hash

Engineering

Anno

Engineering

Darl

Marketing

Pete

Marketing

Meme

Sales

Tomiti

Sales

Bhuti

Logistics
The (+) sign on the emp side of the predicate indicates that emp is the outer table here. The
above SQL can be alternatively written as below (will yield the same result as above):
SELECT dept.name DEPARTMENT, emp.name EMPLOYEE
FROM DEPT dept LEFT OUTER JOIN EMPLOYEE emp
ON dept.id = emp.dept_id
What is the difference between JOIN and UNION?

SQL JOIN allows us to lookup records on other table based on the given conditions between
two tables. For example, if we have the department ID of each employee, then we can use this
department ID of the employee table to join with the department ID of department table to
lookup department names.
UNION operation allows us to add 2 similar data sets to create resulting data set that contains all
the data from the source data sets. Union does not require any condition for joining. For
example, if you have 2 employee tables with same structure, you can UNION them to create one
result set that will contain all the employees from both of the tables.
SELECT * FROM EMP1
UNION
SELECT * FROM EMP2;
What is the difference between UNION and UNION ALL?
UNION and UNION ALL both unify for add two structurally similar data sets, but UNION
operation returns only the unique records from the resulting data set whereas UNION ALL will
return all the rows, even if one or more rows are duplicated to each other.
In the following example, I am choosing exactly the same employee from the emp table and
performing UNION and UNION ALL. Check the difference in the result.
SELECT * FROM EMPLOYEE WHERE ID = 5
UNION ALL
SELECT * FROM EMPLOYEE WHERE ID = 5
ID

MGR_ID

DEPT_ID

NAME

SAL

DOJ

5.0

2.0

2.0

Anno

80.0

01-Feb-2012

5.0

2.0

2.0

Anno

80.0

01-Feb-2012

SELECT * FROM EMPLOYEE WHERE ID = 5


UNION
SELECT * FROM EMPLOYEE WHERE ID = 5
ID

MGR_ID

DEPT_ID

NAME

SAL

DOJ

5.0

2.0

2.0

Anno

80.0

01-Feb-2012

What is the difference between WHERE clause and HAVING clause?

WHERE and HAVING both filters out records based on one or more conditions. The difference
is, WHERE clause can only be applied on a static non-aggregated column whereas we will need
to use HAVING for aggregated columns.
To understand this, consider this example.
Suppose we want to see only those departments where department ID is greater than 3. There is
no aggregation operation and the condition needs to be applied on a static field. We will use
WHERE clause here:
SELECT * FROM DEPT WHERE ID > 3
ID

NAME

Sales

Logistics

Next, suppose we want to see only those Departments where Average salary is greater than 80.
Here the condition is associated with a non-static aggregated information which is average of
salary. We will need to use HAVING clause here:
SELECT dept.name DEPARTMENT, avg(emp.sal) AVG_SAL
FROM DEPT dept, EMPLOYEE emp
WHERE dept.id = emp.dept_id (+)
GROUP BY dept.name
HAVING AVG(emp.sal) > 80
DEPARTMENT

AVG_SAL

Engineering

90

As you see above, there is only one department (Engineering) where average salary of
employees is greater than 80.
What is the difference among UNION, MINUS and INTERSECT?
UNION combines the results from 2 tables and eliminates duplicate records from the result set.
MINUS operator when used between 2 tables, gives us all the rows from the first table except the
rows which are present in the second table.
INTERSECT operator returns us only the matching or common rows between 2 result sets.

To understand these operators, lets see some examples. We will use two different queries to
extract data from our emp table and then we will perform UNION, MINUS and INTERSECT
operations on these two sets of data.
UNION
SELECT * FROM EMPLOYEE WHERE ID = 5
UNION
SELECT * FROM EMPLOYEE WHERE ID = 6
ID

MGR_ID

DEPT_ID

NAME

SAL

DOJ

2.0

Anno

80.0

01-Feb-2012

2.0

Darl

80.0

11-Feb-2012

DEPT_ID

NAME

SAL

DOJ

Hash

100.0

01-Jan-2012

Robo

100.0

01-Jan-2012

MINUS
SELECT * FROM EMPLOYEE
MINUS
SELECT * FROM EMPLOYEE WHERE ID > 2
ID

MGR_ID

1
2

INTERSECT
SELECT * FROM EMPLOYEE WHERE ID IN (2, 3, 5)
INTERSECT
SELECT * FROM EMPLOYEE WHERE ID IN (1, 2, 4, 5)
ID

MGR_ID

DEPT_ID

NAME

SAL

DOJ

Anno

80.0

01-Feb-2012

Robo

100.0

01-Jan-2012

What is Self Join and why is it required?


Self Join is the act of joining one table with itself.
Self Join is often very useful to convert a hierarchical structure into a flat structure
In our employee table example above, we have kept the manager ID of each employee in the
same row as that of the employee. This is an example of how a hierarchy (in this case employeemanager hierarchy) is stored in the RDBMS table. Now, suppose if we need to print out the
names of the manager of each employee right beside the employee, we can use self join. See the
example below:
SELECT e.name EMPLOYEE, m.name MANAGER
FROM EMPLOYEE e, EMPLOYEE m
WHERE e.mgr_id = m.id (+)
EMPLOYEE

MANAGER

Pete

Hash

Darl

Hash

Inno

Hash

Robo

Hash

Tomiti

Robo

Anno

Robo

Privy

Robo

Meme

Pete

Bhuti

Tomiti

Hash
The only reason we have performed a left outer join here (instead of INNER JOIN) is we have
one employee in this table without a manager (employee ID = 1). If we perform inner join, this
employee will not show-up.
How can we transpose a table using SQL (changing rows to column or vice-versa) ?
The usual way to do it in SQL is to use CASE statement or DECODE statement.

How to generate row number in SQL Without ROWNUM


Generating a row number that is a running sequence of numbers for each row is not easy using
plain SQL. In fact, the method I am going to show below is not very generic either. This method
only works if there is at least one unique column in the table. This method will also work if there
is no single unique column, but collection of columns that is unique. Anyway, here is the query:
SELECT name, sal, (SELECT COUNT(*) FROM EMPLOYEE i WHERE o.name >= i.name)
row_num
FROM EMPLOYEE o
order by row_num
NAME

SAL

ROW_NUM

Anno

80

Bhuti

60

Darl

80

Hash

100

Inno

50

Meme

60

Pete

70

Privy

50

Robo

100

Tomiti

70

10

The column that is used in the row number generation logic is called sort key. Here sort key is
name column. For this technique to work, the sort key needs to be unique. We have chosen the
column name because this column happened to be unique in our Employee table. If it was not
unique but some other collection of columns was, then we could have used those columns as our
sort key (by concatenating those columns to form a single sort key).
Also notice how the rows are sorted in the result set. We have done an explicit sorting on the
row_num column, which gives us all the row numbers in the sorted order. But notice that name
column is also sorted (which is probably the reason why this column is referred as sort-key). If
you want to change the order of the sorting from ascending to descending, you will need to
change >= sign to <= in the query.

As I said before, this method is not very generic. This is why many databases already implement
other methods to achieve this. For example, in Oracle database, every SQL result set contains a
hidden column called ROWNUM. We can just explicitly select ROWNUM to get sequence
numbers.
How to select first 5 records from a table?
This question, often asked in many interviews, does not make any sense to me. The
problem here is how do you define which record is first and which is second. Which
record is retrieved first from the database is not deterministic. It depends on many
uncontrollable factors such as how database works at that moment of execution etc. So the
question should really be how to select any 5 records from the table? But whatever it
is, here is the solution:
In Oracle,
SELECT *
FROM EMP
WHERE ROWNUM <= 5;
In SQL Server,
SELECT TOP 5 * FROM EMP;
Generic solution,
I believe a generic solution can be devised for this problem if and only if there exists at least one
distinct column in the table. For example, in our EMP table ID is distinct. We can use that
distinct column in the below way to come up with a generic solution of this question that does
not require database specific functions such as ROWNUM, TOP etc.
SELECT name
FROM EMPLOYEE o
WHERE (SELECT count(*) FROM EMPLOYEE i WHERE i.name < o.name) < 5
Name
Inno
Anno
Darl
Meme

Bhuti
I have taken name column in the above example since name is happened to be unique in this
table. I could very well take ID column as well.
In this example, if the chosen column was not distinct, we would have got more than 5 records
returned in our output.
Do you have a better solution to this problem? If yes, post your solution in the comment.
What is the difference between ROWNUM pseudo column and ROW_NUMBER()
function?
ROWNUM is a pseudo column present in Oracle database returned result set prior to ORDER
BY being evaluated. So ORDER BY ROWNUM does not work.
ROW_NUMBER() is an analytical function which is used in conjunction to OVER() clause
wherein we can specify ORDER BY and also PARTITION BY columns.
Suppose if you want to generate the row numbers in the order of ascending employee salaries for
example, ROWNUM will not work. But you may use ROW_NUMBER() OVER() like shown
below:
SELECT name, sal, row_number() over(order by sal desc) rownum_by_sal
FROM EMPLOYEE o
name

Sal

ROWNUM_BY_SAL

Hash

100

Robo

100

Anno

80

Darl

80

Tomiti

70

Pete

70

Bhuti

60

Meme

60

Inno

50

Privy

50

10

What are the differences among ROWNUM, RANK and DENSE_RANK?


ROW_NUMBER assigns contiguous, unique numbers from 1.. N to a result set.
RANK does not assign unique numbersnor does it assign contiguous numbers. If two records
tie for second place, no record will be assigned the 3rd rank as no one came in third, according to
RANK. See below:
SELECT name, sal, rank() over(order by sal desc) rank_by_sal
FROM EMPLOYEE o
name

Sal

RANK_BY_SAL

Hash

100

Robo

100

Anno

80

Darl

80

Tomiti

70

Pete

70

Bhuti

60

Meme

60

Inno

50

Privy

50

DENSE_RANK, like RANK, does not assign unique numbers, but it does assign contiguous
numbers. Even though two records tied for second place, there is a third-place record. See below:
SELECT name, sal, dense_rank() over(order by sal desc) dense_rank_by_sal
FROM EMPLOYEE o
name

Sal

DENSE_RANK_BY_SAL

Hash

100

Robo

100

Anno

80

Darl

80

Tomiti

70

Pete

70

Bhuti

60

Meme

60

Inno

50

Privy

50

Joining Multiple Tables with SQL Inner Join Statements


By Mike Chapple
Ad
Ads
Scaffoldingwww.cityscaffoldings.inLeading Supplier of Best Quality Scaffoldings. Enquire for Details.
Database Managementwww.synametrics.comWinSQL - A Homogeneous Solution for Heterogeneous Environm
Business Opportunitywww.hktdc.comConnect with over 120,000 suppliers from Hong Kong, China and Taiwa
See More About
sql
inner joins
You can use SQL JOIN statements to combine data from three or more tables. In an earlier
article, we took a look at using inner joins and outer joins to combine data from two different
tables. In many cases, youll want to take this a step further and combine data from three or
more tables.
Fortunately, SQL JOINs are extremely flexible and it is possible to use this powerful
functionality to combine data from multiple tables. Let's take a look at the SQL statements that
allow you to combine results from three different tables using an inner join.
You may recall from our basic inner join example that the SQL statement below combines
data from the Drivers and Vehicles tables in cases where the driver and vehicle are located in
the same city:
SELECT lastname, firstname, tag
FROM drivers, vehicles
WHERE drivers.location = vehicles.location
This query produced the following results:
lastname firstname tag

-------- --------- --Baker Roland H122JM


Smythe Michael D824HA
Smythe Michael P091YF
Jacobs Abraham J291QR
Jacobs Abraham L990MT
Now, lets extend this example to include a third table. Imagine that you wanted to include
only drivers and vehicles present at locations that are open on the weekend. You could bring a
third table into your query by extending the JOIN statement as follows:
SELECT lastname, firstname, tag, open_weekends
FROM drivers, vehicles, locations
WHERE drivers.location = vehicles.location
AND vehicles.location = locations.location
AND locations.open_weekends = 'Yes'
lastname firstname tag open_weekends
-------- --------- --- ------------Baker Roland H122JM yes
Jacobs Abraham J291QR yes
Jacobs Abraham L990MT yes
This powerful extension to the basic SQL JOIN statement allows you to combine data in a
complex manner. In addition to combining tables with an inner join, you can also use this
technique to combine multiple tables using an outer join. As you may recall, outer joins
include results that exist in one table but do not have a corresponding match in the joined
table.

Retrieving Data from Multiple Tables with SQL Joins


Part 1: Introducing Joins
More of this Feature
Part 2: Inner Joins
Part 3: Outer Joins
Join the Discussion
"Share your questions and
tap the knowledge of
hundreds of your peers."
Mike Chapple
Related Resources
SQL Fundamentals
Creating Databases and

In several recent articles we explored the fundamental concepts of


Tables in SQL
SQL, the process of creating databases and database tables and the art Retrieving Data with
of retrieving data from a database using simple queries. This article SQL Queries
expands on these topics and looks at using join techniques to retrieve
data from multiple tables.
By way of example, let's return to our fictitious XYZ Corporation. XYZ utilizes an Oracle
database to track the movements of their vehicle fleet and drivers between their facilities. Some
employees are assigned to drive trucks while others are assigned to drive cars. Take a moment to
examine the following two tables from their vehicle management database:
drivers
licensenum

lastname

firstname location
class

13232

Baker

Roland

New York
Car

18431

Smythe

Michael

Miami
Truck

41948

Jacobs

Abraham

Seattle
Car

81231

Ryan

Jack

Annapolis

vehicles
tag

location
class

D824HA

Miami
Truck

H122JM

New York
Car

Car

J291QR

Seattle
Car

L990MT

Seattle
Truck

P091YF

Miami
Car

Ads
PHP Forumwww.daniweb.comFree community help & discussion Engage with savvy web
developers
OPC To Sqlwww.matrikonopc.com/OPCDatabasesEasily store OPC to databases. Easy to use,
Free to try.
Find & Remove Duplicateswww.cloudingo.comGet rid of duplicates in your CRM From the
makers of DupeCatcher!
In the previous article, we looked at methods used to retrieve data from single tables. For
example, we could use simple SELECT statements to answer questions such as:
Which drivers are located in New York?
How many cars are in each city?
Which drivers assigned to drive trucks are located in Miami?
Practical applications often require the combination of data from multiple tables. Our vehicle
managers might make requests like the following:
List all of the vehicle/driver pairings possible without relocating a vehicle or driver
List all of the drivers authorized to drive vehicles located in Miami
Granted, it would be possible to create complex SELECT statements using subqueries to fulfill
these requests. However, there's a much simpler method -- the use of inner and outer joins. We'll
explore each of these concepts in the next two sections of this article. Read on!
Retrieving Data from Multiple Tables with SQL Joins
Part 2: Inner Joins (Equijoins)
More of this Feature

Part 1: Introducing Joins


Inner joins (also known as equijoins) are used to contain information Part 3: Outer Joins
from a combination of two or more tables. The join condition
determines which records are paired together and is specified in the
Join the Discussion
WHERE clause. For example, let's create a list of driver/vehicle
"Share your questions
match-ups where both the vehicle and driver are located in the same and tap the knowledge of
city. The following SQL query will accomplish this task:
hundreds of your peers."
Mike Chapple
SELECT lastname, firstname, tag
FROM drivers, vehicles
Related Resources
WHERE drivers.location = vehicles.location
SQL Fundamentals
Creating Databases and
Tables in SQL
And let's take a look at the results:
Retrieving Data with
SQL Queries
lastname firstname
tag
-----------------Baker
Roland
H122JM
Smythe
Michael
D824HA
Smythe
Michael
P091YF
Jacobs
Abraham
J291QR
Jacobs
Abraham
L990MT
Notice that the results are exactly what we sought. It is possible to further refine the query by
specifying additional criteria in the WHERE clause. Our vehicle managers took a look at the
results of our last query and noticed that the previous query matches drivers to vehicles that they
are not authorized to drive (e.g. truck drivers to cars and vice-versa). We can use the following
query to resolve this problem:
Ads
Database Managementwww.synametrics.comWinSQL - A Homogeneous Solution for
Heterogeneous Environment.
Clinical Data Serviceswww.quartesian.comData Management, Biostatistics, Programming &
Medical Writing
Scaffoldingwww.cityscaffoldings.inLeading Supplier of Best Quality Scaffoldings. Enquire for
Details.
SELECT lastname, firstname, tag, vehicles.class
FROM drivers, vehicles
WHERE drivers.location = vehicles.location
AND drivers.class = vehicles.class
Notice that in this example we needed to specify the source table for the class attribute in the
SELECT clause. This is due to the fact that class is ambiguous it appears in both tables and we
need to specify which tables column should be included in the query results. In this case it does

not make a difference as the columns are identical and they are joined using an
equijoin. However, if the columns contained different data this distinction would be
critical. Here are the results of this query:
lastname FirstName
Tag
Class
-------- --------- ------Baker
Roland
H122JM
Car
Smythe
Michael
D824HA
Truck
Jacobs
Abraham
J291QR
Car
Notice that the rows pairing Michael Smythe to a car and Abraham Jacobs to a truck have been
removed.
You can also use inner joins to combine data from three or more tables.
Outer joins allow database users to include additional information in the query results. We'll
explore them in the next section of this article. Read on!
Next page > Outer Joins > Page 1, 2, 3

Retrieving Data from Multiple Tables with SQL Joins


Part 3: Outer Joins
Take a moment and review the database tables located on the first
page of this article. Notice that we have a driver -- Jack Ryan -- who
is located in a city where there are no vehicles. Our vehicle managers
would like this information to be included in their query results to
ensure that drivers do not sit idly by waiting for a vehicle to
arrive. We can use outer joins to include records from one table that
have no corresponding record in the joined table. Let's create a list of
driver/vehicle pairings that includes records for drivers with no
vehicles in their city. We can use the following query:
SELECT lastname, firstname, driver.city, tag
FROM drivers, vehicles
WHERE drivers.location = vehicles.location (+)
Notice that the outer join operator "(+)" is included in this
query. This operator is placed in the join condition next to the table
that is allowed to have NULL values. This query would produce the
following results:
lastname firstname city
tag
---------------- -----Baker
Roland
New York H122JM
Smythe
Michael
Miami
D824HA

More of this Feature


Part 1: Introducing Joins
Part 2: Inner Joins
Join the Discussion
"Share your questions
and tap the knowledge of
hundreds of your peers."
Mike Chapple
Related Resources
SQL Fundamentals
Creating Databases and
Tables in SQL
Retrieving Data with
SQL Queries

Smythe
Jacobs
Jacobs
Ryan

Michael
Miami
P091YF
Abraham
Seattle J291QR
Abraham
Seattle L990MT
Patrick
Annapolis

This time our results include the stranded Patrick Ryan and our vehicle management department
can now dispatch a vehicle to pick him up.
Note that there are other possible ways to accomplish the results seen in this article and syntax
may vary slightly from DBMS to DBMS. These examples were designed to work with Oracle
databases, so your mileage may vary. Furthermore, as you advance in your knowledge of SQL
youll discover that there is often more than one way to accomplish a desired result and
oftentimes one way is just as good as another. Case in point, it is also possible to specify a join
condition in the FROM clause rather than the WHERE clause. For example, we used the
following SELECT statement earlier in this article:
Ads
Database Synchronizationwww.pervasync.comSupports My SQL, OracleDB, MS SQL Server
and SQLite.
Scaffoldingwww.cityscaffoldings.inLeading Supplier of Best Quality Scaffoldings. Enquire for
Details.
Home Loaninstantloan.pnbhfl.com/home-loanGet Loan upto 80%*of Property Cost. Avail
Doorstep Services @ PNBHFL.
SELECT lastname, firstname, tag
FROM drivers, vehicles
WHERE drivers.location = vehicles.location
AND drivers.class = vehicles.class
The same query could be rewritten as:
SELECT lastname, firstname, tag
FROM drivers INNER JOIN vehicles ON drivers.location = vehicles.location
WHERE drivers.class = vehicles.class
That's it for this week! Be sure to check back next week for a new exciting article on
databases. If you'd like a reminder in your Inbox, subscribe to the About Databases newsletter.
Next page > > Page 1, 2, 3

NULLs and JOINs

Related Resources

In our last article, we introduced the concept of the NULL (or


unknown) value and described how SQL treats this value when
encountered in logical operations such as AND and OR. In this
article, we take a look at how NULL values impact a more
complicated operation the JOINing of two tables.

SQL Fundamentals
Starting a Career in
Databases
Certification Resources

Let's begin by taking a look at two sample tables that comprise the
course database for a school. We might first have a list of courses and instructors, as shown
below. (Note that, for simplicity's sake, we are making the assumption that there is only one
section of each course and, therefore, that we can use it as the primary key.) In this case, the
instructor Adams has not yet been assigned to a course and the Computers course has no
instructor assigned yet.
Course Instructor
Math
Smith
Science Jones
NULL
Adams
Computers NULL
Now, let's assume that we have a table containing course registrations for students. Again, for
simplicity's sake, we'll assume that each student must take one and only one course. Every
student must take a class, so we will include a NULL record for any student whose course
registration information is unknown. In this case, we're not sure what course Alan is taking.
Student Course
Ryan Math
Betty Science
Alan NULL
If we perform an INNER JOIN, NULL values do not match each other. For example, if we
perform the following query:
SELECT *
FROM Instructors INNER JOIN Students
ON Instructors.Course = Students.Course
We'd get the following result:
Course Instructor Student
Math Smith
Ryan
Science Jones
Betty
The OUTER JOIN operations includes data from one or both tables that doesn't match data in the

other table. There are three types of OUTER JOINs:


The LEFT OUTER JOIN includes rows from the table specified on the left side of the JOIN
statement that don't match with rows from the table on the right side of the JOIN statement.
The RIGHT OUTER JOIN includes rows from the table specified on the right side of the
JOIN statement that don't match with rows from the table on the left side of the JOIN
statement.
The FULL OUTER JOIN includes rows from both tables that don't match data in the other
table.
If we performed the following query:
SELECT *
FROM Instructors LEFT OUTER JOIN Students
ON Instructors.Course = Students.Course
We'd get the following result set:
Course Instructor Student
Math
Smith
Ryan
Science Jones
Betty
NULL
Adams
NULL
Computers NULL
NULL
Similarly, the query:
SELECT *
FROM Instructors RIGHT OUTER JOIN Students
ON Instructors.Course = Students.Course
Would give us:
Course Instructor Student
Math Smith
Ryan
Science Jones
Betty
NULL NULL
Alan
And, finally, the query:
SELECT *
FROM Instructors FULL OUTER JOIN Students
ON Instructors.Course = Students.Course

Would yield:
Course Instructor Student
Math
Smith
Ryan
Science Jones
Betty
Computers NULL
NULL
NULL
NULL
Alan
NULL
Adams
NULL
And that's a look at how NULL values are treated by the JOIN operation!
Aggregate Functions in SQL
Part 1: Introducing SUM and AVG

More of this Feature


By their very nature, our databases contain a lot of data. In previous Part 2: Counting
features, we've explored methods of extracting the specific data we're Records
Part 3: Max and Min
looking for using the Structured Query Language (SQL). Those
methods worked great when we were seeking the proverbial needle in Join the Discussion
the haystack. We were able to answer obscure questions like "What "Need some assistance or
are the last names of all customers who have purchased Siberian wool advice? Join us in the
during the slow months of July and August?"
About Databases forum."
Mike Chapple
Oftentimes, we're also interested in summarizing our data to
determine trends or produce top-level reports. For example, the
purchasing manager may not be interested in a listing of all widget sales, but may simply want to
know the number of widgets sold this month. Fortunately, SQL provides aggregate functions to
assist with the summarization of large volumes of data. In this three-segment article, we'll look at
functions that allow us to add and average data, count records meeting specific criteria and find
the largest and smallest values in a table.
All of our queries will use the WidgetOrder table described below. Please note that this table is
not normalized and I've combined several data entities into one table for the purpose of
simplifying this scenario. A good relational design would likely have Products, Orders, and
Customers tables at a minimum.
Ads
House in Bangalorewww.indiaproperty.com/BangaloreChoose From 50000+ Houses On Sale!
Best deals on Luxury Houses
Home Loaninstantloan.pnbhfl.com/home-loanBest Home Loans with Easy Repayment Options
@ PNB Housing.Apply Online!
OPC To Sqlwww.matrikonopc.com/OPCDatabasesEasily store OPC to databases. Easy to use,
Free to try.

OrderID

FirstName

LastName

Quantity

UnitPrice

Continent

122

John

Jacob

21

4.52

North America

923

Ralph

Wiggum

192

3.99

North America

238

Ryan

Johnson

87

4.49

Africa

829

Mary

Smith

842

2.99

North America

824

Elizabeth

Marks

48

3.48

Africa

753

James

Linea

7.85

North America

942

Alan

Jonas

638

3.29

Europe

Let's begin by taking a look at the SUM function. It is used within a SELECT statement and,
predictably, returns the summation of a series of values. If the widget project manager wanted to
know the total number of widgets sold to date, we could use the following query:
SELECT SUM(Quantity) AS Total
FROM WidgetOrders
Our results would appear as:
Total
----------1837
The AVG (average) function works in a similar manner to provide the mathematical average of a

series of values. Let's try a slightly more complicated task this time. We'd like to find out the
average dollar amount of all orders placed on the North American continent. Note that we'll have
to multiply the Quantity column by the UnitPrice column to compute the dollar amount of each
order. Here's what our query will look like:
SELECT AVG(UnitPrice * Quantity) As AveragePrice
FROM WidgetOrders
WHERE Continent = "North America"
And the results:
AveragePrice
--------------------862.3075
In the next section of this article, we'll explore methods used for counting the number of records
that meet given criteria. Read on!
Next page > Counting Records > Page 1, 2, 3

Part 2: Counting Records


More of this Feature

SQL provides the COUNT function to retrieve the number of records Part 1: Sum and
in a table that meet given criteria. We can use the COUNT(*) syntax Average
Part 3: Max and Min
alone to retrieve the number of rows in a table. Alternatively, a
WHERE clause can be included to restrict the counting to specific
Join the Discussion
records.
"Need some assistance or
advice? Join us in the
About Databases forum."
For example, suppose our Widgets product manager would like to
know how many orders our company processed that requested over Mike Chapple
100 widgets.
Here's the SQL query:
SELECT COUNT(*) AS 'Number of Large Orders'
FROM WidgetOrders
WHERE Quantity > 100
And the results:
Number of Large Orders

---------------------3
The COUNT function also allows for the use of the DISTINCT keyword and an expression to
count the number of times a unique value for the expression appears in the target data. Similarly,
the ALL keyword returns the total number of times the expression is satisfied, without worrying
about unique values. For example, our product manager would like a simple query that returned
the number of unique continents in our orders database.
First, let's take a look at the use of the ALL keyword:
SELECT COUNT(ALL Continent) As 'Number of Continents'
FROM WidgetOrders
And the result set:
Number of Continents
-------------------7
Obviously, this is not the desired results. If you recall the contents of the WidgetOrders table
from the previous page, all of our orders came from North America, Africa and Europe. Let's try
the DISTINCT keyword instead:
SELECT COUNT(DISTINCT Continent) As 'Number of Continents'
FROM WidgetOrders
And the output:
Number of Continents
-------------------3
That's more like it!
In the next section of this article, we'll look at the functions used to find the maximum and
minimum values of an expression. Read on!

What are the different ways to replace NULL values in


SQL Server
This interview question is not that common. My friend faced this interview question, when he attended an
interview in London. My friend said we can use COALESCE() in SQL Server. Then the interviewer said,
that's very good answer, but do you know of any other way?

Apart from using COALESCE(), there are 2 other ways to replace NULL values in SQL Server. Let's
understand this with an example.

I have a Table tblEmployee, as shown in the diagram below. Some of the Employees does not have
gender. All those employees who does not have Gender, must have a replacement value of 'No
Gender' in your query result. Let's explore all the 3 possible options we have.

Option 1 : Replace NULL values in SQL Server using ISNULL() function.


Select Name, ISNULL(Gender,'No Gender') as Gender
From tblEmployee

Option 2 : Replace NULL values in SQL Server using CASE.


Select Name, Case When Gender IS NULL Then 'No Gender' Else Gender End as Gender
From tblEmployee

Option 3 : Replace NULL values in SQL Server using COALESCE() function.


Select Name, Coalesce(Gender, 'No Gender') as Gender
From tblEmployee
There are 3 different types of joins available in sql server, and they are
1. Cross Join
2. Inner Join or Join
3. Outer Join
Outer Join is again divided into 3 types as shown below.
1. Left Outer Join or Left Join
2. Right Outer Join or Right Join
3. Full Outer Join or Full Join
I strongly recomend to learn about the basics and types of joins, before reading this article. Read the
articles below, before proceeding with self join.
1. Basics of Joins
2. Inner Join
3. Left Outer Join
4. Right Outer Join
5. Full Outer Join

Self join is not a different type of join. Self join means joining a table with itself. We can have an inner
self join or outer self join. Let us try to understand with an example.
To set up the data for the example, use the script below to create Employee Table and populate it with
some sample data. We will be using Employee Table to understand Self Join.
CREATE TABLE EMPLOYEE
(
[EMPLOYEEID] INT PRIMARY KEY,
[NAME] NVARCHAR(50),
[MANAGERID] INT
)
GO
INSERT INTO EMPLOYEE VALUES(101,'Mary',102)
INSERT INTO EMPLOYEE VALUES(102,'Ravi',NULL)
INSERT INTO EMPLOYEE VALUES(103,'Raj',102)
INSERT INTO EMPLOYEE VALUES(104,'Pete',103)
INSERT INTO EMPLOYEE VALUES(105,'Prasad',103)
INSERT INTO EMPLOYEE VALUES(106,'Ben',103)
GO
We use Self Join, if we have a table that references itself. For example, In the Employee Table below
MANAGERID column references EMPLOYEEID column. So the table is said to referencing itself. This is
the right scenario where we can use Self Join. Now I want to write a query that will give me the list of all
Employee Names and their respective Manager Names. In order to achieve this I can use Self Join. In the
Table below,Raj is the manager for Pete,Prasad and Ben. Ravi is the manager for Raj and Mary. Ravi
does not have a manager as he is the president of the Company.

The query below is an example of Self Join. Both E1 and E2 refer to the same Employee Table. In this
query we are joining the EmployeeTable with itself.
SELECT E1.[NAME],E2.[NAME] AS [MANAGER NAME]
FROM EMPLOYEE E1
INNER JOIN EMPLOYEE E2
ON E2.EMPLOYEEID =E1.MANAGERID
If we run the above query we only get 5 rows out of the 6 rows as shown below.
Inner Self Join

This is because Ravi does not have a Manager. MANAGERID column for Ravi is NULL. If we want to get
all the rows then we can use LEFT OUTER JOIN as shown below.
SELECT E1.[NAME],E2.[NAME] AS [MANAGER NAME]
FROM EMPLOYEE E1
LEFT OUTER JOIN EMPLOYEE E2
ON E2.EMPLOYEEID =E1.MANAGERID
If we execute the above query we get all the rows, including the row that has a null value in the
MANAGERID column. The results are shown below. The MANAGERNAME for 2nd record is NULL as
Ravi does not have a Manager.
Left Outer Self Join

Let us now slightly modify the above query using COALESCE as shown below. Read COALESCE
function in SQL Server to understandCOALESCE in a greater detail.
SELECT E1.[NAME],COALESCE(E2.[NAME],'No Manager') AS [MANAGER NAME]
FROM EMPLOYEE E1
LEFT JOIN EMPLOYEE E2
ON E2.EMPLOYEEID =E1.MANAGERID
If we execute the above query the output will be as shown in the image below. This is
how COALESCE can be used.
Left Outer Self Join with COALESCE

Full Outer Join in SQL Server with an example


Inner Join and left join are the most commonly used joins in real time projects. It is very important that
you understand the basics of joins before reading this article. Please read the articles below if you have

not done so already.


1. Basics of Joins in SQL Server
2. Inner Join
3. Left Join
4. Right Join
Now, let us understand Full Outer join with an example.
Create 2 tables Company and Candidate. Use the script below to create these tables and populate
them. CompanyId column in Candidate Table is a foreign key referencing CompanyId in Company Table.
CREATE TABLE Company
(
CompanyId TinyInt Identity Primary Key,
CompanyName Nvarchar(50) NULL
)
GO
INSERT Company VALUES('DELL')
INSERT Company VALUES('HP')
INSERT Company VALUES('IBM')
INSERT Company VALUES('Microsoft')
GO
CREATE TABLE Candidate
(
CandidateId tinyint identity primary key,
FullName nvarchar(50) NULL,
CompanyId tinyint REFERENCES Company(CompanyId)
)
GO
INSERT Candidate VALUES('Ron',1)
INSERT Candidate VALUES('Pete',2)
INSERT Candidate VALUES('Steve',3)
INSERT Candidate VALUES('Steve',NULL)
INSERT Candidate VALUES('Ravi',1)
INSERT Candidate VALUES('Raj',3)
INSERT Candidate VALUES('Kiran',NULL)
GO

If you want to select all the rows from the LEFT Table ( In our example Candidate Table ) plus all the
rows from the RIGHT table ( In our example Company Table ) , then we use FULL OUTER JOIN. A
query involving a FULL OUTER JOIN for the Candidate and CompanyTable is shown below.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
FULL OUTER JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If we run the above query the output will be as shown in below. If you look at the out put, we now got 8
rows. All the rows from the CandidateTable and all the rows from the Company Table.

Full Outer Join Result


Instead of using FULL OUTER JOIN keyword we can just use FULL JOIN keyword as shown
below. FULL OUTER JOIN or FULL JOINmeans the same.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
FULL JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If you can think of any other sql server interview questions please post them as comments, so
they will be useful to other users like you. This will be a great help from your side to improve this
site.

Right Outer Join with an example


Please read, Basic SQL Server Interview Questions on Joins article before reading this article.
Inner Join and left join are the most commonly used joins in real time projects.
Click here to read about Inner Join in SQL Server.
Click here to read about Left Outer Join in SQL Server.
Now, let us understand Right Outer join with an example.
Create 2 tables Company and Candidate. Use the script below to create these tables and
populate them. CompanyId column in Candidate Table is a foreign key referencing CompanyId in
Company Table.
CREATE TABLE Company
(
CompanyId TinyInt Identity Primary Key,
CompanyName Nvarchar(50) NULL
)
GO
INSERT Company VALUES('DELL')
INSERT Company VALUES('HP')
INSERT Company VALUES('IBM')
INSERT Company VALUES('Microsoft')
GO
CREATE TABLE Candidate

(
CandidateId tinyint identity primary key,
FullName nvarchar(50) NULL,
CompanyId tinyint REFERENCES Company(CompanyId)
)
GO
INSERT Candidate VALUES('Ron',1)
INSERT Candidate VALUES('Pete',2)
INSERT Candidate VALUES('Steve',3)
INSERT Candidate VALUES('Steve',NULL)
INSERT Candidate VALUES('Ravi',1)
INSERT Candidate VALUES('Raj',3)
INSERT Candidate VALUES('Kiran',NULL)
GO

If you want to select all the rows from the LEFT Table ( In our example Candidate Table) that
have non null foreign key values plus all the rows from the RIGHT table ( In our
example Company Table) including the rows that are not referenced in the LEFT Table, then we
useRIGHT OUTER JOIN. A query involving a RIGHT OUTER JOIN for
the Candidate and Company Table is shown below.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
RIGHT OUTER JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If we run the above query the output will be as shown in below. If you look at the out put, we now
got 6 rows. All the rows from the CandidateTable that has non null foreign key value plus all the
rows from the Company Table including the row that is not referenced in the CandidateTable.

Right Outer Join Results


Instead of using RIGHT OUTER JOIN keyword we can just use RIGHT JOIN keyword as shown
below. RIGHT OUTER JOIN or RIGHT JOINmeans the same.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
RIGHT JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId

If you can think of any other sql server interview questions please post them as comments,
so they will be useful to other users like you. This will be a great help from your side to
improve this site.
Email ThisBlogThis!Share to TwitterShare to FacebookShare to Pinterest

No comments:
Post a Comment
If you are aware of any other sql server questions asked in an interview, please post them
below. If you find anything missing or wrong, please feel free to correct by submitting the
form below.

Left Join with an example


Please read, Basic SQL Server Interview Questions on Joins article before reading this article.
Inner Join and left join are the most commonly used joins in real time projects. Click here to read about
Inner Join in SQL Server. Now, let us understand Left join with an example.
Create 2 tables Company and Candidate. Use the script below to create these tables and populate
them. CompanyId column in Candidate Table is a foreign key referencing CompanyId in Company Table.
CREATE TABLE Company
(
CompanyId TinyInt Identity Primary Key,
CompanyName Nvarchar(50) NULL
)
GO
INSERT Company VALUES('DELL')
INSERT Company VALUES('HP')
INSERT Company VALUES('IBM')
INSERT Company VALUES('Microsoft')
GO
CREATE TABLE Candidate
(
CandidateId tinyint identity primary key,
FullName nvarchar(50) NULL,
CompanyId tinyint REFERENCES Company(CompanyId)
)
GO
INSERT Candidate VALUES('Ron',1)
INSERT Candidate VALUES('Pete',2)
INSERT Candidate VALUES('Steve',3)
INSERT Candidate VALUES('Steve',NULL)
INSERT Candidate VALUES('Ravi',1)
INSERT Candidate VALUES('Raj',3)
INSERT Candidate VALUES('Kiran',NULL)
GO

If you want to select all the rows from the LEFT table ( In our example Candidate Table ) including the
rows that have a null foreign key value ( CompanyId in Candidate Table is the foreign key ) then we
use LEFT OUTER JOIN. A query involving a LEFT OUTER JOIN for theCandidate and Company Table
is shown below.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
LEFT OUTER JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If we run the above query the output will be as shown in below. If you look at the out put, we now got all 7
rows ( All the rows from theCandidate Table ) including the row that has a null value for
the CompanyId column in the Candidate Table. So, LEFT OUTER JOIN would get all the rows from
the LEFT Table including the rows that has null foreign key value.

Left Join Result


Instead of using LEFT OUTER JOIN keyword we can just use LEFT JOIN keyword as shown
below. LEFT OUTER JOIN or LEFT JOINmeans the same.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
LEFT JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If you can think of any other sql server interview questions please post them as comments, so
they will be useful to other users like you. This will be a great help from your side to improve this
site.

Inner Join with an example


Please read, Basic SQL Server Interview Questions on Joins article before reading this article.
Inner Join and left join are the most commonly used joins in real time projects. We will talk about left
join in a later article. Now, let us understand Inner join with an example.
Create 2 tables Company and Candidate. Use the script below to create these tables and populate
them. CompanyId column in Candidate Table is a foreign key referencing CompanyId in Company Table.
CREATE TABLE Company
(
CompanyId TinyInt Identity Primary Key,

CompanyName Nvarchar(50) NULL


)
GO
INSERT Company VALUES('DELL')
INSERT Company VALUES('HP')
INSERT Company VALUES('IBM')
INSERT Company VALUES('Microsoft')
GO
CREATE TABLE Candidate
(
CandidateId tinyint identity primary key,
FullName nvarchar(50) NULL,
CompanyId tinyint REFERENCES Company(CompanyId)
)
GO
INSERT Candidate VALUES('Ron',1)
INSERT Candidate VALUES('Pete',2)
INSERT Candidate VALUES('Steve',3)
INSERT Candidate VALUES('Steve',NULL)
INSERT Candidate VALUES('Ravi',1)
INSERT Candidate VALUES('Raj',3)
INSERT Candidate VALUES('Kiran',NULL)
GO

If you want to select all the rows from the LEFT table(In our example Candidate Table) that have a non
null foreign key value(CompanyId inCandidate Table is the foreign key) then we use INNER JOIN. A
query involving an INNER JOIN for the Candidate and Company Table is shown below.
SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,
Comp.CompanyName
FROM Candidate Cand
INNER JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If we run the above query the output will be as shown in the image below. If you look at the out put, we
only got 5 rows. We did not get the 2 rows which has NULL value in the CompanyId column. So an
INNER JOIN would get all the rows from the LEFT Table that has non null foreign key value.

Inner Join Result


Instead of using INNER JOIN keyword we can just use JOIN keyword as shown below. JOIN or INNER
JOIN means the same.

SELECT Cand.CandidateId, Cand.FullName, Cand.CompanyId, Comp.CompanyId,


Comp.CompanyName
FROM Candidate Cand
JOIN Company Comp
ON Cand.CompanyId = Comp.CompanyId
If you can think of any other sql server interview questions please post them as comments, so
they will be useful to other users like you. This will be a great help from your side to improve this
site.

Aggregate Functions in SQL


Part 3: Max and Min

In this final segment of our aggregate functions feature article, we'll


look at the functionality SQL provides to locate the records
containing the smallest and largest values for a given expression.

More of this Feature


Part 1: Sum and
Average
Part 2: Counting
Records

The MAX() function returns the largest value in a given data


series. We can provide the function with a field name to return the
largest value for a given field in a table. MAX() can also be used
with expressions and GROUP BY clauses for enhanced functionality.

Join the Discussion


"Need some assistance or
advice? Join us in the
About Databases forum."
Mike Chapple

Once again, we'll use the WidgetOrders example table for this query
(see the first page of this article for the specification and contents). Suppose our product
manager wanted to find the order in our database that produced the most revenue for the
company. We could use the following query to find the order with the largest total dollar value:
SELECT MAX(Quantity * UnitPrice)As 'Largest Order'
FROM WidgetOrders
Our results would look like this:
Largest Order
--------------------2517.58
The MIN() function functions in the same manner, but returns the minimum value for the
expression. Let's try a slightly more complicated example utilizing the MIN() function. Our
sales department is currently analyzing data on small widget orders. They'd like us to retrieve
information on the smallest widget order placed on each continent. This requires the use of the
MIN() function on a computed value and a GROUP BY clause to summarize data by continent.
Here's the SQL:
SELECT Continent, MIN(Quantity * UnitPrice) AS 'Smallest Order'

FROM WidgetOrders
GROUP BY Continent
And our result set:
Continent Smallest Order
------------- --------------------Africa
167.04
Europe
2099.02
North America 70.65
That's it for this week. If you're not clear on the use of aggregate functions, be sure to stop by
our forum for some assistance. Check back each week for coverage of a new databases topic. If
you'd like a weekly reminder by e-mail, be sure to subscribe to our newsletter.
Explain about RANK,ROW_NUMBER and DENSE_RANK in Sql server ?
Found a very interesting explanation for the same in the url Click Here . PFB the content of the
same here.
Lets take 1 simple example to understand the difference between 3.
First lets create some sample data :
create table
CREATE TABLE Salaries
(
Names VARCHAR(1),
SalarY INT
)
GO
insert data
INSERT INTO Salaries SELECT
A,5000 UNION ALL SELECT
B,5000 UNION ALL SELECT
C,3000 UNION ALL SELECT
D,4000 UNION ALL SELECT
E,6000 UNION ALL SELECT
F,10000
GO
Test the data
SELECT Names, Salary
FROM Salaries

Now lets query the table to get the salaries of all employees with their salary in descending order.
For that Ill write a query like this :
SELECT names
, salary
,row_number () OVER (ORDER BY salary DESC) as ROW_NUMBER
,rank () OVER (ORDER BY salary DESC) as RANK
,dense_rank () OVER (ORDER BY salary DESC) as DENSE_RANK
FROM salaries
>>Output
NAMES
F
E
A
B
D
C

SALARY
10000
6000
5000
5000
4000
3000

ROW_NUMBER
1
2
3
4
5
6

RANK
1
2
3
3
5
6

DENSE_RANK
1
2
3
3
4
5

Interesting Names in the result are employee A, B and D. Row_number assign different number
to them. Rank and Dense_rank both assign same rank to A and B. But interesting thing is what
RANK and DENSE_RANK assign to next row? Rank assign 5 to the next row, while dense_rank
assign 4.
The numbers returned by the DENSE_RANK function do not have gaps and always have
consecutive ranks. The RANK function does not always return consecutive integers. The
ORDER BY clause determines the sequence in which the rows are assigned their unique
ROW_NUMBER within a specified partition.
So question is which one to use?
Its all depends on your requirement and business rule you are following.
1. Row_number to be used only when you just want to have serial number on result set. It is not
as intelligent as RANK and DENSE_RANK.
2. Choice between RANK and DENSE_RANK depends on business rule you are following.
Rank leaves the gaps between number when it sees common values in 2 or more rows.
DENSE_RANK dont leave any gaps between ranks.
So while assigning the next rank to the row RANK will consider the total count of rows before
that row and DESNE_RANK will just give next rank according to the value.
So If you are selecting employees rank according to their salaries you should be using

DENSE_RANK and if you are ranking students according to there marks you should be using
RANK(Though it is not mandatory, depends on your requirement.)

COMPAREDATE

unit
DateUtils
category
date/time
routines

declaration
type TValueRelationship = -1..1
function CompareDate(const ADate, BDate: TDateTime) : TValueRelationship
description
Compares two TDateTime values (returns "less", "equal" or "greater"). Ignores the Time
part if both values "fall" on the same day.
TValueRelationship represents the relationship between two values. Each of three
TValueRelationship values has a "liked" symbolic constant:
-1 [LessThanValue] The first value is less than the second value.
0 [EqualsValue] The two values are equal.
1 [GreaterThanValue] The first value is greater than the second value.
CompareDate results in:
LessThanValue if ADate occurs on a day prior to the Date part of the BDate.
EqualsValue if date parts of both ADate and BDate are the same, ignoring the Time part.
GreaterThanValue if ADate occurs on a day that follows the Date part of the BDate.
example
var ThisMoment, AnotherMoment : TDateTime;

ThisMoment := Now;
AnotherMoment := IncADay(ThisMoment, 5); //adds 5 days

//CompareDate(ThisMoment, AnotherMoment) returns LessThanValue (-1)


//CompareDate(AnotherMoment, ThisMoment) returns GreaterThanValue (1)

COMPAREDATETIME

unit
DateUtils
category
date/time
routines

declaration
type TValueRelationship = -1..1
function CompareDateTime(const ADate, BDate: TDateTime) : TValueRelationship
description
Compares two TDateTime values (returns "less", "equal" or "greater").
TValueRelationship represents the relationship between two values. Each of three
TValueRelationship values has a "liked" symbolic constant:
-1 [LessThanValue] The first value is less than the second value.
0 [EqualsValue] The two values are equal.
1 [GreaterThanValue] The first value is greater than the second value.
CompareDate results in:
LessThanValue if ADate is earlier than BDate.
EqualsValue if date and time parts of both ADate and BDate are the same
GreaterThanValue if ADate is later than BDate.
example
var ThisMoment, FutureMoment : TDateTime;

ThisMoment := Now;
FutureMoment := IncDay(ThisMoment, 6); //adds 6 days

//CompareDateTime(ThisMoment, FutureMoment) returns LessThanValue (-1)


//CompareDateTime(FutureMoment, ThisMoment) returns GreaterThanValue (1)

COMPARETIME

unit
DateUtils
category
date/time
routines

declaration
type TValueRelationship = -1..1
function CompareDate(const ADate, BDate: TDateTime) : TValueRelationship
description
Compares two TDateTime values (returns "less", "equal" or "greater"). Ignores the Time
part if both values occur at the same time.
TValueRelationship represents the relationship between two values. Each of three
TValueRelationship values has a "liked" symbolic constant:
-1 [LessThanValue] The first value is less than the second value.
0 [EqualsValue] The two values are equal.
1 [GreaterThanValue] The first value is greater than the second value.
CompareDate results in:
LessThanValue if ADate occurs earlier in the day specified by BDate.
EqualsValue if time parts of both ADate and BDate are the same, ignoring the Date part.
GreaterThanValue if ADate occurs later in the day specified by BDate.
example
var ThisMoment, AnotherMoment : TDateTime;

ThisMoment := Now;
AnotherMoment := IncHour(ThisMoment, 6); //adds 6 hours

//CompareDate(ThisMoment, AnotherMoment) returns LessThanValue (-1)


//CompareDate(AnotherMoment, ThisMoment) returns GreaterThanValue (1)

DATE

unit
Sysutils
category
date/time
routines

declaration
type TDateTime = type Double;
function date: TDateTime;
description
Returns the current system date.
The integral part of a TDateTime value is the number of days that have passed since 12/30/1899.
The fractional part of a TDateTime value is fraction of a 24 hour day that has elapsed.
To find the fractional number of days between two dates, simply subtract the two values.
Likewise, to increment a date and time value by a certain fractional number of days, simply add
the fractional number to the date and time value.
example

ShowMessage('Today is ' + DateToStr(Date));

DATETOSTR

declaration
function DateToStr(Value: TDateTime): string;
description
Converts a TDateTime value to a string.

unit
Sysutils
category
date/time
routines

The conversion uses the format specified by the ShortDateFormat global variable.
example

ShowMessage('Today is ' + DateToStr(Date));

DATETIMETOFILEDATE

declaration
function DateTimeToFileDate(DateTime: TDateTime): Integer;
description
Converts a TDateTime value to a system timestamp value.
example
var aFile : string;
aFileDateTime : TDateTime;
aFileOSDate : integer;
begin
aFile : = Application.ExeName;
aFileOSDate := FileAge(aFile);

if aFileOSDate = -1 then Exit; //invalid file

aFileDateTime := DateAdd(Now,1); //add a day

unit
Sysutils
category
date/time
routines

FileSetDate(aFile, DateTimeToFileDate(aFileDateTime));

//Fo, our application exe file "was" modified tomorow


end;

DATETIMETOSTR

unit
Sysutils
category
date/time
routines

declaration
function DateTimeToStr(Value: TDateTime): string;
description
Converts a TDateTime value to a string.
The conversion uses the format specified by the ShortDateFormat global variable for a date part,
followed by the time using the format given by the LongTimeFormat global variable.
example

ShowMessage('Now is ' + DateTimeToStr(Now));

DAYOFWEEK

declaration
type TDateTime = type Double;
function DayOfWeek(Date: TDateTime): integer;

unit
Sysutils
category
date/time
routines

description
Returns the day of the week for a given date.
DayOfWeek returns an integer between 1 and 7, where Sunday is the first day of the week and
Saturday is the seventh.
DayOfTheWeek is not compliant with the ISO 8601 standard.
example
const Days: array[1..7] of string =
('Sunday', 'Monday', 'Tuesday',
'Wednesday', 'Thursday',
'Friday', 'Saturday')

ShowMessage('Today is ' + Days[DayOfWeek(Date)]);

//Today is Monday

DATETIMETOSTR

unit
Sysutils
category
date/time
routines

declaration
function DateTimeToStr(Value: TDateTime): string;
description
Converts a TDateTime value to a string.
The conversion uses the format specified by the ShortDateFormat global variable for a date part,
followed by the time using the format given by the LongTimeFormat global variable.
example

ShowMessage('Now is ' + DateTimeToStr(Now));

DAYOFTHEWEEK

unit
Sysutils
category
date/time
routines

declaration
type TDateTime = type Double;
function DayOfTheWeek(Date: TDateTime): word;
description
Returns the day of the week for a given TDateTime value.
DayOfTheWeek returns an integer between 1 and 7, where Monday is the first day of the week
and Sunday is the seventh.
DayOfTheWeek is compliant with the ISO 8601 standard.
example
const Days: array[1..7] of string =
('Monday', 'Tuesday',
'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday')

ShowMessage('Today is ' + Days[DayOfTheWeek(Date)]);

//Today is Friday

DAYOFTHEMONTH

unit
Date utils
category
date/time
routines

declaration
function DayOfTheMonth(const AValue: TDateTime): Word;
description
Returns the day of the month from a given TDateTime value (from 1 to 31)
example
var
ThisDate : TDateTime;
DaysPassed : Word;
begin
ThisDate := Now; (* 08/15/2003 *)
DaysPassed := DayOfTheMonth(ThisDate)

// DaysPassed == 15
end;

DATETIMETOFILEDATE

declaration
function DateTimeToFileDate(DateTime: TDateTime): Integer;
description
Converts a TDateTime value to a system timestamp value.

unit
Sysutils
category
date/time
routines

example
var aFile : string;
aFileDateTime : TDateTime;
aFileOSDate : integer;
begin
aFile : = Application.ExeName;
aFileOSDate := FileAge(aFile);

if aFileOSDate = -1 then Exit; //invalid file

aFileDateTime := DateAdd(Now,1); //add a day

FileSetDate(aFile, DateTimeToFileDate(aFileDateTime));

//Fo, our application exe file "was" modified tomorow


end;

DAYOFTHEYEAR

declaration
function DayOfTheYear(const AValue: TDateTime): Word;
description

unit
Date utils
category
date/time
routines

Returns the the ordinal position of a TDateTime value's day within its year.
example
var
ThisDate : TDateTime;
DaysPassed : Word;
begin
ThisDate := Now; (* 08/14/2003 *)
DaysPassed := DayOfTheYear(ThisDate)

// DaysPassed == 226
end;

DATETIMETOFILEDATE

declaration
function DateTimeToFileDate(DateTime: TDateTime): Integer;
description
Converts a TDateTime value to a system timestamp value.
example
var aFile : string;
aFileDateTime : TDateTime;
aFileOSDate : integer;
begin

unit
Sysutils
category
date/time
routines

aFile : = Application.ExeName;
aFileOSDate := FileAge(aFile);

if aFileOSDate = -1 then Exit; //invalid file

aFileDateTime := DateAdd(Now,1); //add a day

FileSetDate(aFile, DateTimeToFileDate(aFileDateTime));

//Fo, our application exe file "was" modified tomorow


end;

DAYSPAN

unit
DateUtils
category
date/time
routines

declaration
function DaySpan(const ANow, AThen: TDateTime): double;
description
Gives the number of days (including fractional days) between two specified dates.
Contrary to DaysBetween, DaySpan function does not count only whole days. What this means
is that it will NOT return 0 as the result for difference between 05/01/2003 23:59:59 and
05/01/2003 23:59:58 - where the actual difference is one *whole* day minus 1 second.
example

var dtNow, dtBirth : TDateTime;


fracDaysFromBirth : double;

dtNow := Now;
dtBirth:=EncodeDate(1973, 1, 29);
fracDaysFromBirth := DaySpan(dtNow, dtBirth);

ShowMessage('Zarko Gajic "exists" ' + FloatToStr(fracDaysFromBirth));

DAYSBETWEEN

unit
DateUtils
category
date/time
routines

declaration
function DaysBetween(const ANow, AThen: TDateTime): Integer;
description
Gives the number of whole days between two specified dates.
Function counts only whole days. What this means is that it will return 0 as the result for
difference between 05/01/2003 23:59:59 and 05/01/2003 23:59:58 - where the actual difference
is one *whole* day minus 1 second.
example
var dtNow, dtBirth : TDateTime;
DaysFromBirth : integer;

dtNow := Now;
dtBirth := EncodeDate(1973, 1, 29);
DaysFromBirth := DaysBetween(dtNow, dtBirth);

ShowMessage('Zarko Gajic "exists" ' +


IntToStr(DaysFromBirth) + ' whole days!');

DATEOF

unit
DateUtils
category
date/time
routines

declaration
function DateOf(Date: TDateTime) : TDateTime
description
Returns only the Date portion of the TDateTime value, by setting Time part to 0.
DateOf sets the time portion to 0, which means midnight.
example
var ThisMoment, ThisDay : TDateTime;

ThisMoment := Now; // -> 06/27/2003 10:29:16:138


ThisDay := DateOf(ThisMoment);

//This Day:= 06/27/2003 00:00:00:000


in real code
see also

DECODEDATE

unit
Sysutils
category
date/time
routines

declaration
procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);;
description
Separates Year, Month, and Day values from a TDateTime value.
If the given TDateTime value is less than or equal to zero, the year, month, and day return
parameters are all set to zero.
example
var Y, M, D: Word;

DecodeDate(Date, Y, M, D);

if Y = 2000 then
ShowMessage('You''re in a "wrong" century!);

DECODETIME

unit
Sysutils
category
date/time
routines

declaration
procedure DecodeTime(Date: TDateTime; var Hour, Min, Sec, MSec: Word);;
description
Separates Hour, Minute, Second, and MilliSecond values from a TDateTime value.
If the given TDateTime value is less than or equal to zero, than hour, minute, second, and
millisecond return parameters are all set to zero.

example
var Hour, Min, Sec, MSec : Word;

DecodeTime(Date, Hour, Min, Sec, MSec);

showmessage(
'The time is Second ' + IntToStr(Sec) +
' of Minute ' + IntToStr(Min) +
' of Hour ' + IntToStr(Hour));

ENCODEDATE

unit
Sysutils
category
date/time
routines

declaration
function EncodeDate(Year, Month, Day: Word): TDateTime
description
Creates a TDateTime value from Year, Month, and Day values.
The Year must be between 1 and 9999. Valid Month values are 1 through 12. Valid Day values
are 1 through 28, 29, 30, or 31, depending on the Month value.
If the function fails, EncodeDate raises an EConvertError exception.
example
var Y, M, D: Word;
dt: TDateTime;

y:=2001;
M:=2;
D:=18;

dt:=EncodeDate(Y,M,D);

ShowMessage('Borna will be
one year old on ' + DateToStr(dt))

ENCODETIME

unit
Sysutils
category
date/time
routines

declaration
function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime
description
Creates a TDateTime value from Hour, Min, Sec, and MSec. values.
Valid Hour values are 0 through 23. Valid Min and Sec values are 0 through 59. Valid MSec
values are 0 through 999. If the specified values are not within range, an EConvertError
exception is raised.
The resulting value is a number between 0 (inclusive) and 1 (not inclusive) that indicates the
fractional part of a day given by the specified time.
The value 0 corresponds to midnight, 0.5 corresponds to noon, 0.75 corresponds to 6:00 pm, and
so on.
example

var H, M, S, MS: Word;


dt: TDateTime;

H:=8;
M:=58;
S:=18;
MS:=45;
dt:=EncodeTime(H,M,S,MS);

ShowMessage('The time is ' + TimeToStr(dt))

FORMATDATETIME

unit
Sysutils
category
date/time
routines

declaration
function FormatDateTime(const Fmt: string; Value: TDateTime): string;
description
Formats a TDateTime value to a string.
FormatDateTime uses the format specified by the Fmt parameter. For the supported format
specifiers go see Delphi Help files.
example
var s: string;

d: TDateTime;
...
d:=Now; // today + current time

s:=FormatDateTime('dddd',d);
// s:=Wednesday
s:=FormatDateTime('"Today is " dddd " minute " nn',d)
// s:=Today is Wednesday minute 24

HOUROF

unit
Dateutils
category
date/time
routines

declaration
function HourOf(ADateTime: TDateTime) : Boolean;
description
Returns the hour of the day represented by a TDateTime value.
HourOf returns a value between 0 and 23.
example
if HowOf(Now) > 17 then
ShowMessage ('Work time is over, go home');
in real code
see also
INCDAY

unit
Dateutils
category
date/time

routines
declaration
function IncDay(ADate: TDateTime; Days: Integer = 1) : TDateTime;
description
Adds or substracts a given number of days from a date value.
If the Days parameter is negative the date returned is < ADate. The Time part of day specified by
the Date parameter is copied to the result.
example
var Date: TDateTime;

EncodeDate(Date, 2003, 1, 29) //January 29, 2003


IncDay(Date, -1)

//January 28, 2003

INCMONTH

declaration
function IncMonth(Date: TDateTime; Months: Integer) : TDateTime;
description
Adds or substracts a given number of months from a date value.
The Time part of day specified by the Date parameter is copied to the result.
example
var Date: TDateTime;

unit
Sysutils
category
date/time
routines

EncodeDate(Date, 2000, 1, 31) //January 31, 2000


IncMonth(Date, 1)

//February 28, 2001


//IncMonth won't return
//an invalid date, of course.

ISLEAPYEAR

unit
Sysutils
category
date/time
routines

declaration
function IsLeapYear(Year: Word): boolean;
description
Returns True if a year specified is a leap year.
Use DecodeDate to obtain the value of Year for IsLeapYear from a TDateTime value.
example
var Y, M, D: Word;

DecodeDate(Date, Y, M, D);

if IsLeapYear(Y) then

ShowMessage('The current system year is a leap year!);

ISPM

unit
Dateutils
category
date/time
routines

declaration
function IsPM(ADateTime: TDateTime) : Boolean;
description
Returns true if the time portion of a TDateTime value occurs on or after 12:00 (noon) and
before 24:00 (midnight)
IsPM indicates whether the time portion of a specified TDateTime value occurs after noon.
example
if IsPM(Now) then
ShowMessage ('It's between 12:00 and 24:00');

NOW

unit
Sysutils
category
date/time
routines

declaration
type TDateTime = type Double;
function Now: TDateTime;
description
Returns the current system date and time.
The integral part of a TDateTime value is the number of days that have passed since 12/30/1899.
The fractional part of a TDateTime value is fraction of a 24 hour day that has elapsed.
To find the fractional number of days between two dates, simply subtract the two values.
Likewise, to increment a date and time value by a certain fractional number of days, simply add
the fractional number to the date and time value.

example

ShowMessage('Now is ' + DateTimeToStr(Now));

TIME

unit
Sysutils
category
date/time
routines

declaration
function Time: TDateTime;
description
Returns the current system time.
example

ShowMessage('Time is ' + TimeToStr(Time));

TIMETOSTR

unit
Sysutils
category
date/time
routines

declaration
function TimeToStr(Time: TDateTime): string;
description
Converts a TDateTime (time part) value to a string.
The conversion uses the format specified by the LongTimeFormat global variable.
example

ShowMessage('Now is ' + DateTimeToStr(Now));

TIMEOF

unit
DateUtils
category
date/time
routines

declaration
function TimeOf(Date: TDateTime) : TDateTime
description
Returns only the Time portion of the TDateTime value, by setting Date part to 0.
TimeOf sets the time portion to 0, which means 12/30/1899.
example
var ThisMoment, ThisTime : TDateTime;

ThisMoment := Now; // -> 06/29/2003 10:29:16:138


ThisTime := TimeOf(ThisMoment);

//This Day:= 12/30/1899 10:29:16:138

WITHINPASTDAYS

unit
DateUtils
category
date/time
routines

declaration
function WithinPastDays(const SomeDate, AnotherDate: TDateTime; const ADays:
Integer): boolean;
description
Returns true if two dates are within a specified number of days of each other.

Function counts only whole days - using the DaysBetween function.


example
var dtNow, dtBirth : TDateTime;
DaysFromBirth : integer;

dtNow := Now;
dtBirth := EncodeDate(1973, 1, 29);

if NOT WithinPastDays(dtNow, dtBirth, 3000) then


ShowMessage('You are more than 3000 days old!')

WITHINPASTYEARS

unit
DateUtils
category
date/time
routines

declaration
function WithinPastYears(const SomeDate, AnotherDate: TDateTime; const AYears:
Integer): boolean;
description
Returns true if two dates are within a specified number of years of each other.
Function counts only whole years - using the YearsBetween function - if SomeDate and
AnotherDate are 2 and a half years apart, calling WithinPastYears returns True and sets AYears
to 2.
example
var dtNow, dtBirth : TDateTime;

DaysFromBirth : integer;

dtNow := Now;
dtBirth := EncodeDate(1973, 1, 29);

if NOT WithinPastYears(dtNow, dtBirth, 30) then


ShowMessage('You are more than 30 years old!');

YEARSBETWEEN

unit
DateUtils
category
date/time
routines

declaration
function YearsBetween(const SomeDate, AnotherDate: TDateTime): Integer;
description
Gives the number of whole years between two specified dates.
YearsBetween returns an approximation based on an assumption of 365.25 days per year.
example
var dtSome, dtAnother : TDateTime;
DaysFromBirth : integer;

dtSome := EncodeDate(2003, 1, 1);


dtAnother := EncodeDate(2003, 12, 31);

YearsBetween(dtSome, dtAnother) == 1 //non-leap year

dtSome := EncodeDate(2000, 1, 1);


dtAnother := EncodeDate(2000, 12, 31);

YearsBetween(dtSome, dtAnother) == 0 // leap year

Explain about RANK,ROW_NUMBER and DENSE_RANK in Sql server ?


Found a very interesting explanation for the same in the url Click Here . PFB the content of the
same here.
Lets take 1 simple example to understand the difference between 3.
First lets create some sample data :
create table
CREATE TABLE Salaries
(
Names VARCHAR(1),
SalarY INT
)
GO
insert data
INSERT INTO Salaries SELECT
A,5000 UNION ALL SELECT
B,5000 UNION ALL SELECT
C,3000 UNION ALL SELECT
D,4000 UNION ALL SELECT
E,6000 UNION ALL SELECT
F,10000
GO
Test the data
SELECT Names, Salary
FROM Salaries

Now lets query the table to get the salaries of all employees with their salary in descending order.
For that Ill write a query like this :
SELECT names
, salary
,row_number () OVER (ORDER BY salary DESC) as ROW_NUMBER
,rank () OVER (ORDER BY salary DESC) as RANK
,dense_rank () OVER (ORDER BY salary DESC) as DENSE_RANK
FROM salaries
>>Output
NAMES
F
E
A
B
D
C

SALARY
10000
6000
5000
5000
4000
3000

ROW_NUMBER
1
2
3
4
5
6

RANK
1
2
3
3
5
6

DENSE_RANK
1
2
3
3
4
5

Interesting Names in the result are employee A, B and D. Row_number assign different number
to them. Rank and Dense_rank both assign same rank to A and B. But interesting thing is what
RANK and DENSE_RANK assign to next row? Rank assign 5 to the next row, while dense_rank
assign 4.
The numbers returned by the DENSE_RANK function do not have gaps and always have
consecutive ranks. The RANK function does not always return consecutive integers. The
ORDER BY clause determines the sequence in which the rows are assigned their unique
ROW_NUMBER within a specified partition.
So question is which one to use?
Its all depends on your requirement and business rule you are following.
1. Row_number to be used only when you just want to have serial number on result set. It is not
as intelligent as RANK and DENSE_RANK.
2. Choice between RANK and DENSE_RANK depends on business rule you are following.
Rank leaves the gaps between number when it sees common values in 2 or more rows.
DENSE_RANK dont leave any gaps between ranks.
So while assigning the next rank to the row RANK will consider the total count of rows before
that row and DESNE_RANK will just give next rank according to the value.
So If you are selecting employees rank according to their salaries you should be using

DENSE_RANK and if you are ranking students according to there marks you should be using
RANK(Though it is not mandatory, depends on your requirement.)

Vous aimerez peut-être aussi