SqlServer Interview Ques
SqlServer Interview Ques
What are the differences between primary key and unique key in
SQL Server?
This is of the most asked SQL Server Interview Questions in Interviews. Let
discuss this question in detail.
1. A table can have only one primary key. On the other hand, a table
can have more than one unique key.
2. The primary key column does not accept any null values whereas a
unique key column accepts one null value.
3. Both Primary key and unique key enforce the uniqueness of the
column on which they are defined. But By default, the primary key
creates a unique clustered index on the column whereas a unique
key creates a unique non clustered index.
How can we copy the data from one table to another?
This is one of the most frequently asked SQL Server Interview Questions
and the interviewer basically asked to write the query. When we copy the
data from one table to another table then the two tables should contain
the same structure.
When we copy the data from one table to another table we use insert and
select query. Tables always independent objects that mean a table does
not depend on other tables
What is normalization?
Database normalization is a data design and organization process
applied to data structures based on rules that help build relational
databases. In relational database design the process of organizing data to
minimize redundancy. Normalization usually involves dividing a database
into two or more tables and defining relationships between the tables. The
objective is to isolate data so that additions, deletions, and modifications
of a field can be made in just one table and then propagated through the
rest of the database via the defined relationships.
What is Collation?
Collation refers to a set of rules that determine how data is sorted and
compared. Character data is sorted using rules that define the correct
character sequence, with options for specifying case-sensitivity, accent
marks, kana character types, and character width.
What is a NOLOCK?
This is one of the most frequently asked SQL Interview Questions. Using
the NOLOCK query optimizer hint is generally considered good practice in
order to improve concurrency on a busy system. When the NOLOCK hint is
included in a SELECT statement, no locks are taken when data is read.
The result is a Dirty Read, which means that another process could be
updating the data at the exact time you are reading it. There are no
guarantees that your query will retrieve the most recent data.
The advantage of performance is that your reading of data will not block
updates from taking place, and updates will not block your reading of
data. SELECT statements take Shared (Read) locks. This means that
multiple SELECT statements are allowed simultaneous access, but other
processes are blocked from modifying the data. The updates will queue
until all the reads have completed, and reads requested after the update
will wait for the updates to complete. The result of your system is the
delay(blocking).
Properties of Sub-Query
1. A subquery must be enclosed in the parenthesis.
2. The subquery must be put in the right hand of the comparison
operator, and
3. The subquery cannot contain an ORDER-BY clause.
4. A query can contain more than one sub-queries.
Which TCP/IP port does SQL Server run on? How can it be
changed?
SQL Server runs on port 1433. It can be changed from the Network Utility
TCP/IP properties –> Port number. both on the client and the server.
Where are SQL server users names and passwords are stored in
SQL server?
They get stored in master DB in the sysxlogins table.
Which command using Query Analyzer will give you the version of
SQL server and operating system?
SELECT SERVERPROPERTY(‘productversion’), SERVERPROPERTY
(‘productlevel’), SERVERPROPERTY (‘edition’)
What is the SQL server agent?
This is one of the frequently asked SQL Server Interview Questions. SQL
Server agent plays an important role in the day-to-day tasks of a database
administrator (DBA). It is often overlooked as one of the main tools for
SQL Server management. Its purpose is to ease the implementation of
tasks for the DBA, with its full-function scheduling engine, which allows
you to schedule your own jobs and scripts.
What are the OS services that the SQL Server installation adds?
MS SQL SERVER SERVICE, SQL AGENT SERVICE, DTC (Distribution transac
co-ordinator)
What are the basic functions for master, MSDB, model, TEMPFB
databases?
This is one of the frequently asked SQL Server Interview
Questions. The Master database holds information for all databases
located on the SQL Server instance and is the glue that holds the engine
together. Because SQL Server cannot start without a functioning master
database, you must administer this database with care.
The MSDB database stores information regarding database backups, SQL
Agent information, DTS packages, SQL Server jobs, and some replication
information such as for log shipping.
The TEMPDB holds temporary objects such as global and local temporary
tables and stored procedures. The model is essentially a template
database used in the creation of any new user database created in the
instance.
What is De-normalization?
De-normalization is the process of attempting to optimize the
performance of a database by adding redundant data. It is sometimes
necessary because current DBMSs implement the relational model poorly.
A true relational DBMS would allow for a fully normalized database at the
logical level while providing physical storage of data that is tuned for high
performance. De-normalisation is a technique to move from higher to
lower normal forms of database modeling in order to speed up database
access.
Note: The drawback with a NOT NULL constraint is it will allow duplicate
values whereas in the case of the UNIQUE constraint it will allow null
values.
The Global Temporary Tables are visible to all the connections of the SQL
Server and are only destroyed when the last connection referencing the
table is closed.
Multiple users across multiple connections can have Local temporary
tables with the same name but Global Temporary Table Names should be
unique and if we inspect the name of the Global Temporary Table in the
object explorer there will be no random numbers suffixed at the end of the
table name.
Can you please explain when to use a temp table in SQL Server?
When we want to perform many operations on the data in a specific table
in the database, we can load the data into a temporary table and then we
can perform operations on the temporary table. Loading data into a
temporary table speeds up the process because all the operations are
performed locally on the client. Use of the Temporary Tables reduces the
load on both the network and server as all the interaction with temporary
tables occurs on the Client.
1. When we are doing a large number of row manipulation in stored
procedures.
2. This is useful to replace the cursor. We can store the result set data
into a temp table, then we can manipulate the data from there.
3. When we are having a complex join operation.
4. A Temporary Table variable can be very useful when used with
stored procedures to pass input/output parameters or to store the
result of a table-valued function.
Usually, it is best to create a temp table through the create function. For
example, if we want to check if that temp table existed and then
drop/create a new one and insert data it would go something like this.
IF object_ID('tempdb..##temptable') IS NOT NULL
DROP TABLE ##TEMPTABLE
CREATE TABLE ##TEMPTABLE
INSERT INTO ##TEMPTABLE
SELECT e.EMPLOYEE
FROM Employee e
WHERE e.employeename = 'Pranaya'
This would check for the table and drop it if it exists then would create a
new global temp table (indicated by the ##) and insert all employees with
the name Pranaya into this temp table.
SQL appends random function as at the end of the Local table’s
name. So, we can create a Local table with the same name. But
the Global table’s name has to be unique. Why is that?
It is because a Local table is available to the connection that created it.
Other users can have that name for their local table. But in the case of a
global temporary table, it is available to all users on different sessions. So,
its name cannot be different.
How to copy the structure of the temporary table from one table
to another? i.e., copying the only structure and no data?
Select * into #Temp1 from tblEmployee
Select Top 0 * into #Temp2 from #Temp1
--Or
Select * into #Temp1 from tblEmployee where 1=2
What is an index?
1. An index is a database object which is used by the SQL server to
speed up the performance of queries by providing query access to
rows in the data table.
2. By using indexes, we can save time and we can improve the
performance of database queries and applications.
3. When we create an index on any column SQL Server internally
maintains a separate table called index table so that when any user
trying to retrieve the data from the existing table depends on index
table SQL Server directly go to the table and retrieve required data
very quickly.
4. In a table, we can use a maximum of 250 indexes. The index type
refers to the way the index is stored internally by SQL Server.
What is the system stored procedure that can be used to list all
the indexes that are created for a specific table?
sp_helpindex is the system stored procedure that can be used to list all
the indexes that are created for a specific table. For example, to list all
the indexes on table tblCustomers, we can use the following command.
EXEC sp_helpindex tblCustomers
What is the first thing you will check for if the query below is
performing very slowly?
SELECT * FROM tblProducts ORDER BY UnitPrice ASC
Check if there is an Index created on the UntiPrice column used in the
ORDER BY clause. An index on the UnitPrice column can help the above
query to find data very quickly. When we ask for sorted data, the
database will try to find an index and avoid sorting the results during the
execution of the query. We control sorting of data by specifying a field, or
fields, in an ORDER BY clause, with the sort order as ASC (ascending) or
DESC (descending).
With no index, the database will scan the tblProducts table and sort the
rows to process the query. However, if there is an index, it can provide the
database with a presorted list of prices. The database can simply scan the
index from the first entry to the last entry and retrieve the rows in sorted
order.
The same index works equally well with the following query, simply by
scanning the index in reverse.
SELECT * FROM tblProducts ORDER BY UnitPrice DESC
How many Clustered and Non-Clustered Indexes can you have per
table?
Clustered Index: Only one Clustered Index per table. A clustered index
contains all of the data for a table in the index, sorted by the index key.
The Phone Book is an example of the Clustered Index.
ADVERTISEMENT
What is a table called, if it does not have neither Cluster nor Non-
cluster Index? What is it used for?
Unindexed table or Heap. Microsoft Press Books and Book On Line (BOL)
refers to it as Heap. A heap is a table that does not have a clustered index
and, therefore, the pages are not linked by pointers. The IAM pages are
the only structures that link the pages in a table together.
Unindexed tables are good for fast storing of data. Many times it is better
to drop all indexes from table and than do bulk of inserts and to restore
those indexes after that.
<Event_Type> refers to the event that will fire the trigger which can be
anything like Create_Table, Drop_Table, Alter_Table, etc.
1. We specify the Table as the return type instead of any scalar data
type.
2. The function body is not closed between BEGIN and END block
3. The structure of the table that gets returned is determined by the
select statement within the function.
The rules of transaction management tell that either all the statements in
the transaction should be executed successfully or none of those
statements to be executed. To manage transaction we have provided with
transaction control language that provides commands like “COMMIT
TRANSACTION”, “ROLLBACK TRANSACTION”, and “SAVE
TRANSACTION”.
1. COMMIT TRANSACTION: It indicates that the transaction
completed successfully and all the data manipulation operation
performed since the start of the transaction committed to the
database and frees the resources held by the transaction.
2. ROLLBACK TRANSACTION: It will bring back an implicit or explicit
transaction to the beginning of the transaction or erase all data
modifications made from resources held by the transaction.
3. SAVE TRANSACTION: This is used for dividing or breaking a
transaction into multiple units so that we will have a chance of
rollbacking a transaction up to a location.
Explain various types of SQL Server transactions modes.
SQL Server transactions are classified into three types, they are as follows
1. Auto Commit Transaction Mode (default)
2. Implicit Transaction Mode
3. Explicit Transaction Mode
Auto Commit Transaction Mode in SQL Server:
1. In this mode of transaction, programmers are not responsible for
beginning a transaction or ending a transaction. Whenever we
perform or execute any DML statement SQL Server will only begin
the transaction and end the transaction with a Commit or Rollback.
So the programmer does not have any control over them.
2. This is the default mode of transaction. In this mode, if the
transaction is completed successfully, it is committed. If the
transaction faces any error, it is rolled back.
3. In auto-commit mode, each SQL statement is treated as a separate
transaction.
Implicit Transaction Mode in SQL Server:
1. In this mode of transaction SQL Server begins a transaction
implicitly before the execution of any DML statement and
developers are responsible to end the transaction with a commit or
rollback. Once a transaction ends, automatically a new transaction
start.
2. When the transaction is in implicit mode, a new transaction starts
automatically after the current transaction is committed or rolled
back. Nothing needs to be done to define the start of the
transaction. It generates a continues chain of transactions.
3. Implicit mode for transactions in SQL Server is set to ON or OFF by
using the command SET IMPLICIT_TRANSACTIONS to ON or OFF. If
the implicit mode is set to ON when a new transaction is implicitly
started whenever any particular SQL statement is executed. The
particular SQL statement includes INSERT, SELECT, DELETE, AND
UPDATE and other SQL statements as well. It is called implicit mode
because of the fact that once IMPLICIT_TRANSACTIONS is set to ON
then the transactions are created implicitly for certain SQL
statements without having to say we want to create a transaction
each time.
Explicit Transaction Mode in SQL Server:
1. In this mode of transaction, a programmer is only responsible for
beginning the transaction and ending the transaction.
2. Transactions that have a START and END explicitly written by the
programmer are called as an explicit transaction.
3. In the explicit mode of transaction, every transaction starts with a
BEGIN TRANSACTION statement and ends with either a ROLLBACK
TRANSACTION statement (when the transaction does not complete
successfully) or a COMMIT TRANSACTION statement (when the
transaction completes successfully). The explicit mode is most
commonly used in triggers, stored procedures and application
programs.
Execution:
EXEC DIVIDE 100, 5
EXEC DIVIDE 100, 0
In the above case when we execute the procedure we will get the error at
the second execution because the divisor value is ZERO where a number
cannot be divided by zero as per the rule of mathematics.
In SQL Server whenever an error occurs at a line, it will first print the error
message and then continues with the execution so in the above case
when the error occurred in the procedure the result will be as following
The problem in the above execution is even if the error occurred in the
program, it still showing the result so there are chances of users being
confused.
Note: Whenever an error occurred while executing a program developed
by using any programming language the program terminates abnormally
on the line where the error got occurred but in SQL Server it will still
continue the program execution.
Note:
@@ERROR is cleared and reset on each statement execution. Check it
immediately following the statement being verified, or save it to a
local variable that can be checked later.
In the tblProduct table, we already have a record with ProductId = 2.
So the insert statement causes a primary key violation error. @@ERROR
retains the error number, as we are checking for it immediately after the
statement that causes the error.
On the other hand, when you execute the code below, you get a
message ‘No Errors’ printed. This is because the @@ERROR is cleared
and reset on each statement execution.
Insert into tblProduct values(2, 'Mobile Phone', 1500, 100)
--At this point @@ERROR will have a NON ZERO value
Select * from tblProduct
--At this point, @@ERROR gets reset to ZERO, because of the
--select statement successfully executed
if(@@ERROR <> 0)
Print 'Error Occurred'
Else
Print 'No Errors'
Any set of SQL statements, that can possibly throw an exception are
wrapped between BEGIN TRY and END TRY blocks. If there is an exception
in the TRY block, the control immediately jumps to the CATCH block. If
there is no exception CATCH block will be skipped and the statements
after the CATCH block are executed.
Errors trapped by a CATCH block are not returned to the calling
application. If any part of the error information must be returned to
the application the code in the CATCH block must do so by using
RAISERROR() function.
In procedure spSellProduct, Begin Transaction and Commit
Transaction statements are wrapped between Begin Try and End Try
block. If there are no errors in the code that is enclosed in the TRY block,
then COMMIT TRANSACTION gets executed and the changes are made
permanent. On the other hand, if there is an error then the control
immediately jumps to the CATCH block. In the CATCH block, we are rolling
the transaction back. So it’s much easier to handle errors with Try/Catch
construct than with @@Error system function.
Also notice that in the scope of the CATCH block, there are several system
functions that are used to retrieve more information about the
error that occurred these functions return NULL if they are executed
outside the scope of the CATCH block.
TRY/CATCH cannot be used in a user-defined function.
Create Procedure spSellProduct
@ProductId int,
@QuantityToSell int
As
Begin
-- Check the stock available, for the product we want to sell
Declare @StockAvailable int
Select @StockAvailable = QtyAvailable
From tblProduct where ProductId = @ProductId
-- Throw an error to the calling application, if enough stock is not
available
If(@StockAvailable< @QuantityToSell)
Begin
Raiserror('Not enough stock available',16,1)
End
-- If enough stock available
Else
Begin
Begin Try
Begin Transaction
-- First reduce the quantity available
Update tblProduct set QtyAvailable = (QtyAvailable - @QuantityToSell)
where ProductId = @ProductId
Declare @MaxProductSalesId int
-- Calculate MAX ProductSalesId
Select @MaxProductSalesId = Case When
MAX(ProductSalesId) IS NULL
Then 0 else MAX(ProductSalesId) end
From tblProductSales
--Increment @MaxProductSalesId by 1, so we don't get a primary key
violation
Set @MaxProductSalesId = @MaxProductSalesId + 1
Insert into tblProductSales values(@MaxProductSalesId, @ProductId,
@QuantityToSell)
Commit Transaction
End Try
Begin Catch
Rollback Transaction
Select
ERROR_NUMBER() as ErrorNumber,
ERROR_MESSAGE() as ErrorMessage,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_STATE() as ErrorState,
ERROR_SEVERITY() as ErrorSeverity,
ERROR_LINE() as ErrorLine
End Catch
End
End
What is ERROR_MESSAGE()?
This method is used to display what type of error has occurred in the try
block.
PREDEFINED ERRORS:
Whenever an error occurs under a program like dividing a number by
zero, violation of primary key, violation of Check constraint etc, the
system displays an error message telling us the problem encountered in
the code.
Every error that occurs in the program is associated with four attributes
1. Error Number
2. Error Message
3. SEVERITY Level
4. State
Example: Message 8134 (Error Number), Level 16(SEVERITY
Level), State 1 (state), Divide by Zero error encountered (Error
Message)
ERROR NUMBER: Error number is a unique identification given for each
and every error that occurs in the program. This value will be below
50,000 for predefined errors and must be above 50,000 for error defined
by the user.
ERROR MESSAGE: It is a brief information describing the error occurred
which should be maxed from 2047 characters.
SEVERITY LEVEL: This tells about the importance of the error which can
be ranging between 0 to 24. In which
0 to 9: are not serves which can be considered as information or status
messages.
11 to 16: Indicates these errors can be created by the user.
17 to 19: Indicates these are software errors cannot be corrected by the
user must be reported to the system administrator.
20 to 24: Indicates fatal errors and if these errors occur they can damage
the system or database. So here the connection immediately terminates
with the database.
STATE: It is an arbitrary value which is not that important can be ranging
from 0 to 127. We use this whenever the same error has to occur in
multiple places.
Note: We can find the information of all predefined errors under the table
“Sys Messages”
How to raise errors explicitly in a program?
Generally, errors raised in a program on predefined reasons like dividing a
number by zero, violation of primary key, violation of check, violation of
referential integrity etc. Whereas if required we can also raise an error in
our programs in two different ways
1. Using Raiserror statement
2. Using a throw statement (new feature of SQL Server 2012)
Syntax: Raiserror
Raiserror (errorid/errormsg, SEVERITY, state)[with log]
Syntax: throw
Throw errorid, errormsg, state
The above procedure can also be defined with the help of a throw
statement in place of Raiserror as following.
ALTER PROCEDURE DIVIDEBYONE(@X INT, @Y INT)
AS
BEGIN
DECLARE @Z INT
SET @Z = 0
BEGIN TRY
IF @Y = 1
THROW 50000,'DIVISOR CANNOT BE ONE', 1
SET @Z = @X / @Y
PRINT'THE RESULT IS: '+CAST(@Z AS VARCHAR)
END TRY
BEGIN CATCH
PRINT ERROR_NUMBER()
PRINT ERROR_MESSAGE()
PRINT ERROR_SEVERITY()
PRINT ERROR_STATE()
END CATCH
END
What is @@ERROR?
The @@ERROR automatic variable returns the error code of the last
Transact-SQL statement. If there was no error, @@ERROR returns zero.
Because @@ERROR is reset after each Transact-SQL statement, it must
be saved to a variable if it is needed to process it further after checking it.
Stored procedures report errors to client applications via the RAISERROR
command. RAISERROR doesn’t change the flow of a procedure; it merely
displays an error message, sets the @@ERROR automatic variable, and
optionally writes the message to the SQL Server error log and the NT
application event log.
What is SubProgram?
A subprogram in SQL Server is a named block of code that is directly
saved on the database server. Then we can execute this subprogram
when and where it is required. Under the databases, a subprogram is
reported as a “stored procedure” or “stored function” or “database
triggers”.
The following procedure returns the total number of employees from the
Employee table, using the output parameter i.e. @TotalCount.
Create Procedure spGetTotalCountOfEmployees1
@TotalCount int output
As
Begin
Select @TotalCount = COUNT(ID)
From tblEmployee
End
Using a stored procedure we can also avoid the SQL Injection attack.
What is an execution plan? When would you use it? How would
you view the execution plan?
An execution plan is basically a roadmap that graphically or textually
shows the data retrieval methods chosen by the SQL Server query
optimizer for a stored procedure or ad-hoc query and is a very useful tool
for a developer to understand the performance characteristics of a query
or stored procedure since the plan is the one that SQL Server will place in
its cache and use to execute the stored procedure or query. From within
Query Analyser is an option called “Show Execution Plan” (located on the
Query drop-down menu). If this option is turned on it will display the query
execution plan in the separate window when the query is run again.
This procedure is executed on the session which is created it and once the
session is closed this procedure is automatically deleted. And we cannot
access this procedure once the session is closed also we cannot access
this procedure from another session.
Customers table does not exist. When we execute the above SQL code,
the stored procedure spGetCustomers will be successfully created
without errors. But when you try to call or execute the stored procedure
using Execute spGetCustomers, we will get a runtime error stating
Invalid object name ‘Customers’.
So, at the time of creating stored procedures, only the syntax of the SQL
code is checked. The objects used in the stored procedure are not
checked for their existence. Only when we try to run the procedure, the
existence of the objects is checked. So, the process of postponing, the
checking of the physical existence of the objects until runtime, is called
deferred name resolution in the SQL Server.
Functions in SQL server does not support deferred name resolution. If
we try to create an inline table-valued function as shown below, we get an
error stating Invalid object name ‘Customers’ at the time of the creation of
the function itself.
Create function fnGetCustomers()
returns table
as
return Select * from Customers
So, this proves that stored procedures support deferred name resolution,
whereas function does not. In fact, this is one of the major differences
between functions and stored procedures in SQL Server.
Can a stored procedure call itself or recursive stored procedure?
How many level SP nesting possible?
Yes. Because Transact-SQL supports recursion, you can write stored
procedures that call themselves. Recursion can be defined as a method of
problem solving wherein the solution is arrived at by repetitively applying
it to subsets of the problem. A common application of recursive logic is to
perform numeric computations that lend themselves to repetitive
evaluation by the same processing steps. Stored procedures are nested
when one stored procedure calls another or executes managed code by
referencing a CLR routine, type, or aggregate. You can nest stored
procedures and managed code references up to 32 levels.
A cross join produces the Cartesian product of the tables involved in the
join. The size of a Cartesian product result set is the number of rows in the
first table multiplied by the number of rows in the second table. A query
involving a CROSS JOIN for the Candidate and Company Table is shown
below.
SELECT Cand.CandidateId,
Cand.FullName,
Cand.CompanyId,
Comp.CompanyId,Comp.CompanyName
FROM Candidate Cand
CROSS JOIN Company Comp
If we run the above query, we produce the result set shown in the
image below.
If we want to select all the rows from the LEFT table (In our example
Candidate Table) that have a non-null foreign key value (CompanyId in
Candidate 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 we look at the output, we only got 5 rows. We did not get the 2 rows
that have a 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.
Instead of using the INNER JOIN keyword we can just use the 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 we run the above query the output will be as shown below. If we look at
the output, we now got all 7 rows (all the rows from the Candidate Table)
including the row that has a null value for the CompanyId column in the
Candidate Table. So, the LEFT OUTER JOIN would get all the rows from the
LEFT Table including the rows that have null foreign key value.
Instead of using the LEFT OUTER JOIN keyword we can just use the LEFT
JOIN keyword as shown below. LEFT OUTER JOIN or LEFT JOIN means 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 we run the above query the output will be as shown below. If we look at
the output, we now got 6 rows. All the rows from the Candidate Table that
has non-null foreign key value plus all the rows from the Company Table
including the row that is not referenced in the Candidate Table.
Instead of using the RIGHT OUTER JOIN keyword we can just use the
RIGHT JOIN keyword as shown below. RIGHT OUTER JOIN or RIGHT JOIN
means 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 we run the above query the output will be as shown below. If you look at
the output, we now got 8 rows. All the rows from the Candidate Table and
all the rows from the Company Table.
Instead of using FULL OUTER JOIN keyword we can just use FULL
JOIN keyword as shown below. FULL OUTER JOIN or FULL JOIN means 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