Часто разработчики не обращают внимания на некоторые мелкие, но полезные опции команд. Рассмотрим, например, группировку данных в запросе, в котором есть фильтр для данных. Вот наш запрос:
SELECT OrderDate,
SUM(TotalDue) TotalDueByOrderDate
FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN '7/1/2001' AND '7/31/2001'
GROUP BY OrderDate

Выполнив его (не забыв указать что мы работает с базой данных AdventureWorks) получим в результате всего 31 строку, даты которых соответствуют нашему условию.
Но если нам надо получить в этом запросе и остальные даты? Можно, конечно сделать второй запрос с соответствующим условием и объединить его с первым через UNION. Но есть путь проще. это опции ALL у группировки.
Теперь наш запрос изменим добавив всего одно слово:
SELECT OrderDate,
SUM(TotalDue) TotalDueByOrderDate
FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN '7/1/2001' AND '7/31/2001'
GROUP BY ALL OrderDate

Получим результат, который нам и требовался.

Далее речь пойдет о фильтре по шаблону (LIKE).
Когда используется шаблон мы с помощью спецсимволов задаём нужный нам вариант поиска. А что делать, когда сам спецсимвол должен входить в этот шаблон? Например, если знак процента (%) является часть строки?
Создадим такую строку в таблице Production.ProductDescription базы данных AdventureWorks.
UPDATE Production.ProductDescription
SET Description = 'Chromoly steel. High % of defects'
WHERE ProductDescriptionID = 3

Что бы теперь найти строку с процентом воспользуемся опцией ESCAPE:
SELECT ProductDescriptionID,Description
FROM Production.ProductDescription
WHERE Description LIKE '%/%%' ESCAPE '/'

Чтобы выполнить поиск знака процента в качестве обычного символа, необходимо указать опцию ESCAPE и экранирующий символ. В нашем случае это "/".
Если в шаблоне LIKE после экранирующего символа нет никакого символа, то шаблон является недопустимым и оператор LIKE возвращает значение FALSE. Если символ после экранирующего символа не является символом-шаблоном, то экранирующий символ игнорируется, а этот символ рассматривается как обычный символ в шаблоне. Это относится к таким символам-шаблонам, как подчеркивание (_), процент (%) и левая квадратная скобка ([), в том случае, если они заключены в квадратные скобки. Также в квадратных скобках ([ ]) и при использовании экранирующих символов можно использовать такие символы, как знак вставки (^), дефис (-) и правая квадратная скобка (]).
А теперь обратимся к опции DISTINCT. Все знают как выбрать строки без повторения.
SELECT DISTINCT ProductID
FROM Production.ProductInventory

Но эту же опцию можно применять и в функциях агрегирования, например:
SELECT AVG(DISTINCT ListPrice)
FROM Production.Product;

Этот пример вернёт нам среднюю стоимость не всей продукции, а среднюю справочную цену.
Теперь рассмотрим одну из функций ранжирования (ranking functions) ROW_NUMBER.
Синтаксис этих функций ранжирования имеет вид
< function_name > () OVER([PARTITION BY ]
ORDER BY < order_by_list >) 

Что же позволяет нам получить функция ROW_NUMBER? Она в запросах возвращает порядковые номера полученных строк в соответствии с некоторым правилом. Например, возьмём базу данных AdventureWorks, поставляюмую с SQL Server в качестве примера. Выполним следующий код
SELECT ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum,
FirstName + ' ' + LastName
FROM HumanResources.vEmployee
WHERE JobTitle = 'Production Technician - WC60'
ORDER BY LastName

Мы получим следующий результат (картинка будет позже)
В скрипте мы видим, что первым возвращаемым полем запроса идёт функция ROW_NUMBER, у которой задан порядок сортировки по столбцу LastName. Обращаю ваше внимание на то, что эта функция применяется только в выборках и при заданной опции сортировки.
(*Попробуйте выполнить этот же скрипт поменяв поля сортировки у функции и у самого запроса)

А что даёт нам опция PARTITION? Для получения ответа запустим на выполнение скрипт
SELECT ROW_NUMBER()
OVER(PARTITION BY SUBSTRING(LastName,1,1)
ORDER BY LastName) AS RowNum, FirstName + ' ' + LastName
FROM HumanResources.vEmployee
WHERE JobTitle = 'Production Technician - WC60'
ORDER BY LastName

Мы получим результат (и тут будет картинка).
Т.е. возвращаемые строки были разбиты на секции в соответствии с первой буквой фамилии и номера были выданы уже для каждой секции.
Ну а в качестве самостоятельной проработки поэкспериментируйте с другими функциями ранжирования: RANK, DENSE_RANK, NTILE.

