tags:

views:

87

answers:

6

I'm convinced this will make me slap myself when I see the answer but here goes...

Say I need a list of all products from a certain vendor but they need to order by a specific variable productType at the top and below it doesn't really matter but all products have to be in the list.

So basically

SELECT * FROM Products p WHERE p.VendorID = 1 AND p.ProductType = 'widget'

as the first rows to display. Then,

SELECT * FROM Products p WHERE p.VendorID = 1 AND p.ProductType <> 'widget' 

underneath that.

I'm using LINQ if that helps any but I can't even get this in regular SQL queries

+2  A: 

Create an extra field in the select part that indicates if they should be on top. For instance.

SELECT *, (p.ProductType = 'widget') AS thisfirst  FROM Products p WHERE p.VendorID = 1 ORDER BY thisfirst
Thirler
That won't work in SQL Server and many dbs. You must use a Case function (or if Access (bleh), an IIF function).
Thomas
On SqlServer I get - Incorrect syntax near '='.
David B
For mysql this seems correct to me (haven't ran it though). http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equalOf course with an if or case you can do the same.
Thirler
+1  A: 

Just order by a case statement like so:

select * from products
order by case producttype when 'widget' then 1 end nulls last;
ar
+3  A: 

One option is:

SELECT *, 
        CASE p.ProductType WHEN 'widget' THEN 0 ELSE 1 END AS ProductPriority 
    FROM Products p 
    WHERE p.VendorID = 1 
    ORDER BY ProductPriority
Brian
This worked well too but I only get to pick one answer. Thanks.
HighHat
No problem. I think you picked the right answer (I voted the other answer up).
Brian
+1  A: 

I guess you're using LINQ to SQL, so I think it would be better to do this using a LINQ query:

db.Products
  .Where(p => p.VendorID == 1)
  .OrderBy(p => p.ProductType == 'widget')
Mark Byers
+4  A: 

In Sql:

SELECT *
FROM Products p
WHERE p.VendorID = 1
ORDER BY CASE WHEN p.ProductType = 'widget' THEN 1 ElSE 2 END

And in Linq:

IQueryable<Product> query =
  from p in dc.Products
  where p.VendorID == 1
  orderby p.ProductType == "widget" ? 1 : 2
  select p;
David B
Linq uses double-quotes
StriplingWarrior
Thanks, wrote it in query analyzer so it looked ok. :) Editted.
David B
Nice - thanks for the Linq too!
HighHat
+1  A: 

An alternate approach to Brian's would be a union query:

Select ...
From    (
        Select ..., 0 As SortOrder
        from Products
        Where VendorId = 1
            And ProductType = 'Widget'
        Union All 
        Select ..., 1
        from Products
        Where VendorId = 1
            And ProductType <> 'Widget'
        ) As Z
Order By Z.SortOrder
Thomas
I concur - using UNION is easy and allows the use of possible ORDER BY clauses in conjunction.
Norla
This incurs two accesses to the Products table when only one is required. If the table is large, this will not perform well.
ar
This query will exclude rows where ProductType is null.
David B
@David B: Granted. Although the OP does not provide schema so we have no means of A: knowing if it is nullable or B: if the query should return nulls.
Thomas