Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySQL: Järjestys tarjoushinnan mukaan, jos on

slowhand [27.06.2016 01:34:25]

#

Osaisiko joku fiksumpi kertoa mikähän mahtaisi olla paras ja ennen kaikkea käytössä nopein koodi seuraavaan ongelmaan? Itselläni ei ole kovin hyviä ratkaisuja syntynyt.

Eli yksinkertaistettuna, taulussa on tuotteen nimi, normaalihinta ja tarjoushinta, esim:

nimike       norm.   tarjous
tuote1       40.00    0.00
tuote2       40.00   30.00
tuote3       60.00    0.00
tuote4       30.00   20.00
tuote5       20.00   10.00
tuote6       10.00    5.00

Tuotteen kohdalla vertailussa valitaan tarjoushinta jos se ei ole tyhjä, muuten normaalihinta. (tarjoushinta ei voi olla suurempi kuin norm.hinta) Kutsun tätä valinnan tulosta tosihinnaksi. Merkitsen ne tähän, mutta varsinaisessa taulussa ne siis eivät ole.

nimike       norm.   tarjous  tosihinta
tuote1       40.00    0.00     40.00
tuote2       40.00   30.00     30.00
tuote3       15.00    0.00     15.00
tuote4       30.00   20.00     20.00
tuote5       20.00   10.00     10.00
tuote6       10.00    5.00      5.00

Tuotteista tehdään hakua tosihinnan suuruuden mukaan, esimerkiksi tuotteet joiden tosihinta on 20 euroa tai yli.

Tähän asti olen saanut toimivan mySQL-kyselyn tehtyä. Mutta kun tuotteet sitten pitäisi järjestää tosihinnan mukaan, tulee ongelma. Tosihinta ei ole siis taulussa oikeasti käytössä oleva arvo, en tiedä pitäisikö kyselyssä jotenkin luoda se ja järjestää sen mukaan? Tavalliset Order by ja sarakenimi ei käy tässä.

Hycke [27.06.2016 02:07:29]

#

tämä toimii ainaki MS SQL:ssä, pitäisi toimia sellaisenaan myös mySQL:ssä

select *
from (	select
			nimike,
			norm,
			tarjous,
			case when tarjous = 0 then norm when tarjous < norm then tarjous else norm end as tosihinta
		from
			taulu
	) as tosihinnat
where
	tosihinta >= 20
order by
	tosihinta desc

Grez [27.06.2016 07:07:05]

#

slowhand kirjoitti:

Tuotteen kohdalla vertailussa valitaan tarjoushinta jos se ei ole tyhjä

Esimerkeissä ei näy yhtään tyhjää (null) hintaa. Sen sijaan montaa tuotetta näyttäisi saavan tarjouksessa ilmaiseksi (hinnalla 0).

Periaatteessa jos taulu olisi kuvauksen mukainen, niin Min(Coalesce(tarjous,norm),norm) toimisi myös tuon Hycken mainitseman case -rakenteen lisäksi.

Jos näitä tarvitaan monessa paikassa, niin itse tekisin ehkä näkymän:

CREATE VIEW Tosihinnat AS
SELECT nimike, Min(Coalesce(tarjous,norm),norm) tosihinta from taulu

Sitten vaan

SELECT *
FROM Tosihinnat
WHERE tosihinta >= 20
ORDER BY tosihinta desc

Metabolix [27.06.2016 17:04:22]

#

Tähän sopii helposti IF-funktio:

SELECT * FROM tuotteet WHERE IF(tarjous, tarjous, norm) >= 20

Jos vielä tehdään oikein eli laitetaan tarjoushinnaksi NULL silloin, kun tarjousta ei ole, sopii selvemmin IFNULL-funktio:

SELECT * FROM tuotteet WHERE IFNULL(tarjous, norm) >= 20

NULL kannattaa sekä semanttisista syistä (tulee selvä ero, onko tarjousta vai ei) että käytännön syistä (voi tehdä 0-hintaisen tarjouksen).

Samaa lauseketta voi käyttää ORDER BY -osassa, tai jos hinta haetaan kyselyssä, voi käyttää sille annettua nimeä:

SELECT IFNULL(tarjous, norm) AS tosihinta FROM tuotteet ORDER BY tosihinta

Grez [27.06.2016 17:11:15]

#

Itse suosin COALESCEa IFNULL asemesta koska se on standardi (toimii lähes jos ei kaikissa SQL-pohjaisissa) ja siihen voi laittaa useampiakin kuin 2 kenttää.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta