Recent

Author Topic: [SOLVED] Tricky SQLite sort  (Read 5789 times)

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 630
    • Double Dummy Solver - free download
[SOLVED] Tricky SQLite sort
« on: August 11, 2016, 07:22:45 pm »
My DB has a score field that sometimes is a real number, and sometimes in a PCT, with a % sign. I want to sort this column so that all the Pct scores stay together and all the real numbers stay together. Like this:
   
   0.12
  12.45
   8.05%
  14.50%
 100.00%


I was hoping to use something like the following:
Code: Pascal  [Select][+][-]
  1. 'SELECT * from DataTable Order By Case StrScan(Score,''%'') WHEN ''0'' then 1 ELSE ''0'' END , Cast(Score as Real) '

but there is no such code as StrScan. I've also tried StrPos, but doesn't exist either. How can I accomplish this sort?
« Last Edit: August 12, 2016, 01:57:38 am by bobonwhidbey »
Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64

sfeinst

  • Sr. Member
  • ****
  • Posts: 256
Re: Tricky SQLite sort
« Reply #1 on: August 11, 2016, 07:29:40 pm »
This is off the top of my head so it has not been tested.  But replace your StrScan with
substr(Score, Length(Score), 1) and see if that works.

Overall, though, you may want to consider why your database uses mixed data in a column and if that is a good design.  Also, since % is in the field, I'm guessing it is a varchar of some type where a numeric field might better.

Percents can be stored as real to save you issues.  Of course, if you inherit the database, not much you can do.

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Tricky SQLite sort
« Reply #2 on: August 11, 2016, 08:18:28 pm »
I guess, since it is obviously allowed to store both species ;) (bad design) you store it as a string. In that case why not use
Code: MySQL  [Select][+][-]
  1.  LIKE '*'%''%
dunno but something like that should work.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 630
    • Double Dummy Solver - free download
Re: Tricky SQLite sort
« Reply #3 on: August 11, 2016, 10:26:57 pm »
LIKE will work to select just those records with/without a "%" in the Score field, but it won't work to differentiate them on a sort in the same column :(

Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64

paweld

  • Hero Member
  • *****
  • Posts: 1568
Re: Tricky SQLite sort
« Reply #4 on: August 11, 2016, 10:38:13 pm »
Code: MySQL  [Select][+][-]
  1. SELECT * from DataTable Order By Case WHEN length(replace(score, '%', ''))<length(score) then 1 ELSE 0 END , Cast(Score as Real)
Best regards / Pozdrawiam
paweld

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: Tricky SQLite sort
« Reply #5 on: August 11, 2016, 11:10:44 pm »
This will work (Tested on MS-Access):
Code: MySQL  [Select][+][-]
  1. FROM DataTable
  2. ORDER BY IIf(Right([Score],1)="%",1,0), IIf(Right([Score],1)="%",CDbl(Replace([Score],"%","")),CDbl([Score]));
  3.  

keep in mind this assumes that % will be at the most right of the score with no trilling spaces other wise you should use InStr instead of Right to check if % in score.
« Last Edit: August 11, 2016, 11:15:21 pm by shobits1 »

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 630
    • Double Dummy Solver - free download
Re: Tricky SQLite sort
« Reply #6 on: August 12, 2016, 12:25:28 am »
I don't think any of those functions exist in SQLite. Certainly one of the downside for using SQLite.

The SQLite documentation talks about an InStr(x,y) function, but that doesn't seem to work within Order By. I tried this to no avail:

Code: Pascal  [Select][+][-]
  1. 'SELECT * from DataTable Order By Case InStr(Score,''%'') When 0 then 0 ELSE 1 END , Score'
Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: Tricky SQLite sort
« Reply #7 on: August 12, 2016, 01:07:33 am »
Sorry didn't pay attention to Post's Tilte (SQLite)  :-[

anyway this will work (tested) http://sqliteonline.com/#fiddle-57ad04f9f393bf53e02a54f567fe058c418d6d161bf7f45475

Code: MySQL  [Select][+][-]
  1. FROM DataTable
  2. ORDER BY instr(Score, "%")<>0, Cast( replace(Score, "%", "") AS REAL)
  3.  
« Last Edit: August 12, 2016, 01:18:43 am by shobits1 »

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 630
    • Double Dummy Solver - free download
Re: Tricky SQLite sort
« Reply #8 on: August 12, 2016, 01:39:56 am »
Very nice shobits1

When I run your code in my Laz app, I get an error message: no such function :  instr

BUT when I run your code in "DB Browser for SQLite", version 3.8.0, it works perfectly. That app uses SQLite version 3.9.2

It seems I need a new version of SQLite for my Laz 1.6.  So I downloaded the latest version of SQLite3.dll, put in in my app's folder, and ALL IS WELL.

THANK YOU.
« Last Edit: August 12, 2016, 01:57:02 am by bobonwhidbey »
Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: Tricky SQLite sort
« Reply #9 on: August 12, 2016, 02:26:12 am »
According to the SQLite site instr function was added back in 2012 (v3.7.15) so you are using a very old version,, as to what you need to do is to download the last dll version and copy it to the lazarus directory and to you application project (where the exe file).

Also, you may need to upgrade your database file, if you don't have any important data then I advice to create new database with the latest sqlite.

useful links:
https://www.sqlite.org/download.html
http://www.sqlite.org/changes.html
https://www.sqlite.org/cli.html
http://stackoverflow.com/questions/3424156/upgrade-sqlite-database-from-one-version-to-another

 

TinyPortal © 2005-2018