Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[SQL] Zoeken tussen data met apart Jaar en Maand veld

Pagina: 1
Acties:

  • bastv
  • Registratie: September 2005
  • Laatst online: 15-11 00:39
Ik wil in een tabel zoeken met 2 apparte velden (geen datetime types) 1 voor de maand en 1 voor het jaar.
voorbeeld:

jaarmaandwaarde
200711054
20072654
20084684


nu kan ik het maar niet voor mekaar krijgen om tussen 2 data te zoeken

ik wil dus alle waardes tussen 1-2007 en 3-2008 (in dit voorbeeld 2 waardes)
"where jaar >= 2007 and jaar <= 2008" werkt wel maar "where maand <= 3" gaat mis omdat ik wel alle maanden van 2007 wil hebben.

ik heb getest met convert datetime en datediff etc. maar ik kom er echt niet uit.

iemand tips?

Verwijderd

1-2007-> 1 + (12 * 2007) = 24085
3-2008 -> 3 + (12* 2008) = 24099

code:
1
2
3
4
SELECT  veld1,veld2 
    FROM tabel 
    WHERE (((jaar*12) + maand)>=24085) 
         AND (((jaar*12) + maand)<=24099)


zomaar ff een idee, vraag me alleen af of dit nog geindexeerd wordt afgehandeld.

[ Voor 17% gewijzigd door Verwijderd op 14-05-2008 13:24 ]


  • Cartman!
  • Registratie: April 2000
  • Niet online
De beste optie is denk ik om een veld te maken waar je de waarden combineert in een formaat waar SQL mee kan rekenen (DATETIME bijv.).

  • Redshark
  • Registratie: Mei 2002
  • Laatst online: 18-11 19:44
Je kunt ze gewoon achter elkaar plakken (wel een string van maken) en dan daarop je selectie uitvoeren?

krijg je waardes uit jouw voorbeeld van 200703 tm 200803.

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Eeh jaar = 2007 or (jaar= 2008 and month<=3)

  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
bastv schreef op woensdag 14 mei 2008 @ 13:13:
Ik wil in een tabel zoeken met 2 apparte velden (geen datetime types) 1 voor de maand en 1 voor het jaar.
voorbeeld:

jaarmaandwaarde
200711054
20072654
20084684


nu kan ik het maar niet voor mekaar krijgen om tussen 2 data te zoeken

ik wil dus alle waardes tussen 1-2007 en 3-2008 (in dit voorbeeld 2 waardes)
"where jaar >= 2007 and jaar <= 2008" werkt wel maar "where maand <= 3" gaat mis omdat ik wel alle maanden van 2007 wil hebben.

ik heb getest met convert datetime en datediff etc. maar ik kom er echt niet uit.

iemand tips?
code:
1
select * from tabel where (jaar * 100) + maand between 200701 and 200803

"He who thinks knows evertyhing, knows nothing" - Socrates


  • lier
  • Registratie: Januari 2004
  • Laatst online: 09:29

lier

MikroTik nerd

Waarom maak je in je tabel gebruik van een maand en een jaar kolom ?
Was het niet logischer geweest om een datum veld te gebruiken ?

Hoe vies de oplossingen ook zijn, je zal altijd naar een variabele moeten die of een numerieke waarde of een datum voor stelt.

Eerst het probleem, dan de oplossing


  • Reinier
  • Registratie: Februari 2000
  • Laatst online: 07:44

Reinier

\o/

Natuurlijk is dit onhandig, maar de oplossing van Vozze is aardig netjes. Ik zou het zo ook doen :)

  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
lier schreef op woensdag 14 mei 2008 @ 13:37:
Waarom maak je in je tabel gebruik van een maand en een jaar kolom ?
Was het niet logischer geweest om een datum veld te gebruiken ?

Hoe vies de oplossingen ook zijn, je zal altijd naar een variabele moeten die of een numerieke waarde of een datum voor stelt.
Als je je gegevens per maand beschikbaar hebt, is het onzinnig om een datum-veld op te nemen. Wat neem je dan? De eerste dag van de maand of de laatste dag van de maand...

Een jaarmaand-veld (bv. 200701) was wel handiger geweest.

"He who thinks knows evertyhing, knows nothing" - Socrates


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Deze thread mag echt op de daily wtf:

select * from tabel where jaar = 2007 or (jaar= 2008 and month<=3)

deze code is tenminste over een jaar ook nog te begrijpen, kan geoptimiseerd worden door de sql engine, is eenvoudig aanpasbaar, uitbreidbaar, etc... geen idiote combinaties van maand en jaar, daar komen later alleen maar vodden van.

  • lier
  • Registratie: Januari 2004
  • Laatst online: 09:29

lier

MikroTik nerd

Vozze schreef op woensdag 14 mei 2008 @ 13:41:
Als je je gegevens per maand beschikbaar hebt, is het onzinnig om een datum-veld op te nemen. Wat neem je dan? De eerste dag van de maand of de laatste dag van de maand...

Een jaarmaand-veld (bv. 200701) was wel handiger geweest.
Het gaat mij er dan ook meer om waarom voor deze oplossing gekozen is (en vandaar mijn vraag),

Eerst het probleem, dan de oplossing


Verwijderd

masterpoi schreef op woensdag 14 mei 2008 @ 13:45:
Deze thread mag echt op de daily wtf:

select * from tabel where jaar = 2007 or (jaar= 2008 and month<=3)