Дальше я хочу рассмотреть интересные моменты в работе с такими мелочами как точка и запятая. А также будет уделено внимание некоторым опциям команды BULK INSERT.
Символ точка (.) играет большую роль, когда вы пишете запросы. Обычно мы точку используем, когда указываем колонки в запросах, как на следующем примере.
select t1.col1,t1.col2,t2.col3,t2.col4 from table1 as t1 
inner join table1 as t2 on t1.col1=t2.col1

Но иногда использование точки может удивить вас. Выполните следующий код.
create table #test(i int) insert into #test(i) select 10 select * from #test

Вы видите, что в результате получилось 10. Но что будет, если мы выполним следующие запросы
select * from .#test select * from ..#test select * from ...#test

Все они вернут 10. Если вы ожидали увидеть ошибку, то ваши ожидания не оправдались. Т.к. когда мы указали одну точку, то это означало, что перед именем таблицы указан владелец по умолчанию (в SQL Server 2000) или схема по умолчанию (в SQL Server 2005 и старше). Две точки означают, что ещё используется база данных по умолчанию. Ну, а три точки означают, что указан сервер БД по умолчанию. Ошибку вы получите уже только тогда, когда укажите более трёх точек.

А теперь рассмотрим следующий пример.
select * from #test[.] select * from #test[..] select * from #test[...] 
select * from #test[....] select * from #test[.....]

Все запросы вернут значение 10. Это произошло потому что точки между квадратными скобками являются псевдонимом (alias) для таблицы #test.

Рассмотрим другой пример.
select 10.35

Результатом запроса будет 10.35 (десять целых тридцать пять сотых). А что случится если запрос написать вот так
select 10.test

Вы видимо ожидаете что будет синтаксическая ошибка? Неверно, вы получите ответ 10 и название результирующего столбца будет test
test ----- 10

Т.е. парсер (разборщик запроса) понял что у нас указано не число и текст воспринял как псевдоним столбца. А вот такой код вызовет у вас синтаксическую ошибку.
select 10 .test 
Msg 258, Level 15, State 1, Line 1 Cannot call methods on int

Надеюсь вы поняли в чём причина ошибки?

Давайте теперь рассмотрим работу с запятой при использовании оператора BULK INSERT. Вы можете использовать команду BULK INSERT для вставки данных из текстового файла в таблицу. Однако, если в качестве разделителя используется запятая и в самих данных есть запятая, то вы получите проблему. Чтобы избежать её вы можете использовать функцию OPENROWSET.
Пусть у нас есть данные
"Davolio Nancy",644 "Fuller Andrew",2354 "Leverling Janet",4834 
"Peacock Margaret",1056 "Buchanan Steven",6893 "Suyama Michael",8195 
"King Robert",75920 "Callahan Laura",7003 "Dodsworth ,t" ,386

Создадим таблицу.
create table test (names varchar(100),no int)

Теперь вставим данные с помощью команды BULK INSERT
BULK INSERT test FROM 'F:\testing.txt' WITH ( FIELDTERMINATOR =','
ROWTERMINATOR = '\n' )

Получаем ошибку
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 9, column 2 (no).

Она возникла из-за того, что в строка "Dodsworth ,t" разбилась на два столбца. Если же использовать функцию OPENROWSET, то данные импортируются корректно.
insert into test(names, no
SELECT * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','text;HDR=NO;FMT=FixedLength;Database=F:\', testing#txt)

Раз мы заговорили о BULK INSERT, то давайте отметим ещё несколько моментов. Пусть у нас есть таблица с ограничением на колонке
create table test (id int
amount int check(amount >=1000 and amount<=5000));

И есть текстовый файл
1 700 2 2000 3 870 4 4500

Если выполнить следующую команду, то ограничение не сработает
bulk insert test from 'f:\test.txt' 
with (fieldterminator=',', rowterminator='\n')

Для того, что ограничение работало верно необходимо его включить с помощью соответствующей опции.
bulk insert test from 'f:\test.txt' with (fieldterminator=','
rowterminator='\n', check_constraints) select * from test

Кроме того, в операциях массовой вставки можно указать сколько строк из файла мы хотим скопировать
bulk insert test from 'f:\test.txt' with (fieldterminator=','
rowterminator='\n', FIRSTROW =1, LASTROW=3)

А что делать, если при вставке обнаружились не корректные данные? Как их увидеть? В этом нам поможет файл отчета об ошибках.
bulk insert test from 'f:\test.txt' with (fieldterminator=','
rowterminator='\', FIRSTROW =1, LASTROW=3, ERRORFILE ='F:\error.txt', 
check_constraints)  

Как видите, в опциях команд кроется много интересного и полезного.