Category Archives: Blog

Articles related to this Blog

#0335 – SQL Server – Using the WITH TIES option in the TOP clause of SELECT queries


When working with the AdventureWorks database, assume that we have the following requirement:

Please provide the list of customers with TOP 100 orders from Australia with the highest order totals.

The following query is the first one that comes to mind:

USE AdventureWorks2012;
GO
SELECT TOP 100 soh.CustomerID, 
               soh.TotalDue, 
               soh.TerritoryID
FROM Sales.SalesOrderHeader AS soh
INNER JOIN Sales.SalesTerritory AS sst ON soh.TerritoryID = sst.TerritoryID
WHERE sst.CountryRegionCode = 'AU'
ORDER BY soh.TotalDue DESC;
GO

image

This query would work in most cases, but analyzing the requirement, we realize that we don’t want the TOP 100 orders, we want all customers with the TOP 100 orders. These two requirements are different, and here’s why:

  • TOP 100 orders by total value = this means that we should have only 100 orders being returned, in the order defined by the ORDER BY clause
  • Customers with TOP 100 orders by total value = this means that we need to first fetch the TOP 100 order totals and then look for all customers which have orders with these totals. In this case, the number of orders being returned may be more than 100

In this case, we need to use the WITH TIES clause when defining the TOP statement. Here’s the query:

USE AdventureWorks2012;
GO
SELECT TOP 100 WITH TIES 
        soh.CustomerID, 
        soh.TotalDue, 
        soh.TerritoryID
FROM Sales.SalesOrderHeader AS soh
INNER JOIN Sales.SalesTerritory AS sst ON soh.TerritoryID = sst.TerritoryID
WHERE sst.CountryRegionCode = 'AU'
ORDER BY soh.TotalDue DESC;
GO

image

NOTES:

  • The TOP…WITH TIES can only be used in a SELECT statement
  • It cannot be used without an accompanying ORDER BY clause (a normal TOP can)
  • The TOP…WITH TIES also works with the TOP (n) PERCENT option

Until we meet next time,

Be courteous. Drive responsibly.

#0334 – SQL Server – SSMS – Troubleshooting Intellisense issues


Intellisense is one of the most frequently used features of SQL Server in the development community – so much so that if Intellisense stops working, work comes to a grinding halt and frantic calls to the IT team are made.


This post documents the steps, in order of most common occurrence (in my experience) that can be taken when faced with an issue that relates to Intellisense.


Assumption: The user is attempting to type in code in the code block, i.e. not in the comments block or string literals.



  1. Confirm that Intellisense is enabled (it may have been accidentally turned off due to “happy clicking”)

  2. Refresh the local cache

    • Often, when workstations (especially laptops) are hibernated and awaken again, newer objects are created or when connections in the Query editor are changed, Intellisense may stop working or take a while to refresh
    • To manually refresh the cache, press (Ctrl + Shift + R) or go to Edit –> Intellisense –> Refresh Local Cache

  3. Is the SSMS connecting to a SQL Server running a lower version? (e.g. SSMS for SQL 2012 connecting to SQL 2008 R2/2005 or lower) If yes, SSMS would not work
  4. Review the code – does an error exist such that the queries in the particular query editor cannot be parsed?
  5. After Visual Studio 2010 SP1 is installed on a workstation with SQL Server 2008 R2 (any release from RTM to CU6), the Intelli-sense feature in the SQL server Management Studio (SSMS) may stop working

    • This is a  known, documented issue with Microsoft (KB2531482)and the fix is quite simple – deploy the latest service pack/cumulative update of SQL Server 2008 R2

While Intellisense kicks back to life in most cases after the above steps are performed, it is still possible that it may cease to work in rare cases. The last step in this case is to reinstall the SQL Server client tools.


Further Reading:


Here are some other posts about Intelli-sense that you may be interested in:



Until we meet next time,



Be courteous. Drive responsibly.

#0333 – Opening Office documents from Sharepoint online – The file is corrupt and cannot be opened


