Think in Sets: Writing High-Performance SQL the Declarative Way
Think in Sets: Writing High-Performance SQL the Declarative Way “SQL is not about loops—it's about logic. The sooner you let go of procedural thinking, the faster your queries fly.” If you’ve come from a programming background, chances are your instinct is to iterate. But SQL wasn’t designed for that. SQL speaks the language of sets, and when you think in sets, your queries become: Faster More readable Easier to maintain In this article, we’ll compare procedural vs set-based logic with clear examples and best practices. The Problem: Updating Order Statuses Scenario: Mark all Pending orders as Shipped. ❌ Procedural Style with Cursors (SQL Server) DECLARE order_cursor CURSOR FOR SELECT id FROM Orders WHERE status = 'Pending'; DECLARE @id INT; OPEN order_cursor; FETCH NEXT FROM order_cursor INTO @id; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE Orders SET status = 'Shipped' WHERE id = @id; FETCH NEXT FROM order_cursor INTO @id; END CLOSE order_cursor; DEALLOCATE order_cursor;

Think in Sets: Writing High-Performance SQL the Declarative Way
“SQL is not about loops—it's about logic. The sooner you let go of procedural thinking, the faster your queries fly.”
If you’ve come from a programming background, chances are your instinct is to iterate. But SQL wasn’t designed for that. SQL speaks the language of sets, and when you think in sets, your queries become:
- Faster
- More readable
- Easier to maintain
In this article, we’ll compare procedural vs set-based logic with clear examples and best practices.
The Problem: Updating Order Statuses
Scenario: Mark all Pending
orders as Shipped
.
❌ Procedural Style with Cursors (SQL Server)
DECLARE order_cursor CURSOR FOR
SELECT id FROM Orders WHERE status = 'Pending';
DECLARE @id INT;
OPEN order_cursor;
FETCH NEXT FROM order_cursor INTO @id;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Orders SET status = 'Shipped' WHERE id = @id;
FETCH NEXT FROM order_cursor INTO @id;
END
CLOSE order_cursor;
DEALLOCATE order_cursor;