deze code is tenminste over een jaar ook nog te begrijpen, kan geoptimiseerd worden door de sql engine, is eenvoudig aanpasbaar, uitbreidbaar, etc... geen idiote combinaties van maand en jaar, daar komen later alleen maar vodden van.
je hebt wel gelijk, maar dan nu nu voor: 6-2007 t/m 7-2008,

[ Voor 16% gewijzigd door Verwijderd op 14-05-2008 13:52 ]


  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
masterpoi schreef op woensdag 14 mei 2008 @ 13:45:
Deze thread mag echt op de daily wtf:

select * from tabel where jaar = 2007 or (jaar= 2008 and month<=3)

deze code is tenminste over een jaar ook nog te begrijpen, kan geoptimiseerd worden door de sql engine, is eenvoudig aanpasbaar, uitbreidbaar, etc... geen idiote combinaties van maand en jaar, daar komen later alleen maar vodden van.
Nee, jouw oplossing is lekker. Schrijf hem nu ook even voor de periodes tussen 2005-3 en 2008-9. 8)7

"He who thinks knows evertyhing, knows nothing" - Socrates


  • bastv
  • Registratie: September 2005
  • Laatst online: 15-11 00:39
masterpoi schreef op woensdag 14 mei 2008 @ 13:45:
select * from tabel where jaar = 2007 or (jaar= 2008 and month<=3)
dat werkt dus niet
Vozze schreef op woensdag 14 mei 2008 @ 13:31:
[...]
code:
1
select * from tabel where (jaar * 100) + maand between 200701 and 200803
Werkt prima! thanx Vozze hier was ik zelf nooit op gekomen!

(en ja 1 tabel was makkelijker geweest of een datetime tabel. maar dat is niet mogelijk omdat deze data uit een sql database komt die ik niet zelf beheer en niet aan te passen is)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Tja, en dan wil je in de toekomst een query van maart 2007 tot juni 2009, en dan?te laat

De oplossing van Vozze is de meest elegante. Als indexering een probleem is kun je altijd een tweede clause gebruiken, dus WHERE (jaar between 2007 and 2008) AND (100*jaar+maand) between 200701 and 200803.