Today, I do not have a SQL Server blog. Today’s post is about a solution to a problem that I faced recently when working with documents stored on Sharepoint Online.


I had received a new laptop from the IT team and when attempting to edit an Excel file in Excel 2010 directly from Sharepoint, I encountered the following error:



The file is corrupt and cannot be opened.


Root Cause


When a document is opened from the Internet, Office spawns off another program under restricted permissions to open the document. This restricted process will be unable to create temporary files and folders required for Office to open and edit the document.


Solutions


The following solutions can be implemented to resolve the issue:


Solution 01:


If a particular Sharepoint URL is frequently used and trusted, a good alternative would be to Add the URL to the list of Trusted sites in under the browser Options.


Office will trust documents originating from trusted locations and hence these documents will open successfully.


Solution 02:


Follow the steps provided in the Microsoft KB article: http://support.microsoft.com/kb/2387587


Solution 03 (NOT recommended):


Disable Protected Mode (NOT recommended)



  1. Go to File -> Options -> Trust Center
  2. Open the Trust Center window by clicking on the “Trust Center Settings” button
  3. Navigate to the “Protected View” window
  4. Uncheck the following checkboxes:

    • Enable Protected View for files originating from the Internet
    • Enable Protected View for files located in potentially unsafe locations
    • Enable Protected View for Outlook attachments
    • Enable Data Execution Prevention mode

While most blogs and forums suggest that protected mode options should be unchecked, I would not recommend this as it reduces the security enforced by Office.


image



Have you ever encountered this issue? If yes, how did you resolve the error?


Until we meet next time,



Be courteous. Drive responsibly.

#0332 – SQL Server – Myths – Is DISTINCT faster than GROUP BY?


I have often seen a recommendation that using DISTINCT instead of GROUP BY is better from a performance perspective. DISTINCT is definitely a more readable alternative, but I wanted to test for myself as to what the truth was.


To compare the performance of the two, I wrote the following simple queries.


The query below helps in identifying the number of records that SQL Server will need to process. On my machine, when executed without the GROUP BY or the DISTINCT clause, the query generates records in excess of 380,000.

USE AdventureWorks2012;
GO
SELECT COUNT(so1.object_id)
FROM sys.objects AS so1
CROSS JOIN sys.objects AS so2 ;
GO

The queries below fetch the same information – one uses the GROUP BY whereas the other query uses a DISTINCT.

USE AdventureWorks2012;
GO
–Clean the buffers and procedure cache
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO

–Evaluate GROUP BY
SELECT so1.object_id,
so1.name
FROM sys.objects AS so1
CROSS JOIN sys.objects AS so2
GROUP BY so1.object_id, so1.name ;
GO

–Clean the buffers and procedure cache
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO

–Evaluate DISTINCT
SELECT DISTINCT
so1.object_id,
so1.name
FROM sys.objects AS so1
CROSS JOIN sys.objects AS so2 ;
GO


Before executing the two queries (one with the GROUP BY and the other with the DISTINCT), I had turned on the actual execution plan.


image


Upon studying the execution plan, the following observations can be made:



  1. When the SQL server database engine detected that the 2nd query did not have any aggregation function, it was smart enough to convert the GROUP BY into a DISTINCT when the query plan is generated
  2. There is no difference in the execution plan across both the queries

In conclusion,



DISTINCT is not faster than GROUP BY. In fact, Both DISTINCT and GROUP BY demonstrate equal performance impact.


When aggregations are not being used, DISTINCT is more readable when compared to GROUP BY.


Until we meet next time,



Be courteous. Drive responsibly.

#0331-SQL Server-What is evaluated first-TOP or ORDER BY?


One of our systems needs to support paging and needs to work on multiple SQL Server versions (SQL 2005 and above). Our solution therefore uses the TOP clause and not the OFFSET…FETCH solution introduced in SQL 2012.

Being a reasonably old system, we also get a lot of enhancement requests. One of the requirements that we received was to change the order in which the elements were returned to the application by the query. As one of the team members was working on the enhancement, he raised an interesting question:

We need to use both the TOP and the ORDER BY clause. Which will be evaluated first?

Here’s the reason why the question is interesting. We know that the ORDER BY is evaluated after the SELECT (after all, how can you order a result set if you haven’t fetched anything into the result set in the first place?). The way a T-SQL query is written the TOP clause is part of the SELECT clause. So, we have two options with respect to the evaluation sequence:

  1. Fetch the number/percentage of records based on the value specified in the TOP clause and then order this intermediate result set
  2. Fetch all records, order them and then fetch the number/percentage of records based on the value specified in the TOP clause

In each of these options, the results returned by the query will be different. In order to answer this question, I came up with the following quick test:

TOP and ORDER BY

To begin our test, let me create a test table, and insert some records into it. Note that:

  1. The Table does not have a clustered index
  2. The records being inserted into the test table are out-of-order
USE tempdb;
GO
--Safety Check
IF OBJECT_ID ('tempdb..#OrderingTest','U') IS NOT NULL
    DROP TABLE #OrderingTest;
GO

--Create a test table
CREATE TABLE #OrderingTest (OrderId INT NOT NULL,
                            OrderValue VARCHAR(20)
                           );
GO

--Insert some test data
--Note that records are being inserted out of order
INSERT INTO #OrderingTest (OrderId, OrderValue)
VALUES (10, 'Ten'),
       (5, 'Five'),
       (4, 'Four'),
       (12, 'Twelve'),
       (1, 'One'),
       (8, 'Eight'),
       (2, 'Two'),
       (3, 'Three'),
       (7, 'Seven'),
       (9, 'Nine');
GO

TOP without ORDER BY

First up, let us SELECT TOP 5 records from the table without the ORDER BY clause.

USE tempdb;
GO
--SELECT the TOP 5 records from the table
--without ORDER BY clause
SELECT TOP 5 ot.OrderId, 
             ot.OrderValue
FROM #OrderingTest AS ot;
GO

image

As can be seen from the result-set, without the ORDER BY clause, no ordering was performed. The records were returned in the physical order in which they were found by the database engine.

TOP with ORDER BY

Now, let us add an ORDER BY clause to the query. First up, we will perform the standard ascending (ASC) ordering.

USE tempdb;
GO
SELECT TOP 5 ot.OrderId, 
             ot.OrderValue
FROM #OrderingTest AS ot
ORDER BY ot.OrderId ASC;
GO

image

Next, let us change the order to descending by using the DESC keyword:

USE tempdb;
GO
SELECT TOP 5 ot.OrderId, 
             ot.OrderValue
FROM #OrderingTest AS ot
ORDER BY ot.OrderId DESC;
GO

image

As can be seen from the results, the TOP operation was performed after the ORDER BY, i.e. the results were ordered first, the TOP was performed later.

Adding a clustered index

Finally, let us add a clustered index on the table and then fetch the records without an ORDER BY clause.

USE tempdb;
GO
ALTER TABLE #OrderingTest
    ADD CONSTRAINT pk_OrderingTest 
    PRIMARY KEY CLUSTERED (OrderId ASC);
GO

--Repeat Scenario A
USE tempdb;
GO
SELECT TOP 5 ot.OrderId, ot.OrderValue
FROM #OrderingTest AS ot;
GO

image

image

As can be seen from the screenshot above, the results are in a sorted order. The sorting comes from the fact that the database engine used the clustered index to access the table. Because the clustered index arranges records in a logical order, they are accessed in when accessed via the clustered index they are accessed in a specific order.

However, SQL Server does not guarantee the order in which the results are returned, so if that’s the requirement, it is always a good idea to use the ORDER BY clause and sort the results explicitly.

Conclusion

The conclusion quite simply is that

The TOP clause is evaluated after the ORDER BY/sort operation.

If no explicit ordering is performed, SQL Server returns results in the order in which they are physically accessed by the database engine.

Until we meet next time,

Be courteous. Drive responsibly.