28
The main statement used to retrieve data in T-SQL is the SELECT statement. Following are the main query clauses specified in the order that you are supposed to type them (known as “keyed-in order”): 1. SELECT 2. FROM 3. WHERE 4. GROUP BY 5. HAVING 6. ORDER BY But as mentioned, the logical query processing order, which is the conceptual interpretation order, is different. It starts with the FROM clause. Here is the logical query processing order of the six main query clauses: 1. FROM 2. WHERE 3. GROUP BY 4. HAVING 5. SELECT 6. ORDER BY When referring to identifiers of attributes, schemas, tables, and other objects, there are cases in which you are required to use delimiters vs. cases in which the use of delimiters is optional. T-SQL supports both a standard form to delimit identifiers using double quotation marks, as in "Sales"."Orders", as well as a proprietary form using square brackets, as in [Sales].[Orders]. When the identifier is “regular,” delimiting it is optional. In a regular identifier, the identifier complies with the rules for formatting identifiers. The rules say that the first character must be a letter in the range A through Z (lower or uppercase), underscore (_), at sign (@), or number sign (#). Subsequent characters can include letters, decimal numbers, at sign, dollar sign ($), number sign, or underscore. The identifier cannot be a reserved keyword in T-SQL, cannot have embedded spaces, and must not include supplementary characters. An identifier that doesn’t comply with these rules must be delimited. Observe that when any of the inputs is NULL, the + operator returns a NULL. SELECT empid, country, region, city, country + COALESCE( N',' + region, N'') + N',' + city AS location FROM HR.Employees; Another option is to use the CONCAT function which, unlike the + operator, substitutes a

The Main Statement Used to Retrieve Data in T

Embed Size (px)

DESCRIPTION

gchgc

Citation preview

Page 1: The Main Statement Used to Retrieve Data in T

The main statement used to retrieve data in T-SQL is the SELECT statement. Following arethe main query clauses specified in the order that you are supposed to type them (known as“keyed-in order”):1. SELECT2. FROM3. WHERE4. GROUP BY5. HAVING6. ORDER BYBut as mentioned, the logical query processing order, which is the conceptual interpretationorder, is different. It starts with the FROM clause. Here is the logical query processingorder of the six main query clauses:1. FROM2. WHERE3. GROUP BY4. HAVING5. SELECT6. ORDER BY

When referring to identifiers of attributes, schemas, tables, and other objects, there are casesin which you are required to use delimiters vs. cases in which the use of delimiters is optional.T-SQL supports both a standard form to delimit identifiers using double quotation marks, asin "Sales"."Orders", as well as a proprietary form using square brackets, as in [Sales].[Orders].When the identifier is “regular,” delimiting it is optional. In a regular identifier, the identifiercomplies with the rules for formatting identifiers. The rules say that the first character must bea letter in the range A through Z (lower or uppercase), underscore (_), at sign (@), or numbersign (#). Subsequent characters can include letters, decimal numbers, at sign, dollar sign ($),number sign, or underscore. The identifier cannot be a reserved keyword in T-SQL, cannothave embedded spaces, and must not include supplementary characters.An identifier that doesn’t comply with these rules must be delimited.

Observe that when any of the inputs is NULL, the + operator returns a NULL.

SELECT empid, country, region, city,country + COALESCE( N',' + region, N'') + N',' + city AS locationFROM HR.Employees;

Another option is to use the CONCAT function which, unlike the + operator, substitutes aNULL input with an empty string. Here’s how the query looks.

SELECT empid, country, region, city,CONCAT(country, N',' + region, N',' + city) AS location

FROM HR.Employees;

With the SUBSTRING function, you can extract a substring from a string given as the firstargument, starting with the position given as the second argument, and a length given as thethird argument. For example, the expression SUBSTRING('abcde', 1, 3) returns 'abc'.

The LEFT and RIGHT functions extract a requested number of characters from the left andright ends of the input string, respectively. For example, LEFT('abcde', 3) returns 'abc' andRIGHT('abcde', 3) returns 'cde'.

The CHARINDEX function returns the position of the first occurrence of the string providedas the first argument within the string provided as the second argument. For example, the expressionCHARINDEX(' ','Itzik Ben-Gan') looks for the first occurrence of a space in the second input, returning 6 in this example.

The LEN function returns the length of an input string in terms of the number of characters.Note that it returns the number of characters, not bytes, whether the input is a regular

Page 2: The Main Statement Used to Retrieve Data in T

character or Unicode character string. For example, the expression LEN(N'xyz') returns 3. Ifthere are any trailing spaces, LEN removes them.

This section covers functions that you can use to apply formatting options to an input string.Those are the UPPER, LOWER, LTRIM, RTRIM, and FORMAT functions.The first four functions are self-explanatory (uppercase form of the input, lowercase formof the input, input after removal of leading spaces, and input after removal of trailing spaces).Note that there’s no TRIM function that removes both leading and trailing spaces; to achievethis, you need to nest one function call within another, as in RTRIM(LTRIM(<input>)).

The COALESCE function accepts a list of expressions as input and returns the first thatis not NULL, or NULL if all are NULLs. For example, the expression COALESCE(NULL, 'x', 'y')returns 'x'. More generally, the expression:COALESCE(<exp1>, <exp2>, …, <expn>)

T-SQL supports a nonstandard function called ISNULL that is similar to the standardCOALESCE, but it’s a bit more limited in the sense that it supports only two inputs. LikeCOALESCE, it returns the first input that is not NULL.

There are a couple of subtle differences between COALESCE and ISNULL that you might beinterested in. One difference is in which input determines the type of the output. Consider thefollowing code.DECLARE@x AS VARCHAR(3) = NULL,@y AS VARCHAR(10) = '1234567890';SELECT COALESCE(@x, @y) AS [COALESCE], ISNULL(@x, @y) AS [ISNULL];Here’s the output of this code.COALESCE ISNULL---------- ------1234567890 123Observe that the

Observe that the type of the COALESCE expression is determined by the returned element,whereas the type of the ISNULL expression is determined by the first input.

T-SQL also supports the standard NULLIF function. This function accepts two input expressions,returns NULL if they are equal, and returns the first input if they are not. For example,consider the expression NULLIF(col1, col2). If col1 is equal to col2, the function returns aNULL; otherwise, it returns the col1 value.

With the IIF function, you can return one value if an inputpredicate is true and another value otherwise. The function has the following form.IIF(<predicate>, <true_result>, <false_or_unknown_result>)

The CHOOSE function allows you to provide a position and a list of expressions, and returnsthe expression in the indicated position. The function takes the following form.CHOOSE(<pos>, <exp1>, <exp2>, …, <expn>)

Here’s one way to compute the end of the current month.SELECT EOMONTH(getDate()) AS end_of_current_month;

And here’s one way to compute the end of the current year.

SELECT DATEADD(month,12-month(getDate()),EOMONTH(getDate())) AS end_of_current_year;

Products table that returns the existing numericproduct ID, in addition to the product ID formatted as a fixed-sized string with 10digits with leading zeros.

SELECT productid,RIGHT(REPLICATE('0', 10) + CAST(productid AS VARCHAR(10)), 10) AS str_productid

Page 3: The Main Statement Used to Retrieve Data in T

FROM Production.Products;

For example, suppose you have a stored procedure that accepts an input parameter @dtrepresenting an input shipped date. The procedure is supposed to return orders that wereshipped on the input date. If the shippeddate column did not allow NULLs, you could use thefollowing query to address this task.SELECT orderid, orderdate, empidFROM Sales.OrdersWHERE shippeddate = @dt;

However, the shippeddate column does allow NULLs; those represent orders that weren’tshipped yet. When users will need all orders that were not shipped yet, the users will providea NULL as the input shipped date, and your query would need to be able to cope with such acase.

SELECT orderid, orderdate, empidFROM Sales.OrdersWHERE COALESCE(shippeddate, '19000101') = COALESCE(@dt, '19000101');

better way:-

SELECT orderid, orderdate, empidFROM Sales.OrdersWHERE shippeddate = @dtOR (shippeddate IS NULL AND @dt IS NULL);

If you want to look for a character that is considered a wildcard, you can indicate it aftera character that you designate as an escape character by using the ESCAPE keyword. For example,the expression col1 LIKE '!_%' ESCAPE '!' looks for strings that start with an underscore(_) by using an exclamation point (!) as the escape character.

select * from empwhere ename like '!_%' ESCAPE '!'

(or)

select * from empwhere ename like '\_%' ESCAPE '\'

Page 4: The Main Statement Used to Retrieve Data in T

BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression.NOT BETWEEN returns TRUE if the value of test_expression is less than the value of begin_expression or greater than the value of end_expression.

using between with datetime values:-When the time part is unspecified, it defaults to 12:00 A.M

SELECT BusinessEntityID, RateChangeDateFROM HumanResources.EmployeePayHistoryWHERE RateChangeDate BETWEEN '20011212' AND '20020105';

 Note that a row that contains a time part that is after 12:00 A.M. on 2002-01-05 would not be returned by this query because it falls outside the range.

whenever we want to deal with the datetime column in the condition part we should be careful.why because sql server round up the milli second value,so if you are mentioned the date time with time part as 23:59:59.999 then it will round up to 12:00 Am(00:00:00.000)

SELECT orderid, orderdate, empid, custidFROM Sales.OrdersWHERE orderdate >= '20070201' AND orderdate < ='20070227 23:59:59.999'order by orderdate desc;

the above query will also return the records with order date 2007-02-28 00:00:00.000 which is not expected.so to aviod this write the query as below.

SELECT orderid, orderdate, empid, custidFROM Sales.OrdersWHERE orderdate >= '20070201' AND orderdate < '2007-02-28 00:00:00.000'order by orderdate desc;

Between val1 and val2 --- > (column/expression) >=val1 and <=val2

A query that doesn’t have an explicit instruction to return the rows in a particular order doesn’t guarantee the order of rows in the result. When you do need such a guarantee, the only way to provide it is by adding an ORDER BY clause to the query.

If you don’t indicate a direction for sorting, ascending order is assumed by default. Youcan be explicit and specify city ASC, but it means the same thing as not indicating the direction.For descending ordering, you need to explicitly specify DESC.

Another tricky aspect of ordering is treatment of NULLs.

Should all NULL's sort together? If so, should they sort beforeor after non-NULL values? In SQLServer the decision was to sort them before non-NULLs

As an interesting challenge, see if you can figureout how to sort the orders by shipped date ascending, but have NULLs sort last.

Page 5: The Main Statement Used to Retrieve Data in T

SELECT orderid, case when shippeddate is NULL then '9999-01-01'else shippeddateend as shipdateFROM Sales.OrdersWHERE custid = 20ORDER BY shipdate

Without good indexes, SQL Server needs to sort the data, and sortingcan be expensive, especially when a large set is involved. If you don’t need to return the datasorted, make sure you do not specify an ORDER BY clause, to avoid unnecessary costs.

The PERCENT option puts a ceiling on the resulting number of rows if it’s not whole. In thisexample, without the TOP option, the number of rows in the result is 830. Filtering 1 percentgives you 8.3, and then the ceiling of this value gives you 9; hence, the query returns 9 rows.

SELECT TOP (1) PERCENT orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC;

The TOP option isn’t limited to a constant input; instead, it allows you to specify a selfcontainedexpression. From a practical perspective, this capability is especially important whenyou need to pass a parameter or a variable as input, as the following code demonstrates.

DECLARE @n AS BIGINT = 5;SELECT TOP (@n) orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC;

TOP WITH TIES :Used when you want to return two or more rows that tie for last place in the limited results set. Must be used with the ORDER BY clause. WITH TIES may cause more rows to be returned than the value specified inexpression. For example, if expression is set to 5 but 2 additional rows match the values of the ORDER BYcolumns in row 5, the result set will contain 7 rows.

SELECT TOP (3) WITH TIES orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC;

The OFFSET and FETCH clauses appear right after the ORDER BY clause, and in fact, inT-SQL, they require an ORDER BY clause to be present. You first specify the OFFSET clauseindicating how many rows you want to skip (0 if you don’t want to skip any); you then optionallyspecify the FETCH clause indicating how many rows you want to filter. For example,the following query defines ordering based on order date descending, followed by order IDdescending; it then skips 50 rows and fetches the next 25 rows.

As mentioned, in T-SQL, the OFFSET-FETCH option requires an ORDER BY clause to bepresent. Also, in T-SQL—contrary to standard SQL—a FETCH clause requires an OFFSET clauseto be present. So if you do want to filter some rows but skip none, you still need to specifythe OFFSET clause with 0 ROWS.

SELECT orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC, orderid DESCOFFSET 0 ROWS FETCH FIRST 25 ROWS ONLY;

While in T-SQL, a FETCH clause requires an OFFSET clause, and the OFFSET clause doesn’t

Page 6: The Main Statement Used to Retrieve Data in T

require a FETCH clause. In other words, by indicating an OFFSET clause, you’re requesting toskip some rows; then by not indicating a FETCH clause, you’re requesting to return all remainingrows. For example, the following query requests to skip 50 rows, returning all the rest.

SELECT orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC, orderid DESCOFFSET 50 ROWS;

With both the OFFSET and the FETCH clauses, you can use expressions as inputs. This is veryhandy when you need to compute the input values dynamically. For example, suppose thatyou’re implementing a paging concept where you return to the user one page of rows at a time.The user passes as input parameters to your procedure or a function the page number they areafter (@pagenum parameter) and page size (@pagesize parameter). This means that you needto skip as many rows as @pagenum minus one times @pagesize, and fetch the next @pagesizerows. This can be implemented using the following code (using local variables for simplicity).DECLARE @pagesize AS BIGINT = 25, @pagenum AS BIGINT = 3;SELECT orderid, orderdate, custid, empidFROM Sales.OrdersORDER BY orderdate DESC, orderid DESCOFFSET (@pagenum - 1) * @pagesize ROWS FETCH NEXT @pagesize ROWS ONLY;

if (null=null) print 'null is equal to null' else if (null!=null) print 'null is not equal to null'else print 'null is unknown even can not be compared with a null value'

o/p:- null is unknown even can not be compared with a null value

if (5 is not null) print 'null is equal to null'if (null is not null) print 'null to null'if (null is null) print 'null is not equal to null'else print 'null is unknown even can not be compared with a null value'

o/p :- null is equal to nullnull is not equal to null

see the difference in above two queries when using operators and string comparisions.

SELECTS.companyname AS supplier, S.country,P.productid, P.productname, P.unitpriceFROM Production.Suppliers AS SLEFT OUTER JOIN Production.Products AS PON S.supplierid = P.supplieridWHERE S.country = N'Japan';

SELECTS.companyname AS supplier, S.country,P.productid, P.productname, P.unitpriceFROM Production.Suppliers AS SLEFT OUTER JOIN Production.Products AS P

Page 7: The Main Statement Used to Retrieve Data in T

ON S.supplierid = P.supplieridand S.country = N'Japan'; ---> ON ( S.supplierid = P.supplierid and S.country = N'Japan') --> it picks all the rows from table Production.Suppliers where S.supplierid = P.supplierid and S.country = N'Japan' and also pick the rows from the same left table Production.Suppliers where S.supplierid != P.supplierid and S.country != N'Japan')

INNER JOIN ->ONLY MATCING RECORDS FORM THE TWO TABLES

LEFT JOIN ->PRESERVES THE LEFT TABLE,MATCHING VALUES ARE RETRIVED FRM THE RIGHT TABLE,IF NO MATCH THEN RETURNS NULL FOR THE RIGHT TABLE COLUMNS.

RIGHT JOIN: PRESERVES THE RIGHT TABLE,MATCHING VALUES ARE RETRIVED FRM THE LEFT TABLE,IF NO MATCH THEN RETURNS NULL FOR THE LEFT TABLE COLUMNS.

FULL JOIN :- PRESERVES BOTH LEFT ANF RIGHT TABLES.NULL IS RETURNED FOR THE LEFT AND RIGHT TABLES IF THERE IS NO MACTH.

CROSS JOIN : IT WILL NOT CHECK FR THE MATCH.IF LEFT TABLE HAS M ROWS AND RIGHT TABLE HAS N ROWS THE RESULT OF CROSS JOIN WILL BE MxN ROWS.

SELECTS.companyname AS supplier, S.country,P.productid, P.productname, P.unitprice,C.categorynameFROM Production.Suppliers AS SLEFT OUTER JOIN Production.Products AS PON S.supplierid = P.supplieridINNER JOIN Production.Categories AS CON C.categoryid = P.categoryidWHERE S.country = N'Japan';

when there are multiple joins the execution goes through from left to right.In the above query left join get executed first and the result will act as left table to the inner join.

SELECTS.companyname AS supplier, S.country,P.productid, P.productname, P.unitprice,C.categorynameFROM Production.Suppliers AS SLEFT OUTER JOIN(Production.Products AS PINNER JOIN Production.Categories AS CON C.categoryid = P.categoryid)ON S.supplierid = P.supplieridWHERE S.country = N'Japan';

In the above query inner join is executed first and then left join.

Self-Contained SubqueriesSelf-contained subqueries are subqueries that have no dependency on the outer query.

a subquery can return different forms of results. It can return a single value,multiple values, or even an entire table result.

Page 8: The Main Statement Used to Retrieve Data in T

Subqueries that return a single value, or scalar subqueries, can be used where a singlevaluedexpression is expected.

SELECT productid, productname, unitpriceFROM Production.ProductsWHERE unitprice =(SELECT MIN(unitprice)FROM Production.Products);

If the scalar subquery returns an empty set, it is converted to a NULL.

Correlated SubqueriesCorrelated subqueries are subqueries where the inner query has a reference to a column fromthe table in the outer query.

SELECT categoryid, productid, productname, unitpriceFROM Production.Products AS P1WHERE unitprice =(SELECT MIN(unitprice)FROM Production.Products AS P2WHERE P2.categoryid = P1.categoryid);

SELECT custid, companynameFROM Sales.Customers AS CWHERE EXISTS(SELECT *FROM Sales.Orders AS OWHERE O.custid = C.custidAND O.orderdate = '20070212');

The EXISTS predicate accepts a subquery as input and returns true when the subqueryreturns at least one row and false otherwise.

NOT EXISTS:-

SELECT custid, companynameFROM Sales.Customers AS CWHERE NOT EXISTS(SELECT *FROM Sales.Orders AS OWHERE O.custid = C.custidAND O.orderdate = '20070212');

Table ExpressionsTable expressions are named queries. You write an inner query that returns a relational resultset, name it, and query it from an outer query. T-SQL supports four forms of table expressions:■■ Derived tables■■ Common table expressions (CTEs)■■ Views■■ Inline table-valued functionsThe first two are visible only to the statement that defines them. As for the last two, youpreserve the definition of the table expression in the database as an object; therefore, it’sreusable

Derived Tables

Page 9: The Main Statement Used to Retrieve Data in T

A derived table is probably the form of table expression that most closely resembles asubquery—only a subquery that returns an entire table result. You define the derivedtable’s inner query in parentheses in the FROM clause of the outer query, and specify thename of the derived table after the parentheses.

SELECT categoryid, productid, productname, unitpriceFROM (SELECTROW_NUMBER() OVER(PARTITION BY categoryidORDER BY unitprice, productid) AS rownum,categoryid, productid, productname, unitpriceFROM Production.Products) AS DWHERE rownum <= 2;

CTEsA common table expression (CTE) is a similar concept to a derived table in the sense that it’sa named table expression that is visible only to the statement that defines it. Like a queryagainst a derived table, a query against a CTE involves three main parts:■■ The inner query■■ The name you assign to the query and its columns■■ The outer query

WITH <CTE_name>AS(<inner_query>)<outer_query>;

WITH C AS --C is the CTE name(SELECT ---inner queryROW_NUMBER() OVER(PARTITION BY categoryidORDER BY unitprice, productid) AS rownum,categoryid, productid, productname, unitpriceFROM Production.Products)SELECT categoryid, productid, productname, unitprice --outer queryFROM CWHERE rownum <= 2;

You don’t nest CTEs like you do derived tables. If you need to define multiple CTEs, yousimply separate them by commas. Each can refer to the previously defined CTEs, and theouter query can refer to all of them. After the outer query terminates, all CTEs defined in thatWITH statement are gone. The fact that you don’t nest CTEs makes it easier to follow the logicand therefore reduces the chances for errors. For example, if you want to refer to one CTEfrom another, you can use the following general form.

WITH C1 AS(SELECT ...FROM T1WHERE ...

Page 10: The Main Statement Used to Retrieve Data in T

),C2 AS(SELECTFROM C1WHERE ...)SELECT ...FROM C2WHERE ...;

Because the CTE name is assigned before the start of the outer query, you can refer tomultiple instances of the same CTE name, unlike with derived tables. The general form lookslike the following.WITH C AS(SELECT ...FROM T1)SELECT ...FROM C AS C1INNER JOIN C AS C2ON ...;

CTEs also have a recursive form. The body of the recursive query has two or more queries,usually separated by a UNION ALL operator. At least one of the queries in the CTE body,known as the anchor member, is a query that returns a valid relational result. The anchorquery is invoked only once. In addition, at least one of the queries in the CTE body, known asthe recursive member, has a reference to the CTE name. This query is invoked repeatedly untilit returns an empty result set.

As an example, the following code uses a recursive CTE to return the management chainleading all the way up to the CEO for a specified employee.

WITH EmpsCTE AS(SELECT empid, mgrid, firstname, lastname, 0 AS distanceFROM HR.EmployeesWHERE empid = 9UNION ALLSELECT M.empid, M.mgrid, M.firstname, M.lastname, S.distance + 1 AS distanceFROM EmpsCTE AS SJOIN HR.Employees AS MON S.mgrid = M.empid)SELECT empid, mgrid, firstname, lastname, distanceFROM EmpsCTE;

Views and Inline Table-Valued FunctionsAs you learned in the previous sections, derived tables and CTEs are table expressions that arevisible only in the scope of the statement that defines them. After that statement terminates,the table expression is gone. Hence, derived tables and CTEs are not reusable. For reusability,you need to store the definition of the table expression as an object in the database, and forthis you can use either views or inline table-valued functions. Because these are objects in thedatabase, you can control access by using permissions.

The main difference between views and inline table-valued functions is that the formerdoesn’t accept input parameters and the latter does.

Page 11: The Main Statement Used to Retrieve Data in T

IF OBJECT_ID('Sales.RankedProducts', 'V') IS NOT NULL DROP VIEW Sales.RankedProducts;GOCREATE VIEW Sales.RankedProductsASSELECTROW_NUMBER() OVER(PARTITION BY categoryidORDER BY unitprice, productid) AS rownum,categoryid, productid, productname, unitpriceFROM Production.Products;GO

Note that it’s not the result set of the view that is stored in the database; rather, only itsdefinition is stored. Now that the definition is stored, the object is reusable. Whenever youneed to query the view, it’s available to you, assuming you have the permissions to query it.

SELECT categoryid, productid, productname, unitpriceFROM Sales.RankedProductsWHERE rownum <= 2;

As for inline table-valued functions, they are very similar to views in concept; however,as mentioned, they do support input parameters. So if you want to define something like aview with parameters, the closest you have is an inline table-valued function. As an example,consider the recursive CTE from the section about CTEs that retuned the management chainleading to employee 9. Suppose that you wanted to encapsulate the logic in a table expressionfor reusability, but also wanted to parameterize the input employee instead of using theconstant 9. You can achieve this by using an inline table-valued function with the followingdefinition.

IF OBJECT_ID('HR.GetManagers', 'IF') IS NOT NULL DROP FUNCTION HR.GetManagers;GOCREATE FUNCTION HR.GetManagers(@empid AS INT) RETURNS TABLEASRETURNWITH EmpsCTE AS(SELECT empid, mgrid, firstname, lastname, 0 AS distanceFROM HR.EmployeesWHERE empid = @empidUNION ALLSELECT M.empid, M.mgrid, M.firstname, M.lastname, S.distance + 1 AS distanceFROM EmpsCTE AS SJOIN HR.Employees AS MON S.mgrid = M.empid)SELECT empid, mgrid, firstname, lastname, distance --PART OF DEFINITION ONLYFROM EmpsCTE;GO

When querying the function, you pass a specific input employee ID as the following example shows.

SELECT *FROM HR.GetManagers(9) AS M;

Page 12: The Main Statement Used to Retrieve Data in T

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.

APP LY :-the inner query in the right table expression can have a reference to an element from the left table. So conceptually, the right table expression is evaluated separately for each left row. This means that you can replace the use of cursors in some cases with the APPLY operator.For example, suppose that you have a query that performs some logic for a particular customer.Suppose that you need to apply this query logic to each customer from the Sales.Customers table. You could use a cursor to iterate through the customers, and in each iterationinvoke the query for the current customer. Instead, you can use the APPLY operator, providingthe Sales.Customers table as the left input, and a table expression based on your query as theright input. You can correlate the customer ID in the inner query of the right table expression tothe customer ID from the left table.The two forms of the APPLY operator—CROSS and OUTER—are described in the nextsections.

CROSS APPLY:-

SELECT S.supplierid, S.companyname AS supplier, A.*FROM Production.Suppliers AS SCROSS APPLY (SELECT productid, productname, unitpriceFROM Production.Products AS PWHERE P.supplierid = S.supplierid

Page 13: The Main Statement Used to Retrieve Data in T

ORDER BY unitprice, productidOFFSET 0 ROWS FETCH FIRST 2 ROWS ONLY) AS AWHERE S.country = N'Japan';

using CTE :-

with toptwo as(SELECTROW_NUMBER() OVER(PARTITION BY supplieridORDER BY UNITPRICE,productid)AS RNUM,supplierid,productid,productname, unitpriceFROM Production.Products )SELECT s.supplierid,s.companyname as supplier,productid,productname,unitprice FROM TOPTWO t join Production.Suppliers son t.supplierid=s.supplieridWHERE t.RNUM<=2

OUTER APP LYThe OUTER APPLY operator does what the CROSS APPLY operator does, but also includes inthe result rows from the left side that get an empty set back from the right side.

and therefore,does return left rows when the right side returns an empty set. NULLs are used asplaceholders in the attributes from the right side in the outer rows.

Page 14: The Main Statement Used to Retrieve Data in T

SELECT S.supplierid, S.companyname AS supplier, A.*FROM Production.Suppliers AS SOUTER APPLY (SELECT productid, productname, unitpriceFROM Production.Products AS PWHERE P.supplierid = S.supplieridORDER BY unitprice, productidOFFSET 0 ROWS FETCH FIRST 2 ROWS ONLY) AS AWHERE S.country = N'Japan';Here’s the output of this query.

supplierid supplier productid productname unitprice----------- --------------- ---------- -------------- ----------4 Supplier QOVFD 74 Product BKAZJ 10.004 Supplier QOVFD 10 Product YHXGE 31.006 Supplier QWUSF 13 Product POXFU 6.006 Supplier QWUSF 15 Product KSZOI 15.5030 Supplier XYZ NULL NULL NULL --you will not get this row when u use cross apply

If you use the OUTER APPLY operator instead of CROSS APPLY, you will preserve the left side.

Using Set Operators :-

Page 15: The Main Statement Used to Retrieve Data in T

T-SQL supports three set operators: UNION,INTERSECT, and EXCEPT; it also supports one multiset operator: UNION ALL.

Working with set operators follows a number of guidelines:■■ Because complete rows are matched between the result sets, the number of columnsin the queries has to be the same and the column types of corresponding columnsneed to be compatible (implicitly convertible).■■ Set operators consider two NULLs as equal for the purpose of comparison. This is quiteunusual when compared to filtering clauses like WHERE and ON.■■ Because the operators are set operators and not cursor operators, the individual queriesare not allowed to have ORDER BY clauses.■■ You can optionally add an ORDER BY clause that determines presentation ordering ofthe result of the set operator.■■ The column names of result columns are determined by the first query.

UNION and UNION ALLThe UNION set operator unifies the results of the two input queries. As a set operator, UNIONhas an implied DISTINCT property, meaning that it does not return duplicate rows.

The UNIONALL operator unifies the results of the two input queries, but doesn’t try to eliminate duplicates.

INTERSECTThe INTERSECT operator returns only distinct rows that are common to both sets.

EXCEPTThe EXCEPT operator performs set difference. It returns distinct rows that appear in the firstquery but not the second.

Data Grouping :-

ex:-SELECT shipperid, YEAR(shippeddate) AS shippedyear,COUNT(*) AS numordersFROM Sales.OrdersWHERE shippeddate IS NOT NULLGROUP BY shipperid, YEAR(shippeddate)HAVING COUNT(*) < 100;

Notice that the query filters only shipped orders in the WHERE clause. This filter is appliedat the row level conceptually before the data is grouped. Next the query groups the data byshipper ID and shipped year. Then the HAVING clause filters only groups that have a count ofrows (orders) that is less than 100. Finally, the SELECT clause returns the shipper ID, shippedyear, and count of orders per each remaining group.

With general set functions, you can work with distinct occurrences by specifying a DISTINCTclause before the expression, as follows.

SELECT shipperid, COUNT(DISTINCT shippeddate) AS numshippingdatesFROM Sales.OrdersGROUP BY shipperid;

Note that the DISTINCT option is available not only to the COUNT function, but also toother general set functions. However, it’s more common to use it with COUNT.

Working with Multiple Grouping Sets :-

T-SQL supports three clauses that allowdefined multiple grouping sets: GROUPING SETS, CUBE, and ROLLUP. You use these in the

Page 16: The Main Statement Used to Retrieve Data in T

GROUP BY clause.You can use the GROUPING SETS clause to list all grouping sets that you want to define inthe query. As an example, the following query defines four grouping sets.SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrdersGROUP BY GROUPING SETS(( shipperid, YEAR(shippeddate) ),( shipperid ),( YEAR(shippeddate) ),( ));You list the grouping sets separated by commas within the outer pair of parentheses belongingto the GROUPING SETS clause. You use an inner pair of parentheses to enclose eachgrouping set. If you don’t indicate an inner pair of parentheses, each individual element isconsidered a separate grouping set.

This query defines four grouping sets. One of them is the empty grouping set, which definesone group with all rows for computation of grand aggregates.

the equivalent query for the above is

SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrdersGROUP BY shipperid, YEAR(shippeddate)

UNION ALLSELECT shipperid,null,COUNT(*) AS NUMOFORDERSFROM Sales.OrderSGROUP BY SHIPPERID

UNION ALL

SELECT NULL,YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrderSGROUP BY YEAR(shippeddate)

union all

select NULL,NULL,COUNT(*) AS numorders FROM Sales.OrderS

The output combines the results of grouping and aggregating the data of four differentgrouping sets. As you can see in the output, NULLs are used as placeholders in rows where anelement isn’t part of the grouping set. For example, in result rows that are associated with thegrouping set (shipperid), the shipyear result column is set to NULL. Similarly, in rows that areassociated with the grouping set (YEAR(shippeddate)), the shipperid column is set to NULL.You could achieve the same result by writing four separate grouped queries—each definingonly a single grouping set—and unifying their results with a UNION ALL operator.

The CUBE clause accepts a list of expressions asinputs and defines all possible grouping sets that can be generated from the inputs—includingthe empty grouping set. For example, the following query is a logical equivalent of the previousquery that used the GROUPING SETS clause.

SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrdersGROUP BY CUBE( shipperid, YEAR(shippeddate) );

The CUBE clause defines all four possible grouping sets from the two inputs:

Page 17: The Main Statement Used to Retrieve Data in T

1. ( shipperid, YEAR(shippeddate) )2. ( shipperid )3. ( YEAR(shippeddate) )4. ( )

The ROLLUP clause is also an abbreviation of the GROUPING SETS clause, but you use itwhen there’s a hierarchy formed by the input elements.

It will roll up the data in one direction in a hierarchical manner.

for ex:-

SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrdersGROUP BY rollup( shipperid, YEAR(shippeddate) ) -- GROUP BY A,Border by shipperid,shipyear

is qual to

SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numordersFROM Sales.OrdersGROUP BY shipperid, YEAR(shippeddate) -- GROUP BY A,B

UNION ALLSELECT shipperid,null,COUNT(*) AS NUMOFORDERSFROM Sales.OrderSGROUP BY SHIPPERID -- GROUP BY A

UNION ALL

select NULL,NULL,COUNT(*) AS numorders FROM Sales.OrderS -- EMPTY GROUPING SET WITH ALL ROWS

order by shipperid,shipyear

The GROUPING function accepts a single element as input and returns 0 when the elementis part of the grouping set and 1 (NULL place holder)when it isn’t. The following query demonstrates using theGROUPING function.

SELECTshipcountry, GROUPING(shipcountry) AS grpcountry,shipregion , GROUPING(shipregion) AS grpcountry,shipcity , GROUPING(shipcity) AS grpcountry,COUNT(*) AS numordersFROM Sales.OrdersGROUP BY ROLLUP( shipcountry, shipregion, shipcity ); --run this and see the o/p

SELECT C.custid, grouping(C.custid) as grpcustid,C.city, COUNT(*) AS numordersFROM Sales.Customers AS CINNER JOIN Sales.Orders AS OON C.custid = O.custidWHERE C.country = N'Spain'GROUP BY GROUPING SETS ( (C.custid, C.city), () )ORDER BY grpcustid -- (or) order by grouping(C.custid)

if you see the output of the above query NUll value is sorted into the last record as it is not original value of custid and it is a placeholder.that means order applied first for the original values of the column and then placeholders.

Page 18: The Main Statement Used to Retrieve Data in T

Pivoting and Unpivoting Data:-

Pivoting Data :-In all pivot queries, you need to identify three elements:■■ What do you want to see on rows? This element is known as the on rows, or groupingelement.■■ What do you want to see on columns? This element is known as the on cols, or spreadingelement.■■ What do you want to see in the intersection of each distinct row and column value?This element is known as the data, or aggregation element.

WITH PivotData AS(SELECT< grouping column >,< spreading column >,< aggregation column >FROM < source table >)SELECT < select list > --grouping column, required distinct spreading valuesFROM PivotDataPIVOT( < aggregate function >(< aggregation column >)FOR < spreading column > IN (< distinct spreading values >) ) AS P;

ex:-

WITH PivotData AS(SELECTcustid , -- grouping columnshipperid, -- spreading columnfreight -- aggregation columnFROM Sales.Orders)SELECT custid,[1] as shippperid_1,[2] shippperid_2,[3] shippperid_3FROM PivotDataPIVOT(SUM(freight) FOR shipperid IN ([1],[2],[3]) ) AS P;

The COUNT(*) function isn’t allowed as the aggregate function used by the PIVOToperator. If you need a count, you have to use the general COUNT(<col name>) aggregatefunction.

A PIVOT operator is limited to using only one aggregate function.

Un pivoting :-

WITH PivotData AS(SELECTcustid , -- grouping columnshipperid, -- spreading columnfreight -- aggregation columnFROM Sales.Orders)

Page 19: The Main Statement Used to Retrieve Data in T

SELECT *INTO Sales.FreightTotalsFROM PivotDataPIVOT( SUM(freight) FOR shipperid IN ([1],[2],[3]) ) AS P;SELECT * FROM Sales.FreightTotals;

in every unpivotingtask, you need to identify the three elements involved:■■ The set of source columns that you’re unpivoting (in this case, [1],[2],[3])■■ The name you want to assign to the target values column (in this case, freight)■■ The name you want to assign to the target names column (in this case, shipperid)

SELECT custid, shipperid, freightFROM Sales.FreightTotalsUNPIVOT( freight FOR shipperid IN([1],[2],[3]) ) AS U;

Window Aggregate FunctionsWindow aggregate functions are the same as the group aggregate functions (for example,SUM, COUNT, AVG, MIN, and MAX), except window aggregate functions are applied to awindow of rows defined by the OVER clause.

SELECT custid, orderid,val,SUM(val) OVER(PARTITION BY custid) AS custtotal,SUM(val) OVER() AS grandtotalFROM Sales.OrderValues;

SELECT distinct custid,SUM(val) OVER(PARTITION BY custid) AS custtotal,SUM(val) OVER() AS grandtotalFROM Sales.OrderValues

Window Ranking Functions :-T-SQL supports four window ranking functions: ROW_NUMBER, RANK, DENSE_RANK, and NTILE.

SELECT custid, orderid, val,ROW_NUMBER() OVER(ORDER BY val) AS rownum,RANK() OVER(ORDER BY val) AS rnk,DENSE_RANK() OVER(ORDER BY val) AS densernk,NTILE(100) OVER(ORDER BY val) AS ntile100FROM Sales.OrderValues;

The sample query doesn’t have a presentation ORDER BY clause, and therefore, there’s noassurance that the rows will be presented in any particular order. The window order clauseonly determines ordering for the window function’s computation. If you invoke a windowfunction in your query but don’t specify a presentation ORDER BY clause, there’s no guaranteethat the rows will be presented in the same order as the window function’s ordering.If you need such a guarantee, you need to add a presentation ORDER BY clause.

Page 20: The Main Statement Used to Retrieve Data in T

How to check if a table exists in sql server :-

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES            WHERE TABLE_NAME = N'ENTER TABLE NAME')BEGIN  PRINT 'Table Exists'

