Avatar billede side1 Novice
21. november 2010 - 17:09 Der er 10 kommentarer og
1 løsning

Find nærmeste værdi under

jeg har brug for at finde nærmeste værdi til en tid. Jeg har f.eks. følgende værdier i databasen.

19:35
20:00
21:25
21:45
23.30

Jeg vil så finde værdier over 19:45, så jeg siger den skal finde over 19.45 (f.eks. WHERE tid>19.45), og den finder 20:00, 21:25, 21:45, 23.30.

Men jeg vil gerne have den skal tage 19:35 med. Hvordan får jeg den til at tage nærmeste værdi, der ligger under med.


I need to find a value in the database that is the nearest to a given value. It can be greater than, less than or equal to.

So, for example:

Values: 40, 42, 45, 48, 51, 53, 55, 58

Select the nearest value to 50. Obviously in the above example it would be 51. However, with this series:

Values: 40, 42, 45, 48, 53, 55, 58, 60

Now, the nearest value is 48.

How do I do that?
Avatar billede webweaver Praktikant
21. november 2010 - 17:15 #1
Er tiden altid 19.35?

Så kunne det være,
... WHERE tid = '19.35 AND WHERE tid > '19.45' ....
Avatar billede arne_v Ekspert
21. november 2010 - 17:26 #2
for heltal:

SELECT *
FROM dintabel
WHERE val = (SELECT MIN(ABS(val-X)) FROM dintabel)

for tid:

SELECT *
FROM dintabel
WHERE tid = (SELECT MIN(TIMESTAMPDIFF(SECOND,tid,X)) FROM dintabel)
Avatar billede side1 Novice
21. november 2010 - 17:33 #3
Jeg kan ikke rigtig få det til at virke den siger

Query failed : Unknown column 'X' in 'field list'
Avatar billede arne_v Ekspert
21. november 2010 - 17:45 #4
X er den værdi du leder efter det nærmeste til!
Avatar billede side1 Novice
21. november 2010 - 17:52 #5
Hvis jeg har forstået det rigtig, så skal jeg skrive det sådan

sql=SELECT * FROM tabel WHERE tid = (SELECT MIN(TIMESTAMPDIFF(SECOND,tid,'19:50')) FROM tabel)

Men det giver 0 resultater, selv om jeg altså har værdierne:

19:35
20:00
21:25
21:45
23.30
Avatar billede arne_v Ekspert
21. november 2010 - 18:00 #6
prøv:

sql=SELECT * FROM tabel WHERE TIMESTAMPDIFF(SECOND,tid,'19:50') = (SELECT MIN(TIMESTAMPDIFF(SECOND,tid,'19:50')) FROM tabel)
Avatar billede side1 Novice
21. november 2010 - 18:14 #7
Virker heller ikke, den siger heller ikke fejl, så koder er nok rigtig.
Avatar billede arne_v Ekspert
21. november 2010 - 18:16 #8
så prøv med ABS på:

sql=SELECT * FROM tabel WHERE ABS(TIMESTAMPDIFF(SECOND,tid,'19:50')) = (SELECT MIN(ABS(TIMESTAMPDIFF(SECOND,tid,'19:50'))) FROM tabel)
Avatar billede side1 Novice
21. november 2010 - 18:25 #9
Give heller ikke noget resultat. Spørgsmålet er om man kan gå en anden vej. Jeg har ingen problemer med at finder værdierne over med:

WHERE tid > '19.45' ....

Jeg kunne så bare lave dette ekstra kald

WHERE tid < '19.45 limit 1

Jeg skal jo bare finde den første værdi der er under 19.45

Men det er ikke særligt elegant at bruge 2 kald på det. Kan man samle det til et kald, i stedet for at lave 2 kald?
Avatar billede arne_v Ekspert
22. november 2010 - 02:30 #10
Der er tilsyneladende tsore problemer i MySQL med TIME's som bliver konverteret til meget tidlige DATETIME's.

Men prøve denne her variant:

mysql> CREATE TABLE timefun (
    ->    id INTEGER NOT NULL PRIMARY KEY,
    ->    t TIME
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> INSERT INTO timefun VALUES(1, '19:35');
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO timefun VALUES(2, '20:00');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO timefun VALUES(3, '21:25');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO timefun VALUES(4, '21:45');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO timefun VALUES(5, '23:30');
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT *
    -> FROM timefun;
+----+----------+
| id | t        |
+----+----------+
|  1 | 19:35:00 |
|  2 | 20:00:00 |
|  3 | 21:25:00 |
|  4 | 21:45:00 |
|  5 | 23:30:00 |
+----+----------+
5 rows in set (0.00 sec)

mysql>
mysql> SELECT *
    -> FROM timefun
    -> WHERE ABS(UNIX_TIMESTAMP(CONCAT('2000-1-1 ',t))-UNIX_TIMESTAMP(CONCAT('2000-1-1 ','19:50')))
    -> = (SELECT MIN(ABS(UNIX_TIMESTAMP(CONCAT('2000-1-1 ',t))-UNIX_TIMESTAMP(CONCAT('2000-1-1 ','19:50')))) FROM timefun);
+----+----------+
| id | t        |
+----+----------+
|  2 | 20:00:00 |
+----+----------+
1 row in set (0.00 sec)

mysql>
mysql> DROP TABLE timefun;
Query OK, 0 rows affected (0.01 sec)
Avatar billede arne_v Ekspert
27. december 2010 - 00:26 #11
OK?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester