Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

Getallen in database sorteren.

None
13 antwoorden
  • Voor een bepaalde toepassing worden in een database twee kolommen gevuld met hoogte informatie.
    Dat gebeurt dmv twee variabelen: $elevation en $elevation1
    met deze regels.
    [code:1:225179afaf]#Schrijf hoogtedata naar de velden userdata en userdata2
    $d_UserData="$elevation1"+ " ft"
    $d_User2="$elevation" + " m"[/code:1:225179afaf]

    In de ene kolom (Userdata) komt de hoogte in voeten te staan, in de tweede kolom (User2) de hoogte in meters.
    Grootste waarden zullen niet groter zijn dan 30000 voor de voeten en 10000 voor de meters. Deze waardes kunnen wél negatief worden.

    Zoals het nu is worden, bij sorteren op de betreffende kolommen, de cellen getoond op volgorde van het begincijfer bijv:

    1
    11
    111
    2
    22
    201
    terwijl ik zou willen:
    1
    2
    11
    22
    111
    201

    Het meest voor de hand liggend is misschien om er nullen voor te zetten en zo tot een vast formaat te komen. 1 wordt dan 00001.
    Beter is het misschien om er spaties voor te zetten. Dan ziet het er rustiger uit.
    Nou ben ik niet zo'n programmeur (zeg maar dat ik er eigenlijk geen kaas van heb gegeten) maar ik wilde toch proberen iets te verzinnen waarmee ik dat kon bereiken. Ik heb zojuist alles gewist omdat ik er bende van maak en helemaal niets zinnigs heb weten te verzinnen.
    Kan er iemand me mogelijk helpen hier uit te komen?
    Voor de volledigheid heb ik het hele stukje code hieronder gezet.
    Het wordt gebruikt binnen de macrofuncties van het software programma GSAK:
    [code:1:225179afaf]
    #*******************************************
    # MacVersion = 0.5
    # MacDescription = Elevation technology test
    # MacAuthor = Lignumaqua/ door mij aangepast
    # MacFileName = elevation_a.gsk
    # MacUrl =
    #*******************************************

    # A technology test. This macro queries the geonames.org satellite and shuttle data
    # for elevation at the best resolution it can. If it can't find a result at the 90m resolution
    # it tries again with the 1km resolution data. Any results over the ocean will return -9999
    #
    # The macro populates an SQLite database with the elevations of every waypoint in the current filter.
    # Intent is that this database would be permanent so that the geonames server is hit as little as possible.
    #
    # If you run this against a large database it will take a LONG time to run the first time through!
    #
    # After getting all the data the macro shows a simple summary of the highest and lowest 10 points and their
    # elevations (in meters or feet as appropriate) along with the average elevation. All the data is available for further analysis.
    #
    # Further runs will only hit the geonames server for any missing data.

    VERCHECK Version=7.5.0.0 (Note: this macro requires the latest 7.5 GSAK release)

    # Units?
    IF SysInfo("Distance") = "K"
    $distunits = "m"
    ELSE
    $distunits = "ft"
    ENDIF

    $conversion = 3.28084

    $outputhtml = $_Install + "\temp\elevationdata.html"

    $database = Replace("'","''",$_CurrentDatabase)

    # Set up the SQL table
    $sqlfile = $_Install + "\macros\elevationdataSQL.db3"

    $status = ""

    IF NOT(FileExists($sqlfile))
    $status = Sqlite("create",$sqlfile)
    ENDIF

    $status = Sqlite("open",$sqlfile)

    $Data="Code text, Database text, Elevation integer, Resolution text, units text, PRIMARY KEY (Code, Database)"
    $_sql = "CREATE TABLE IF NOT EXISTS elevationdata ($Data)"
    $status = Sqlite("sql",$_sql)
    # Filter down to the caches where we have no elevation data
    $Status = DbToSQLite("caches","Code,Name,Country,State,FoundByMeDate",$sqlfile)
    $_sql = "select code from caches WHERE (caches.code NOT IN (SELECT code from elevationdata WHERE database='$database'))"
    $codes = Sqlite("sql",$_sql)

    IF NOT($codes="")

    MACROFLAG type=clear range=all
    $status = CodeMatch($codes,$_NewLine,"M")
    MFILTER Expression=$d_MacroFlag
    $TotalCount = $_FilterCount
    $count = 0

    $_sql = "BEGIN"
    $status = Sqlite("sql",$_sql)

    WHILE NOT($_EOL) AND ($TotalCount > 0)
    $count = $count + 1
    $codefield = Replace("'","''",$d_Code)
    $_sql = "SELECT Code from elevationdata WHERE code = '$codefield' and database = '$Database' and elevation <> -32768 and elevation <> -9999"
    $status = Sqlite("sql",$_sql)
    IF Len($status) = 0
    $url = "http://ws5.geonames.org/srtm3?lat=" + $d_Latitude + "&lng=" + $d_Longitude
    SHOWSTATUS msg="Getting 90m resolution Elevation for $d_name" Width=350 Title="$count of $TotalCount"
    $data = GetUrl($url,"")
    $resolution = "90m"
    IF Val($data) = -32768
    $url = "http://ws.geonames.org/gtopo30?lat=" + $d_Latitude + "&lng=" + $d_Longitude
    SHOWSTATUS msg="Getting 1km resolution Elevation for $d_name" Width=350 Title="$count of $TotalCount"
    $data = GetUrl($url,"")
    $resolution = "1km"
    ENDIF
    IF Len($data) > 0
    $elevation = Val($data)
    IF $elevation = -9999
    $elevation = 0
    ENDIF
    $elevation1 = Int($conversion * $elevation)
    $_sql = "REPLACE INTO elevationdata VALUES('$codefield','$database',$elevation,'$resolution','$distunits')"
    $status = Sqlite("sql",$_sql)
    #Schrijf hoogtedata naar de velden userdata en userdata2 in GSAK zelf
    $d_UserData="$elevation1"+ " ft"
    $d_User2="$elevation" + " m"
    SHOWSTATUS msg="Posting Elevation for $d_name: $elevation" Width=350 Title="$count of $TotalCount"
    ENDIF

    ENDIF
    GOTO position=next
    ENDWHILE
    SHOWSTATUS msg="End" Width=350 Display=Off

    $_sql = "COMMIT"
    $status = Sqlite("sql",$_sql)

    ENDIF

    CANCELFILTER

    $_sql = "select elevationdata.code, name, country, state, resolution, elevation from elevationdata, caches WHERE elevationdata.code = caches.code and database='$database' order by elevation desc limit 10"
    $status = Sqlite("sql",$_sql,"headings=yes")

    $_sql = "select count(*) from caches"
    $rows = Val(Sqlite("sql",$_sql,""))

    $_sql = "select elevationdata.code, name, country, state, resolution, elevation from elevationdata, caches WHERE elevationdata.code = caches.code and database='$database' order by elevation desc limit ($rows-10),10"
    $status = $status + " $distunits <tr><td>…</td><td>…</td><td>…</td><td>…</td><td>…</td><td>…</td></tr><tr><td>" + Sqlite("sql",$_sql,"")


    $status = Replace(";","</td><td>",$status)
    $status = Replace($_NewLine," $distunits </td></tr>" + $_NewLine + "<tr><td>",$status)
    $status = $status + " $distunits"

    $_sql = "select avg(elevation) from elevationdata WHERE database = '$database'"
    $status = $status + "</td></tr><tr><td colspan='5'>" + "Average of all caches in database:</td><td>" + NumToStr(Round(Val(Sqlite("sql",$_sql)),1)) + " $distunits" + "</td></tr>"

    $status = "<center><table border='1' style='font-size:80%;font-family:verdana'><td>" + $status + "</table></center>"

    $status = PutFile($outputhtml,$status)

    $Form = Editform($Form,"Browser1","url",$outputhtml)

    $result = Form($form,"")

    #$_sql = "DROP TABLE IF EXISTS Caches"
    #$status = Sqlite("sql",$_sql)

    #MSGOK msg=$status

    <Data> VarName=$form
    #********************************************************************
    # Form generated by GSAK form designer on Sat 20-Dec-2008 18:33:20
    #********************************************************************

    Name = Form1
    Type = Form
    Height = 700
    Width = 700

    Name = Label1
    Type = Label
    Color = 16744448
    Height = 20
    Left = 220
    Size = 12
    Style = bold
    Top = 10
    Width = 143
    Caption = Ten Highest && Lowest Elevations

    Name = Browser1
    Type = Browser
    Height = 570
    Left = 21
    Top = 39
    Width = 650
    Taborder = 8

    Name = Button1
    Type = Button
    Height = 25
    Left = 308
    Top = 620
    Width = 75
    Taborder = 9
    Caption = OK

    <enddata>[/code:1:225179afaf]
  • Het lijkt er op dat je de 'elevation's als tekst opslaat. Dan is de sortering alfabetisch. Als de de waarden als getal opslaat, zal de sortering waarschijnlijk numeriek gebeuren.
    Verder lijkt het me teveel om 2 samenhangende getallen in een tabel op te nemen…
  • [quote:7c12f79e23="MaartenW"]Het lijkt er op dat je de 'elevation's als tekst opslaat. Dan is de sortering alfabetisch. Als de de waarden als getal opslaat, zal de sortering waarschijnlijk numeriek gebeuren.[/quote:7c12f79e23]

    Geen idee…het is door een ander geschreven. Oorspronkelijk werd er maar één kolom gevuld met één soort hoogteinformatie, nl in voeten.

    Met veel experimenteren en proberen heb ik er een tweede kolom aan toe kunnen voegen met daarin in feite dezelfde info, maar dan in meters. Dat is mijn hele bijdrage….en dat werkt al meer dan een half jaar prima….met uitzondering van het sorteren.
    Het sorteren is een functie binnen de database en er kan dus op de twee verschillende kolommen (maar ook andere) worden gesorteerd.
    Voordat ik die tweede kolom toevoegde werd er in op dezelfde manier gesorteerd als dat het nu plaats vindt, alleen kon dat toen dus alleen maar op de kolom waarin de waarde in voeten wordt aangegeven. Nu kan dat dus ook op de kolom in meters, maar er wordt ( en werd) altijd op dezelfde (voor mij onlogische) manier gesorteerd.
    Als het opgelost kan worden door de gegevens als getal op te slaan, dan vind ik dat prima, maar hoe doe ik dat dan?

    [quote:7c12f79e23]Verder lijkt het me teveel om 2 samenhangende getallen in een tabel op te nemen…[/quote:7c12f79e23]
    Ik snap niet wat je hier mee bedoelt denk ik. Waarom zou ik geen twee afzonderlijke kolommen met in feite dezelfde waarde (maar uitgedrukt in een andere eenheid) naast elkaar kunnen gebruiken?
  • [quote:65a423f2fe]Als het opgelost kan worden door de gegevens als getal op te slaan, dan vind ik dat prima, maar hoe doe ik dat dan? [/quote:65a423f2fe]
    Door in de database van dat veld een getal veld te maken ipv een tekst veld….
    Wel eerst een backup maken…
  • [quote:7da56b83ae="andre@home"]Door in de database van dat veld een getal veld te maken ipv een tekst veld….
    Wel eerst een backup maken…[/quote:7da56b83ae]

    Helaas niet mogelijk (volgens mij). Ik heb geen toegang tot de eigenschappen van die kolom (cellen). Die is vastgelegd in het programma (GSAK) dat voor het tonen/opbouwen van de database weer gebruik maakt van SQl.
    Het enige dat ik kan doen (via die macro) is het vullen van datavelden in de binnen de database ter beschikking staande kolom(men) voor eigen gebruik, in dit geval $d_User2 en $d_Userdata genoemd.
  • Mogelijk kun je de geSELECTeerde tekstwaarden omzetten in getallen en daarop rangschikken, bv.:
    [code:1:a532e74cd7]
    $_sql = "select elevationdata.code, name, country, state, resolution, CAST(elevation as INTEGER) IntElevation from elevationdata, caches WHERE elevationdata.code = caches.code and database='$database' order by IntElevation desc limit 10"
    Mogelijk moet je voor CAST een ander woord gebruiken, afhankelijk van het SQL dialect.[/code:1:a532e74cd7]
    Hierbij wordt met de CAST de tekst elevation omgezet in de integer IntElevation.
  • MaartenW
    Bedankt voor de moeite, maar ik realiseer me bij het lezen van het antwoord dat ik niet duidelijk genoeg ben geweest.
    De macro doet twee dingen:
    1. vult de betreffende cellen van de kolommen met een waarde ( in meters dan wel in voeten ) die van het internet wordt gehaald.

    2. Aan het einde wordt -als extra- een pagina opgebouwd met een overzicht van de tien hoogste en de tien laagste waarden van die database.
    Zie dit als een extraatje.
    Die tabel kun je HIER op mijn webpagina te zien, het bovenste deel, direct onder het kopje "Highest and Lowest Elevations".
    Dit wordt gerealiseerd in het deel van het programma dat volgt op "CANCELFILTER"

    Het gaat me om het eerste deel, het vullen van de database. Dit omdat ik binnen het programma GSAK weer gebruik maak van die database (waar ik verder geen enkele invloed op uit kan oefenen) en daardoor de database kan bevragen bijv via filtering of door per kolom op inhoud te sorteren.
    Bij dit alles zit de database als het ware opgesloten in GSAK en is voor mij niet 'zichtbaar'of direct benaderbaar.
    Ik moet me dus beperken tot het formateren van de data die ik (in dit geval via de macro) in de database zet.

    Dat doet de macro met behulp van de twee regels code die ik in mijn eerste posting apart heb vermeld.

    Ik heb geprobeerd om de variabele $elevation om te vormen naar een vaste grootte.
    Zoals gezegd zal het getal nooit langer zijn dan vijf digits (bijv 10000 meter) en mininaal 1 digit (nul) De waarde kan wel negatief worden.
    Bijv -4 meter.
    Ik heb geprobeerd om het aantal digits vast te stellen en daar dan nullen of spaties voor te zetten.
    Bijvoorbeeld het getal 23 –> dat bestaat uit twee digits.
    Voeg nu vóór het getal drie nullen of drie spaties in (ik weet niet wat het handigste is)
    Het getal wordt dan: 00023 of ' 23'
    Mijn hoop is dan dat er, op het moment dat ik in de kolom sorteer (door op de kolomheader te klikken) dan een meer logische sorteervolgorde ontstaat.
    Dat bepalen van het aantal digits en die aan te vullen tot een vaste lengte lukt me dus niet. Ook heb ik geen idee hoe ik dat doe in het geval van een negatief getal.

    Hopelijk maakt deze toelichting het wat duidelijker.

    Hoe dan ook, bedankt voor de moeite om me te helpen.
  • Het is me niet duidelijker geworden… :cry:
    Ik neem aan - je hebt het niet gespecificeerd - dat de VB of VBA gebruikt.
    Het probleem wat je hebt is dat de sortering niet goed werkt. Je kunt de tekst omzetten in getallen (val…) en/of je kunt de getallen omzetten in geformatteerde tekst (format…). Hiermee kun je de sortering uitvoeren.
  • MaartenW,
    ik heb ook geen idee wat gebruikt wordt VB of VBA of….?
    Zoals gezegd, het is een macro die door iemand anders geschreven is -tbv dat programma GSAK dat ik gebruik- en die ik van het internet heb gehaald.
    Die macro voorzag in het plaatsen van hoogtedata in feet in een kolom.
    Met mijn beperkte kennis van BASIC van 20 jaar geleden ben ik er in geslaagd om een tweede kolom te vullen met dezelfde waarden, maar dan uitgedrukt in meters.
    Maar daar houdt het dan ook mee op…..verdere experimenten om de gegevens zo te formateren dat er meer logisch gesorteerd wordt hebben niets opgeleverd…..alleen maar rommel.

    Ik zal nog eens gaan puzzelen met 'val' en 'format' maar ik zie het donker in….;-)
  • Als ik het goed lees wordt sqlite gebruikt als database. Omdat je je velden als tekst opslaat, wordt er bij een standaard 'order by' alfanumeriek gesorteerd. Dat betekent dat je het resultaat krijgt wat jij beschrijft. Om het het resultaat te krijgen wat je [b:0a87533451]wil[/b:0a87533451] zal je de 'order by' clausule iets moeten aanpassen.
    Je moet ervoor zorgen dat de database niet alfanumeriek, maar numeriek sorteert, en dat doe je als volgt (ik heb het even snel getest met een simpel tabelletje)[code:1:0a87533451]select <velden> from <tabel> order by cast(<user_data> as real)[/code:1:0a87533451]Doordat je nu het veld cast naar een real datatype, wordt de sortering numeriek uitgevoerd. Hierdoor krijg je dan de door jou gewenste sortering.
  • Meneer_Ed.

    Ik ben een beetje laat met antwoorden, maar ben een dagje afwezig geweest.

    Inderdaad is de database gebaseerd op SQL. Probleem voor mij is echter dat die database gebruikt wordt door een programma (GSAK) en dat ik alleen via dat programma de database bevraag.
    Nou zou dat wel op een andere manier kunnen, bijv via SQLight, maar dan mis ik de functionaliteiten van GSAK. En juist binnen GSAK is dat belangrijk in relatie tot andere gegevens.

    En binnen GSAK kan ik de manier waarop de data bevraagd wordt niet beïnvloeden. Ik kan alleen op kolomheaders klikken om de sorteervolgorde te bepalen, hoog naar laag of laag naar hoog dus A–>Z of Z–>A. Er is een groot aantal kolommen (Code, naam, eigenaar, land, streek, lengtegraad, breedtegraad en dan ook de hoogte en nog een stuk of wat) en bij het aanklikken van een bepaalde kolom wordt op die kolom gesorteerd.
    (allemaal wel bekend denk ik ;-) ).
    En daar houdt het dus op wat mijn mogelijkheden betreft. Het enige dat ik kan beïnvloeden is de invoer (denk ik).
    Nou wordt die invoer voor de hoogte binnen GSAK geregeld via dat macro waar ik het al de hele tijd over heb. Dat moet ook wel geautomatiseerd gebeuren, gezien het grote aantal gegevens ( een database bevat makkelijk 5000 punten).
    Daarom zoek ik het in het formatteren van de invoer omdat dat het enige is dat ik kan beïnvloeden…..denk ik. Maar zoals ook al eerder opgemerkt, ik heb bitter weinig kaas gegeten van programmeren en van SQL weet ik al helemaal niets. Ik heb inmiddels SQLite opgescharreld en hoop op die manier achteraf de gegevens om te zetten aangezien ik aan de structuur van de database zelf niets mag wijzigen om te voorkomen dat ik daardoor GSAK opblaas.

    Is het overigens binnen SQL mogelijk om spaties of nullen voor een getal (leading zero's)te gebruiken?
    Ik ben daar nog niet achter kunnen komen en als dat niet kan, dan kan ik beter meteen stoppen met het te proberen want dan is mijn idee gewoon niet uitvoerbaar.
    Of slaat het idee gewoon nergens op? Laat me dat dan ook svp weten, dan hoeven we er geen energie in te steken.

    Al weer bedankt voor alle moeite.
  • [quote:41ff06c9f3="helicop"]Meneer_Ed.

    Ik ben een beetje laat met antwoorden, maar ben een dagje afwezig geweest.
    [/quote:41ff06c9f3]
    Ik ben een weekje ziek geweest, dus ik kon toch niet eerder reageren.
    Door je codevoorbeeld (de macro neem ik aan) dacht ik dat je wel zelf queries kom gebruiken.
    Heb je trouwens al op het forum van de GSAK website gekeken/gezocht? Ik denk dat je daar toch het snelst hulp krijgt van medegebruikers van de applicatie.
  • [quote:6500422814="meneer_ed"][quote:6500422814="helicop"]Meneer_Ed.

    Ik ben een beetje laat met antwoorden, maar ben een dagje afwezig geweest.
    [/quote:6500422814]
    Ik ben een weekje ziek geweest, dus ik kon toch niet eerder reageren.
    Door je codevoorbeeld (de macro neem ik aan) dacht ik dat je wel zelf queries kom gebruiken.
    Heb je trouwens al op het forum van de GSAK website gekeken/gezocht? Ik denk dat je daar toch het snelst hulp krijgt van medegebruikers van de applicatie.[/quote:6500422814]


    Weer helemaal beter hoop ik?? :D

    Ja, heb op het forum gekeken. Ben een trouw bezoeker. Maar de macro die ik gebruik is vrij oud en min of meer in onbruik geraakt omdat de functionaliteit op is genomen in een andere macro, die voor mij (nog) niet interessant is.
    Ik wil de maker van de macro niet meer lastig vallen met mijn persoonlijke probleempje. Ik ben kennelijk de enige die zich er aan stoort.
    Daarnaast heb ik die macro ook een beetje aangepast aan mijn eigen idee ( dat lukte me toen wel, zij het ook met een beetje hulp van de maker en veel experimenteren) en is het niet meer de oorspronkelijke macro.

    Ik denk dat ik het maar op geef.
    Heel erg bedankt voor de moeite.

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.