The above query checks the existence of the Customers table across all the schemas in the current database. Instead of this if you want to check the existence of the Table in a specified Schema and the Specified Database then we can write the above query as below:

Approach 2: Using OBJECT_ID() function

We can use OBJECT_ID() function like below to check if a Customers Table exists in the  current database.

IF OBJECT_ID(N'dbo.Customers', N'U') IS NOT NULLBEGIN  PRINT 'Table Exists'

Page 21: The Main Statement Used to Retrieve Data in T

END

IF OBJECT_ID(N'SqlHintsDemoDB.dbo.Customers', N'U') IS NOT NULLBEGIN  PRINT 'Table Exists'END

Altering a TableAfter you have created a table, you can use the ALTER TABLE command to change the table'sstructure and add or remove certain table properties, such as table constraints. You can useALTER TABLE to:■■ Add or remove a column, including a computed column. (New columns are placed atthe end of the table's column order.)■■ Change the data type of a column.■■ Change a column's nullability (that is, from NULL to NOT NULL, or vice versa).■■ Add or remove a constraint, including the following:■■ Primary key constraint■■ Unique constraint■■ Foreign key constraint■■ Check constraint■■ Default constraint

If you want to change the definition of a constraint or the definition of a computed column, drop the constraint or column with the old definition and add the constraint or computed column back in with the new definition.

