sql >> Databáze >  >> RDS >> Sqlserver

Podmíněné pořadí T-SQL podle

CASE je výraz, který vrací hodnotu. Není to pro kontrolu toku, jako IF . A nemůžete použít IF v rámci dotazu.

Bohužel existují určitá omezení s CASE výrazy, díky nimž je těžkopádné dělat to, co chcete. Například všechny větve v CASE výraz musí vracet stejný typ nebo být implicitně převoditelný na stejný typ. To bych s řetězci a datlemi nezkoušel. Nemůžete také použít CASE k určení směru řazení.

SELECT column_list_please
FROM dbo.Product -- dbo prefix please
ORDER BY 
  CASE WHEN @sortDir = 'asc' AND @sortOrder = 'name' THEN name END,
  CASE WHEN @sortDir = 'asc' AND @sortOrder = 'created_date' THEN created_date END,
  CASE WHEN @sortDir = 'desc' AND @sortOrder = 'name' THEN name END DESC,
  CASE WHEN @sortDir = 'desc' AND @sortOrder = 'created_date' THEN created_date END DESC;

Pravděpodobně jednodušším řešením (zejména pokud je to složitější) je použití dynamického SQL. Chcete-li zabránit vkládání SQL, můžete otestovat hodnoty:

IF @sortDir NOT IN ('asc', 'desc')
  OR @sortOrder NOT IN ('name', 'created_date')
BEGIN
  RAISERROR('Invalid params', 11, 1);
  RETURN;
END

DECLARE @sql NVARCHAR(MAX) = N'SELECT column_list_please
  FROM dbo.Product ORDER BY ' + @sortOrder + ' ' + @sortDir;

EXEC sp_executesql @sql;

Další plus pro dynamické SQL, navzdory všemu strachu, který se kolem toho šíří:můžete získat nejlepší plán pro každou variantu řazení namísto jediného plánu, který se bude optimalizovat pro jakoukoli variantu řazení, kterou jste náhodou použili jako první. V nedávném srovnání výkonu, které jsem provedl, si také vedl univerzálně nejlépe:

http://sqlperformance.com/conditional-order-by



  1. získat záznamy za poslední tři měsíce z tabulky

  2. Tři hlavní důvody, proč se lidé stěhují do SaaS

  3. Jak zřetězit řetězce řetězcového pole v dotazu PostgreSQL „seskupit podle“?

  4. Jak mohu použít CREATE OR REPLACE?