[ Voor 4% gewijzigd door MSalters op 14-05-2008 13:53 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
of meer algemeen

SELECT * FROM tabel WHERE
(jaar = @beginjaar AND month >= @beginmaand) OR
jaar BETWEEN @beginjaar+1 AND @eindjaar -1 OR (jaar = @eindjaar AND month <= @eindmaand)

De implimentatie van 'BETWEEN' is db engine afhankelijk dus nakijken of het inclusief of exclusief de grenzen is.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Nee, dat werkt niet voor het interval 2008/02 - 2008/04 want de eerste clause pakt ook 2008/05

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
dat werkt dus niet
Dan moet je je probleem beter uitleggen. Werkt prima!!

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
De oplossing van Vozze zorgt ervoor dat de dbengine geen rekening houdt met evt. indexering. Als je predicaten op afzonderlijke kolomen defineert heb je (theoretisch) de meeste performance om dat de indexen dan kunnen geraadpleegd worden.

(Tenzij je een samengestelde index hebt op month en jaar maar dat moet ik eens uittesten)

[ Voor 218% gewijzigd door masterpoi op 14-05-2008 14:03 ]


Verwijderd

masterpoi schreef op woensdag 14 mei 2008 @ 13:58:
De oplossing van Vozze zorgt ervoor dat de dbengine geen rekening houdt met evt. indexering. (Tenzij je een samengestelde index hebt op month en jaar maar dat moet ik eens uittesten)
lijkt mij ook.
beste oplossing zou zijn om een 3e veld te vullen via een db-trigger.

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Verwijderd schreef op woensdag 14 mei 2008 @ 14:04:
[...]

lijkt mij ook.
beste oplossing zou zijn om een 3e veld te vullen via een db-trigger.
Dat introduceert naar mijn mening te veel code-maitenance. (Vooral om dat het code in de DB is) Inderdaad wel het snelste.

  • Aetos
  • Registratie: November 2001
  • Laatst online: 14-10 18:36
WHERE ((jaar > beginjaar) OR (jaar = beginjaar AND maand >= beginmaand)) AND
((jaar < eindjaar) OR (jaar = eindjaar AND maand <= eindmaand))

en nu nog >= en <= bekijken of je inclusief of exclusief wilt hebben.

[ Voor 5% gewijzigd door Aetos op 14-05-2008 14:21 ]


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Heeft MySQL geen support voor computated columns? Want in dat geval zou je dat datum 'berekening' van Vozze als formule kunnen gebruiken er daarop een index leggen.

If it isn't broken, fix it until it is..


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Aetos schreef op woensdag 14 mei 2008 @ 14:20:
WHERE ((jaar > beginjaar) OR (jaar = beginjaar AND maand >= beginmaand)) AND
((jaar < eindjaar) OR (jaar = eindjaar AND maand <= eindmaand))

en nu nog >= en <= bekijken of je inclusief of exclusief wilt hebben.
En het verschil met mijn post is??

Verwijderd

masterpoi schreef op woensdag 14 mei 2008 @ 14:07:
[...]
Dat introduceert naar mijn mening te veel code-maitenance. (Vooral om dat het code in de DB is)
ja dat zijn afwegingen, ligt ook aan omstandigheden, of huidige db/structuur uberhaupt kan worden aangepast. Qua code valt de trigger op zich nogal mee lijkt me.
En voor maintenance daarop, is hier nog een leuk draadje: Versie beheer databases

  • Aetos
  • Registratie: November 2001
  • Laatst online: 14-10 18:36
masterpoi schreef op woensdag 14 mei 2008 @ 14:22:
[...]


En het verschil met mijn post is??
Practisch geen behalve dat ik geen DB afhankelijke en minder bekende SQL gebruik en de naamgeving van de kolom maand meer overeenkomt met het voorbeeld.

Hierdoor las ik jouw voorbeeld eerst verkeerd.

Och.. En bij nadere inspectie doet ie het echt niet goed. Kijk naar het voorbeeld van MSalters voor een periode van 2008/2 tot 2008/4 selecteert hij 2008/1 en 2008/5 ook.


2008/5 omdat hij matcht met de eerste clausule and 2008/1 matcht met de laatste clausule.

[ Voor 33% gewijzigd door Aetos op 14-05-2008 14:45 ]


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Aetos schreef op woensdag 14 mei 2008 @ 14:31:
[...]


Practisch geen behalve dat ik geen DB afhankelijke en minder bekende SQL gebruik
Eh?? gewoon ANSI SQL. (Toegegeven er zijn nuances (inclusief/exclusief). Maar die hoor je als je SQL schrijft eigenlijk te kennen) Between kan doorgaans beter geoptimiseerd worden door de sql engine omdat het beter de intentie weerspiegeld. Ik denk bevoorbeeld aan specifieke algoritmes om indexes te doorlopen die door de SQL engine steeds door analyse van de query worden bepaald. De juiste keywords helpen de SQL engine zijn job beter te doen.
en de naamgeving van de kolom maand meer overeenkomt met het voorbeeld.

Hierdoor las ik jouw voorbeeld eerst verkeerd.
Jah lezen is een kunst...
Och.. En bij nadere inspectie doet ie het echt niet goed. Kijk naar het voorbeeld van MSalters voor een periode van 2008/2 tot 2008/4 selecteert hij 2008/1 en 2008/5 ook.


2008/5 omdat hij matcht met de eerste clausule and 2008/1 matcht met de laatste clausule.
Klopt, 2008/6-12 trouwens ook. Maar weerom behoorlijk eenvoudig aan te passen niet?

Ik blijf wel bij mijn punt dat speciale formules verzinnen een slecht idee is omwille van het onderhoud van de code achteraf. (Wat was dit nu ook al weer? Vereist documentatie) Dit terwijl standaard technieken altijd te begrijpen zijn (iedereen die sql kent kan de clausules begrijpen) en bovendien dikwijls efficienter. (Uiteraard was een enkel kolom nog beter geweest maar die is er nu dus niet.)

[ Voor 12% gewijzigd door masterpoi op 14-05-2008 20:35 ]


  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
masterpoi schreef op woensdag 14 mei 2008 @ 20:28:
Ik blijf wel bij mijn punt dat speciale formules verzinnen een slecht idee is...
Ik ga akkoord met jouw stelling, maar... (anders had deze post geen meerwaarde ;^) de in deze thread voorgestelde formule, is een wel erg generieke oplossing om dit probleem met datums op te lossen en dus nog moeilijk een speciale formule te noemen. Iedereen die al eens met datumproblemen heeft gezeten zal ze herkennen en begrijpen.
offtopic:
een ander typisch gebruik vd formule: verjaardagen sorteren op basis van geboortedatum

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
moozzuzz schreef op donderdag 15 mei 2008 @ 14:42:
Iedereen die al eens met datumproblemen heeft gezeten zal ze herkennen en begrijpen.
Iedereen die zelf 'ff' met datums gaat rekenen zal het herkennen en dat zijn tevens de personen die vaker 'datumproblemen' hebben. Anderen kiezen toch eerder voor een bepaalde conventie zodat ze voortaan bestaande functies kunnen gebruiken. Rekenen met tijd is een van de meest onderschatte klusjes.
offtopic:
een ander typisch gebruik vd formule: verjaardagen sorteren op basis van geboortedatum
Slecht voorbeeld. Op een geboortedatum kan je gewoon sorteren, of je sorteert op basis van bestaande date functies als je enkel dag en maand wil gebruiken.

{signature}


  • stappel_
  • Registratie: Augustus 2000
  • Laatst online: 10-11 13:04
Makkelijk via MySQL:
code:
1
2
WHERE ("datum"start" >= STR_TO_DATE(CONCAT( `jaar` , '-', `maand` , '-', `dag` ),'%Y-%m-%d' )) 
AND (STR_TO_DATE(CONCAT( `jaar` , '-', `maand` , '-', `dag` ),'%Y-%m-%d' ) < "datumeind")

Ubero: #2, Euler: #1, GOT: #1, Des: #1, Zeta: #1, Eon: #3, OGR-24: #3, OGR-25: #7,
LM: #7, AP: #5, DF: #19, D2OL: #37, SOB: #50, TSC: #63, RC5: #96


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
stappel_ schreef op donderdag 15 mei 2008 @ 15:30:
Makkelijk via MySQL:
code:
1
2
WHERE ("datum"start" >= STR_TO_DATE(CONCAT( `jaar` , '-', `maand` , '-', `dag` ),'%Y-%m-%d' )) 
AND (STR_TO_DATE(CONCAT( `jaar` , '-', `maand` , '-', `dag` ),'%Y-%m-%d' ) < "datumeind")
omgomgomg! ;) Nu snap ik waarom er zoveel vraag is naar goede iters :P

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

masterpoi schreef op woensdag 14 mei 2008 @ 14:22:
[...]


En het verschil met mijn post is??
Dat de jouwe wel een fundamentele en ernstige bug heeft meneer de goede IT'er.

Professionele website nodig?


  • Aetos
  • Registratie: November 2001
  • Laatst online: 14-10 18:36
Heb je nu bezwaar tegen mijn speciale formule of naar alle halfbakken oplossingen die gaan rekenen met de velden van de database en daardoor een tablescan forceren? Of een computed column introduceren die verder niet nodig is. Een beetje goede db engine zou van mijn where nog gebruik kunnen maken van de indexen op jaar en mogelijk nog op maand. Alhoewel het gebruik van OR in een where clause bijna altijd inefficienter is dan een where clause die alleen uit and bestaat.

De implementatie die gebruikmaakt van between is fundamenteel fout. Misschien is het mogelijk om met gebruik van between een equivalente where clause te maken. Maar dan wil ik er wel een equivalentie bewijs bij zien.

Mijn formule is niet zo verschrikkelijk moeilijk toch? En algemeen toepasbaar.

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Die zoals ik al eerder zei (lezen is echt een kunst!) eenvoudig op te lossen is.

Verwijderd

masterpoi schreef op vrijdag 16 mei 2008 @ 11:06:

Die zoals ik al eerder zei (lezen is echt een kunst!) eenvoudig op te lossen is.
Je fout zit hem helemaal niet in die BETWEEN. Dus wat bedoel je nu eigenlijk?
[edit]
Ah, we gaan een aantal posts later met een of andere vaag excuus komen maar laten het origineel gewoon fout staan, want dat is handig voor anderen die misschien dit topic ooit nog eens tegenkomen.

[ Voor 28% gewijzigd door Verwijderd op 16-05-2008 11:18 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

masterpoi schreef op vrijdag 16 mei 2008 @ 11:06:
[...]


Die zoals ik al eerder zei (lezen is echt een kunst!) eenvoudig op te lossen is.
Uhm jij bent hier degene die met halfbakken niet functionerende 'superoplossingen' aan komt en doet alsof ze net zo goddelijk zijn als jezelf. Moet je niet vreemd opkijken als mensen je daarop aanspreken.Die oplossing die je daar gaf bevat een fundamentele fout en heb je nergens gecorrigeerd, je hebt 'm alleen verdedigd toen iemand die fout wel goed voorkwam.

Professionele website nodig?


  • Aetos
  • Registratie: November 2001
  • Laatst online: 14-10 18:36
Hm. Ok. Mogelijke makkelijke verbeteringen verzinnen.... vanuit de clausule

A or jaar between x and y or B.

hm. tijdlijntje gaan schrijven:

j = jaarovergang
x = begin of eind punt

X ------x----------j----------j------x

of Y ----x----j----x
of Z j-----x----x----j


de between zal alleen bij geval A iets kunnen doen.


ok ok..

A = (eindjaar - beginjaar = 1 and ((jaar = beginjaar and maand >= beginmaand) or (jaar = eindjaar and maand <= eindmaand))

B = (eindjaar = beginjaar and jaar = beginjaar and maand between beginmaand and eindmaand)

maar of dat nou een simpele oplossing is.... En of ik geen fouten gemaakt heb weet ik ook niet.

en in clause A staat al 3/4 van mijn initiele where clause.

EDIT:

oeps.. ik vergeet alles van het beginjaar en het eindjaar in geval X. oftewel.. simpel is het niet. en ik zou X en Y samen kunnen nemen omdat between dat kan. zucht. en dan komen we ongeveer op hetzelfde uit.

En zelfs die oplossing is niet bestand tegen foute keuzes van beginjaar en eindjaar.

Neem de periode 2008-5 tot 2007-4 maar eens. En bedenk wat er gebeurt.

Naja.. Dit is uiteindelijk allemaal het gevolg van een verkeerd data model dat niet veranderd mag worden. Of een leuke huiswerk opdracht.

[ Voor 26% gewijzigd door Aetos op 16-05-2008 11:45 ]


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Aetos schreef op vrijdag 16 mei 2008 @ 10:44:
Heb je nu bezwaar tegen mijn speciale formule of naar alle halfbakken oplossingen die gaan rekenen met de velden van de database en daardoor een tablescan forceren? Of een computed column introduceren die verder niet nodig is.
Dat lezen is een kunst sloeg ook op mij. Ik dacht eerst dat jouw oplossing een simpele herfrasering was zonder between.

Nu de requirement van moet ook werken binnen een jaar is voor mijn post niet eerder geponeerd. (Ik had hem misschien wel moeten veronderstellen.)

Jouw oplossing is dus zeker goed en maakt uiteraard gebruik van indexen. Veel beter dan die van Vozze, om over die van stappel_ nog maar te zwijgen.

Or keyword is uiteraard niet trager in grote tabellen, als de afzonderlijke clauses de index gebruiken, dan een enkele where clause waar een table scan voor nodig is.

Een (onelegante) oplossing met het between keyword zou kunnen zijn (maar ik wil er niet aan blijven vastklampen, jouw oplossing is uiteraard leesbaarder):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(
@beginjaar != @eindjaar 
AND 
(
(jaar = @beginjaar AND month >= @beginmaand)
 OR
jaar BETWEEN @beginjaar+1 AND @eindjaar -1
 OR 
(jaar = @eindjaar AND month <= @eindmaand) 
)
)
OR 
(
@beginjaar = @eindjaar 
AND month BETWEEN @beginmaand AND@eindmaand 
AND jaar=@beginjaar
)

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Ah, we gaan een aantal posts later met een of andere vaag excuus komen maar laten het origineel gewoon fout staan, want dat is handig voor anderen die misschien dit topic ooit nog eens tegenkomen.
Waar slaat dit nu op? Dat is toch niet mijn verantwoordelijkheid! Ik heb al meermaals toegegeven dat mijn oplossing fout is? Ik heb zonet een mogelijke maar onelegante correctie gegeven... Wat verlang je nog meer?

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
curry684 schreef op vrijdag 16 mei 2008 @ 11:13:
[...]

Uhm jij bent hier degene die met halfbakken niet functionerende 'superoplossingen' aan komt en doet alsof ze net zo goddelijk zijn als jezelf. Moet je niet vreemd opkijken als mensen je daarop aanspreken.Die oplossing die je daar gaf bevat een fundamentele fout en heb je nergens gecorrigeerd, je hebt 'm alleen verdedigd toen iemand die fout wel goed voorkwam.
Lol. Sorry voor de schijnbare pretentie dan. Ik heb nooit gezegd dat mijn oplossing "super" is of dat ik "God" ben, dat maak jij ervan.

Hoedanook de oplossing van Vozze is gewoon niet goed en van hetzelfde caliber als je vaak op TheDailyWTF tegenkomt. Dat mijn eerste oplossing niet correct is ligt aan een gebrekkige probleembeschrijving waarvan pas achteraf een andere poster de vereiste van heeft geformuleerd (waar ik toegegeven eerst had overgelezen). Ondertussen heb ik wel een (slechte) oplossing geven. Gebruik de oplossing van Aetos. Maar ik vrees dat bastv zonder al te veel nadenken de eerste werkende oplossing heeft gekozen.

[ Voor 9% gewijzigd door masterpoi op 16-05-2008 11:55 ]


  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
masterpoi schreef op vrijdag 16 mei 2008 @ 11:51:
[...]


Lol. Sorry voor de schijnbare pretentie dan. Ik heb nooit gezegd dat mijn oplossing "super" is of dat ik "God" ben, dat maak jij ervan.

Hoedanook de oplossing van Vozze is gewoon niet goed en van hetzelfde caliber als je vaak op TheDailyWTF tegenkomt. Dat mijn eerste oplossing niet correct is ligt aan een gebrekkige probleembeschrijving waarvan pas achteraf een andere poster de vereiste van heeft geformuleerd (waar ik toegegeven eerst had overgelezen). Ondertussen heb ik wel een (slechte) oplossing geven. Gebruik de oplossing van Aetos. Maar ik vrees dat bastv zonder al te veel nadenken de eerste werkende oplossing heeft gekozen.
Als je naar het resultaat kijkt, is er niets mis met mijn oplossing. Daarnaast is de leesbaarheid van mijn oplossing een stuk beter dan die van jou.

Het enige nadeel van mijn oplossing zou de performance kunnen zijn. Dit zou een afweging kunnen zijn om voor jouw oplossing te kiezen.
Dit is iets van de TS zelf kan testen en ik ben er dus ook erg benieuwd naar. Zoals ik er tegen aan kijk lijkt de data op maandniveau opgeslagen te zijn waardoor de performanceverlies te verwaarlozen zou kunnen zijn.

"He who thinks knows evertyhing, knows nothing" - Socrates


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Vozze schreef op vrijdag 16 mei 2008 @ 12:05:
[...]

Als je naar het resultaat kijkt, is er niets mis met mijn oplossing. Daarnaast is de leesbaarheid van mijn oplossing een stuk beter dan die van jou.

Het enige nadeel van mijn oplossing zou de performance kunnen zijn. Dit zou een afweging kunnen zijn om voor jouw oplossing te kiezen.
Dit is iets van de TS zelf kan testen en ik ben er dus ook erg benieuwd naar. Zoals ik er tegen aan kijk lijkt de data op maandniveau opgeslagen te zijn waardoor de performanceverlies te verwaarlozen zou kunnen zijn.
Ik denk natuurlijk miljoenen rijen. Op een kleine table zou ik durven gokken dat jouw oplossing zelfs sneller is. Maar bij grote tabellen moet je de indexen gebruiken.

De leesbaarheid is discutabel. Maar stel dat je de query moet uitbreiden, naar ik zeg maar wat, dagen. Dan moet je van je 100, 100000 maken van je maanden *100 en er de dagen bij optellen en dan overal je grenzen gaan aanpassen. Dat worden zeer snel, zeer veel aanpassingen (denk ook verder naar minuten, seconden, enz...). In mijn oplossing komt er gewoon een clause bij.

De oplossing van Stappel_ werkt uiteraard ook, maar ik denk dat we het eens zijn dat dat niet zo'n goed idee is alles naar string om te zetten?

Verwijderd

masterpoi schreef op vrijdag 16 mei 2008 @ 11:51:

Hoedanook de oplossing van Vozze is gewoon niet goed en van hetzelfde caliber als je vaak op TheDailyWTF tegenkomt.
En als je van die 100 nou eens 12 maakt? Vind je het dan nog steeds een WTF?

  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
masterpoi schreef op vrijdag 16 mei 2008 @ 12:15:
[...]


Ik denk natuurlijk miljoenen rijen. Op een kleine table zou ik durven gokken dat jouw oplossing zelfs sneller is. Maar bij grote tabellen moet je de indexen gebruiken.

De leesbaarheid is discutabel. Maar stel dat je de query moet uitbreiden, naar ik zeg maar wat, dagen. Dan moet je van je 100, 100000 maken van je maanden *100 en er de dagen bij optellen en dan overal je grenzen gaan aanpassen. Dat worden zeer snel, zeer veel aanpassingen (denk ook verder naar minuten, seconden, enz...). In mijn oplossing komt er gewoon een clause bij.

De oplossing van Stappel_ werkt uiteraard ook, maar ik denk dat we het eens zijn dat dat niet zo'n goed idee is alles naar string om te zetten?
Hier doe je dus al twee aannames:

1. Er zijn indexes aanwezig
2. Er zitten miljoenen rijen in

Aanpassen is even snel dan bedenken hoe de WHERE clause (foutloos) omgebouwd moet gaan worden. Ik heb de TS een generieke manier laten zien van hoe je van een maand en een jaar-kolom een periode kan maken. Mijns inziens een oplossing die echt niet van het niveau "Daily WTF" is.
Verwijderd schreef op vrijdag 16 mei 2008 @ 12:33:
[...]

En als je van die 100 nou eens 12 maakt? Vind je het dan nog steeds een WTF?
In het geval van * 100 komt er altijd een periode uit (200705 of 200812) en niet een nietszeggend getal.

Wanneer je dus tussen twee periodes de data wilt hebben, hoef je niet eerst je calculator te pakken om te bepalen wat de waardes moeten worden.

[ Voor 15% gewijzigd door Vozze op 16-05-2008 12:55 ]

"He who thinks knows evertyhing, knows nothing" - Socrates


Verwijderd

Vozze schreef op vrijdag 16 mei 2008 @ 12:52:

In het geval van * 100 komt er altijd een periode uit (200705 of 200812) en niet een nietszeggend getal.
Anders schoffel je eigen prutsoplossing nog even onderuit. Wat is er nietszeggend aan "aantal maanden sinds het begin van de jaartelling"? Er zijn in elk geval geen waarden die "niet kunnen", terwijl in jouw geval "200714" eigenlijk niet kan. Is een UNIX timestamp ook onzin?
Wanneer je dus tussen twee periodes de data wilt hebben, hoef je niet eerst je calculator te pakken om te bepalen wat de waardes moeten worden.
Waarvoor moet ik een calculator pakken dan? We hebben het toch over SQL? Volgens mij kan SQL zelf ook wel "rekenen".

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Verwijderd schreef op vrijdag 16 mei 2008 @ 12:33:
[...]

En als je van die 100 nou eens 12 maakt? Vind je het dan nog steeds een WTF?
Ja uiteraard, nog erger wat leesbaarheid en maintainability betreft. (Ik moet weten dat er twaalf maanden in een jaar zijn en dat die twaalf daarop slaat)

Verwijderd

masterpoi schreef op vrijdag 16 mei 2008 @ 13:09:

Ja uiteraard, nog erger wat leesbaarheid en maintainability betreft. (Ik moet weten dat er twaalf maanden in een jaar zijn en dat die twaalf daarop slaat)
Als je dat niet kunt onthouden én niet kunt opmaken uit de context, kun je nog altijd documenteren :*

  • Aetos
  • Registratie: November 2001
  • Laatst online: 14-10 18:36
Ik denk dat masterpoi net als ik bezwaar maken tegen een constructie die iets doet als:
code:
1
select a,b from c where Z*a+b < Y


Een database engine zal hier geen indexen voor kunnen gebruiken. Hierbij maakt het me niet uit wat Z en Y zijn zolang Z maar geen 0 is. En bedenk dat er nergens iets over het datatype van jaar en maand gezegd is.

Dus ja.. het is nog steeds een WTF. Als je het zo'n functie van a en b wilt gebruiken en je wilt het perse op die manier oplossen dan moet je een computed column gaan gebruiken. En dat moet je alleen doen als je daarmee bestaande performance problemen oplost. De TS heeft aangegeven het datamodel niet te kunnen/willen veranderen. Dus computed columns kunnen geen deel maken van de oplossing.

Op een database waar maar 100 record in de tabel staan zal het niet uitmaken. Alleen dan vraag ik me af waarom je een database gaat gebruiken? Excel is toch de oplossing van alle IT problemen?

En als je bij het maken van een database/queries geen idee hebt waar je het over hebt moet je aannames maken. En dan mag je wat mij betreft beginnen met 1 miljard rows en indexen. De 1 miljard rows om je in ieder geval na te laten denken over efficientie en de indexen omdat je als je die niet veronderstelt gewoon altijd een trage oplossing bouwt.

Je kunt natuurlijk andere keuzes maken die het je makkelijker maken om tot een oplossing te komen. Gemak dient de mens tenslotte. Maar dan blijft het toch beter om het in excel op te lossen.

Oftewel wees pessimist en je zult nooit teleurgesteld worden.

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Vozze schreef op vrijdag 16 mei 2008 @ 12:52:
[...]


Hier doe je dus al twee aannames:

1. Er zijn indexes aanwezig
2. Er zitten miljoenen rijen in
Akkoord, maar vaak is het zo (althans het is vaak zo geweest in tijdens de "bubble") dat hobby projectjes op kleine databases ook gaan gebruikt worden in echte bedrijfstoepassingen.

Door de indexen meteen juist te gebruiken zorgt je db engine ervoor dat je database moeiteloos kan meeschalen.
Aanpassen is even snel dan bedenken hoe de WHERE clause (foutloos) omgebouwd moet gaan worden. Ik heb de TS een generieke manier laten zien van hoe je van een maand en een jaar-kolom een periode kan maken. Mijns inziens een oplossing die echt niet van het niveau "Daily WTF" is.
Hoedanook jouw oplossing werkt. Ik heb er echter (weinig tactvol, waarvoor excuus) mijn bedenkingen bij ge-uit. De oplossing van Aetos is de beste.

  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Verwijderd schreef op vrijdag 16 mei 2008 @ 13:12:
[...]

Als je dat niet kunt onthouden én niet kunt opmaken uit de context, kun je nog altijd documenteren :*
Dan moet je ook nog eens documentatie lezen...

Stel je outsourced het onderhoud van je code naar een land waar ze nog nooit gehoord hebben van de gregoriaanse kalender en waar men geen engels/nederlands verstaat. Enkel SQL.

Bovendien heb je ook een probleem in het jaar 2^31 / 12 (integer overflow).

(Ok voor dit voorbeeld zijn deze dingen misschien compleet onozel, maar de principes blijven wel. Waarom speciale constructies opzetten als het met standaard sql beter en efficienter kan?)

[ Voor 45% gewijzigd door masterpoi op 16-05-2008 13:45 ]


Verwijderd

Ik vind dat je een beetje pathetische pogingen doet om je gelijk te halen. Kom in het jaar 357913941 maar terug.

Er is hier geen perfecte oplossing mogelijk omdat het datamodel niet geweldig is. Als het als DATE type was opgeslagen was er niet zo'n groot probleem. Als het als jaar*12+maandnr was opgeslagen ook niet. Tenzij je wilt dat het over 357.914 millennia ook nog werkt.

[ Voor 54% gewijzigd door Verwijderd op 16-05-2008 14:17 ]


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Verwijderd schreef op vrijdag 16 mei 2008 @ 14:15:
Ik vind dat je een beetje pathetische pogingen doet om je gelijk te halen. Kom in het jaar 357913941 maar terug.
Dat mag je vinden. Ik hoop echter dat ik nooit code moet onderhouden die jij geschreven hebt.
Ik zei zelf al dat mijn voorbeelden academisch waren.
Er is hier geen perfecte oplossing mogelijk omdat het datamodel niet geweldig is. Als het als DATE type was opgeslagen was er niet zo'n groot probleem. Als het als jaar*12+maandnr was opgeslagen ook niet. Tenzij je wilt dat het over 357.914 millennia ook nog werkt.
Niet iedereen heeft de luxe from scratch te beginnen. Als je legacy systeem moet onderhouden kom je dit soort problemen tegen. En dan moet je roeien met de riemen die hebt. Als je dan nog meer jaar*12+maandnr onzin gaat introduceren dan maak je de situatie alleen maar erger voor de persoon die dat dan weer moet onderhouden. Vandaar mijn referentie naar TDWTF.

Btw als je het als long opslaat kun je met jaar*12+maandnr ook weer een tijdje verder. Punt is dat je een probleem introduceert dat niet nodig is. Het wordt erger als je ook dagen/uren/minuten op die manier gaat vergelijken... jaar*12*31+31*maand + dag enz...

[ Voor 21% gewijzigd door masterpoi op 16-05-2008 15:35 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Cheatah is een van de weinigen in dit topic die een beter datamodel voorstelt, namelijk door gewoon het DATE type te gebruiken of een int welke op een optimale manier een jaar en maand respresenteert.

Juist de rest is wtf spul.
masterpoi schreef op vrijdag 16 mei 2008 @ 15:11:
Dat mag je vinden. Ik hoop echter dat ik nooit code moet onderhouden die jij geschreven hebt.
Ik zei zelf al dat mijn voorbeelden academisch waren.
Cheatah is juist een vd weinige users op got (<5%) waarvan ik code zou willen onderhouden. ;)
Het wordt erger als je ook dagen/uren/minuten op die manier gaat vergelijken... jaar*12*31+31*maand + dag enz...
Neeheehee, want dan is het helemaal te obvious dat je gewoon een passend data type kan gebruiken. ;)

{signature}


  • masterpoi
  • Registratie: Oktober 2004
  • Laatst online: 18-11 13:41
Voutloos schreef op vrijdag 16 mei 2008 @ 15:42:
Cheatah is een van de weinigen in dit topic die een beter datamodel voorstelt, namelijk door gewoon het DATE type te gebruiken of een int welke op een optimale manier een jaar en maand respresenteert.

Juist de rest is wtf spul.
100% Akkoord, maar de constraint is nu net dat DAT niet mag...
[...]
Cheatah is juist een vd weinige users op got (<5%) waarvan ik code zou willen onderhouden. ;)
Kan best zijn voor code die hij from scratch schrijft, maar oplossing die hij verdedigt onder de constraints van het probleem schaalt minder goed, is minder goed onderhoudbaar, enz (zie al mijn vorige rants).

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
12 en 100 zijn allebei magische getallen, maar 12 maakt toch iets meer sense. Als je het te moeilijk vind maak je er leuk een constante van, of maak je een conversie functie. :z

Maar goed, Ts heeft inmiddels de stomme band aid oplossing gebruikt, het datamodel-kan-beter punt is ook wel gemaakt dus kap maar met je wedstrijdje. Ik laat dit topic lekker voor wat het is.

{signature}


  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
Verwijderd schreef op vrijdag 16 mei 2008 @ 13:04:
[...]

Anders schoffel je eigen prutsoplossing nog even onderuit. Wat is er nietszeggend aan "aantal maanden sinds het begin van de jaartelling"? Er zijn in elk geval geen waarden die "niet kunnen", terwijl in jouw geval "200714" eigenlijk niet kan. Is een UNIX timestamp ook onzin?

[...]

Waarvoor moet ik een calculator pakken dan? We hebben het toch over SQL? Volgens mij kan SQL zelf ook wel "rekenen".
Hoezo onderuit schoffelen?

Als jij de gegevens tussen maart 2006 en december 2008 terug wilt hebben, moet je eerst bepalen welke waardes je moet gebruiken in je statement (of je moet uit je hoofd weten welke maanden dit zijn sinds het begin van de jaartelling), Dit doe je door eerst de berekeningen (2006 *12) + 3 en (2008 * 12) + 12 te doen. Pas daarna kan je je statement opbouwen.
Als je (* 100) gebruikt kan je gewoon de periodes neerzetten (200603 en 200812). Daar hoef je niet over na te denken of te berekenen.
200714 zou inderdaad onzin zijn, maar jij en ik weten dat er in 2007 geen 14 maanden zitten en 200714 dus onzin is.

"He who thinks knows evertyhing, knows nothing" - Socrates


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 10-11 10:50
masterpoi schreef op woensdag 14 mei 2008 @ 14:22:
[...]


En het verschil met mijn post is??
Ja, dat vraag ik me ook af. Jouw oplossing is prima. Men moet gewoon met een beetje slim programmeren de sql efficiënt opbouwen maar wel op zo'n manier dat de indexen gebruikt worden. In jouw oplossing gebeurt dat tenminste. Al die andere manieren zorgen ervoor dat elk op record eerst allemaal rare concatenaties gedaan moeten worden wat er voor zorgt dat de indexen buiten spel gezet worden.

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 07:40

Creepy

Tactical Espionage Splatterer

paulh: heb je uberhaupt de rest van het topic doorgelezen tot het punt waar de vraag van masterpoi wordt beantwoord?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 10-11 10:50
Creepy schreef op vrijdag 16 mei 2008 @ 17:16:
paulh: heb je uberhaupt de rest van het topic doorgelezen tot het punt waar de vraag van masterpoi wordt beantwoord?
Nou ik dacht dat ik al aan het eind was ... blijkbaar over de vervolgpagina's heen gekeken :o

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 18-11 00:56
Vozze schreef op vrijdag 16 mei 2008 @ 16:36:
[...]


Hoezo onderuit schoffelen?

Als jij de gegevens tussen maart 2006 en december 2008 terug wilt hebben, moet je eerst bepalen welke waardes je moet gebruiken in je statement (of je moet uit je hoofd weten welke maanden dit zijn sinds het begin van de jaartelling), Dit doe je door eerst de berekeningen (2006 *12) + 3 en (2008 * 12) + 12 te doen. Pas daarna kan je je statement opbouwen.
Als je (* 100) gebruikt kan je gewoon de periodes neerzetten (200603 en 200812). Daar hoef je niet over na te denken of te berekenen.
200714 zou inderdaad onzin zijn, maar jij en ik weten dat er in 2007 geen 14 maanden zitten en 200714 dus onzin is.
Dan typ je in plaats van 200703 toch 2007*12+3? D'r wordt niet voor niets gezegd dat MySQL ook kan rekenen. :)

[ Voor 3% gewijzigd door Jaap-Jan op 16-05-2008 17:37 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:45

.oisyn

Moderator Devschuur®

Demotivational Speaker

Vozze schreef op vrijdag 16 mei 2008 @ 16:36:
Dit doe je door eerst de berekeningen (2006 *12) + 3 en (2008 * 12) + 12 te doen. Pas daarna kan je je statement opbouwen.
Onzin. Dat doe je door die expressies direct in je statement te zetten.
.edit: euh ja ik moet ook verder lezen 8)7

[ Voor 6% gewijzigd door .oisyn op 16-05-2008 18:04 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Vozze
  • Registratie: December 2001
  • Laatst online: 18-11 20:03
Jaap-Jan schreef op vrijdag 16 mei 2008 @ 17:36:
[...]


Dan typ je in plaats van 200703 toch 2007*12+3? D'r wordt niet voor niets gezegd dat MySQL ook kan rekenen. :)
Heb je gelijk in. Ik had alleen het voorbeeld van maui71 (die met het "12 *" - idee aankwam) in m'n hoofd:
Verwijderd schreef op woensdag 14 mei 2008 @ 13:20:
1-2007-> 1 + (12 * 2007) = 24085
3-2008 -> 3 + (12* 2008) = 24099

code:
1
2
3
4
SELECT  veld1,veld2 
    FROM tabel 
    WHERE (((jaar*12) + maand)>=24085) 
         AND (((jaar*12) + maand)<=24099)


zomaar ff een idee, vraag me alleen af of dit nog geindexeerd wordt afgehandeld.
Wat mij betreft stoppen we deze discussie. TS geeft aan dat hij het datamodel niet kan veranderen dus moet hij roeien met de riemen die hij heeft.

Of ie het nu op mijn manier doet of op een andere (eventueel snellere) manier moet hij zelf bepalen. Zoals al eerder aangegeven kan hij zelf de performance testen en daarop een keuze maken.

"He who thinks knows evertyhing, knows nothing" - Socrates


  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 08:48
Aetos schreef op vrijdag 16 mei 2008 @ 13:18:
Ik denk dat masterpoi net als ik bezwaar maken tegen een constructie die iets doet als:
code:
1
select a,b from c where Z*a+b < Y


Een database engine zal hier geen indexen voor kunnen gebruiken. Hierbij maakt het me niet uit wat Z en Y zijn zolang Z maar geen 0 is.
Tenzij je database engine function-indices ondersteund (Oracle kan dit o.a.). Je moet het niet willen als je van scratch begint, maar als je te maken hebt met legacy rommel kan het een uitkomst zijn.

Whatever

Pagina: 1