You cannot use ALTER TABLE to:■■ Change a column name.■■ Add an identity property.■■ Remove an identity property.

SET IDENTITY_INSERT : -SyntaxSET IDENTITY_INSERT [ database. [ owner. ] ] { table } { ON | OFF }

adding new columns to the existing table :-

ex :-

ALTER TABLE <TABLE NAME >ADD <COLUMN NAME> <DATA TYPE> NOT NULL <IDENTITY> <DEFAULT(' ')>

Adding a Primary Key Constraint to the exisitng table :-

ALTER TABLE Production.CategoriesADD CONSTRAINT PK_Categories PRIMARY KEY(categoryid);GO

Page 22: The Main Statement Used to Retrieve Data in T

Unique Constraints :-ALTER TABLE Production.CategoriesADD CONSTRAINT UC_Categories UNIQUE (categoryname);GO

The unique constraint does not require the column to be NOT NULL. You can allow NULL ina column and still have a unique constraint, but only one row can be NULL.

Foreign Key Constraints :-ALTER TABLE Production.Products WITH CHECKADD CONSTRAINT FK_Products_Categories FOREIGN KEY(categoryid)REFERENCES Production.Categories (categoryid)GO

Keep the following rules in mind when creating foreign keys:■■ The column or set of columns from each table must have exactly the same data typesand collation (if they have a string data type).■■ As mentioned earlier, the columns of the referenced table must have a unique indexcreated on them, either implicitly with a primary key or a unique constraint, or explicitlyby creating the index.■■ You can also create foreign key constraints on computed columns.

Check Constraints :-

ALTER TABLE dbo.Vendors ADD CONSTRAINT CK_Vendor_CreditRating CHECK (CreditRating >= 1 AND CreditRating <= 5)

Default Constraints :-

create table xyz_dft( xyz int null constraint dft_vl default(1), pqr int )

alter table xyz_dftdrop constraint dft_vl

alter table xyz_dftadd constraint dft_vl default 2 for xyz