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

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