Problém:
Chcete provést dělení v dotazu SQL, ale jmenovatelem je výraz, který může být nula. Databáze vám zobrazí chybu, když je jmenovatel ve skutečnosti nula.
Příklad:
Naše databáze obsahuje tabulku s názvem investor_data
s údaji v následujících sloupcích:id
, investor_year
, price_per_share
, income
a expenses
.
id | investor_year | price_per_share | příjem | náklady |
---|---|---|---|---|
1 | 2016 | 20 | 3200 | 2300 |
2 | 2017 | 130 | 2000 | 2000 |
3 | 2018 | 40 | 200 | 100 |
4 | 2019 | 15 | 5900 | 4900 |
Vydělme cenu za akcii rozdílem mezi příjmy a výdaji, abychom určili poměr P/E (poměr ceny a zisku) pro každý rok. Všimněte si, že jsou případy, kdy se příjmy rovnají výdajům, takže jejich rozdíl bude nulový. Musíme tedy najít způsob, jak se vyhnout dělení nulou.
Řešení:
SELECT investor_year, price_per_share/NULLIF(income-expenses, 0) AS P_E_ratio FROM investor data;
Tento dotaz vrací poměr P/E pro každý rok, jak je popsáno v prohlášení o problému:
investor_year | P_E_ratio |
---|---|
2016 | 0,0222 |
2017 | NULL |
2018 | 0,4000 |
2019 | 0,0150 |
Pokud je rozdíl mezi příjmy a výdaji nulový (jako v případě roku 2017), NULLIF
funkce změní nulu na hodnotu NULL. Proto dělení nulou dává ve výsledku hodnotu NULL.
Diskuse:
Pokud chcete dělení nulou zvládnout elegantně, můžete použít NULLIF
funkce. NULLIF
má dva argumenty:vyjádření zájmu a hodnotu, kterou chcete přepsat. Pokud je první argument roven druhému, pak NULLIF
vrátí NULL; jinak vrátí první argument.
Tuto funkci můžete použít ke zpracování potenciálního dělení nulou zabalením jmenovatele do volání NULLIF
. Pokud je v našem příkladu rozdíl mezi příjmy a výdaji nula, tato hodnota se změní na NULL a jmenovatel v dělení bude NULL, nikoli nula.
Řešení 2:Použijte WHERE
Samozřejmě, v některých situacích můžete použít jednodušší řešení:Vyhněte se dělení nulou pomocí WHERE
s operátorem porovnání <>. V našem příkladu bychom mohli zkontrolovat, zda se příjmy-výdaje liší od 0. Pokud ano, výpočet se vrátí.
SELECT investor_year, price_per_share/(income-expenses) AS P_E_ratio FROM investor data WHERE (income-expenses) <> 0 ;
Všimněte si, že pomocí WHERE
řešení, získáte méně řádků, než je v investor_date
stůl. Řádky, kde jsou příjmy a výdaje stejné, se v konečném výsledku nezobrazí.