Záznam nejblíže zadanému času – MySQL – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Záznam nejblíže zadanému času – MySQL – Fórum – Programujte.comZáznam nejblíže zadanému času – MySQL – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
hlucheucho+10
Posthunter
10. 5. 2016   #1
-
0
-

Ahoj,

potřebuji z dočasné tabulky temp ( cas datetime(3), hodnota float) vybrat záznam u kterého je hodnota ve sloupci cas nejblíže zadané hodnotě. Zatím jsem přišel na těžkopádné (možná i správné) řešení:

@c = '2016-05-07 13:44:55';  /*zadany cas*/

select min(abs(timediff(@c, cas))) into @d from temp;
select cas, hodnota from temp where abs(timediff(@c, cas)) = @d;

Intuitivně tuším, že existuje "učesanější" řešení. Jaké? Dlouhé hodiny se mi na to nedaří přijít. :(

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Reklama
Reklama
P
~ Anonymní uživatel
193 příspěvků
11. 5. 2016   #2
-
0
-

Nic moc lepsiho asi nevymyslis. Trochu to "ucesat" lze: 

@c = '2016-05-07 13:44:55';  /*zadany cas*/

SELECT cas, hodnota
FROM temp
WHERE ABS(TIMEDIFF(@c, cas)) = (
          SELECT MIN(ABS(TIMEDIFF(@c, cas))) FROM temp
      )
ORDER BY cas
LIMIT 1

Limit je tam proto, kdyby zadany cas lezel presne v polovine mezi 2 zaznamy. Pak lze pomoci ORDER BY Cas [DESC] urcit, jestli se ma vzit ten drivejsi nebo pozdejsi.

Nahlásit jako SPAM
IP: 85.93.116.–
P
~ Anonymní uživatel
193 příspěvků
11. 5. 2016   #3
-
0
-

Kdyby byl problem s vykonem (funkce v podmince), slo by to jeste takto: 

SELECT cas, hodnota
FROM temp
WHERE cas = (
	SELECT	CASE
			WHEN mensi IS NULL THEN vetsi
			WHEN vetsi IS NULL THEN mensi
			WHEN TIMEDIFF(mensi, cas) > TIMEDIFF(cas, vetsi) THEN vetsi
			ELSE mensi
		END
	FROM (
		  SELECT @c AS cas
		, (SELECT MAX(cas) FROM temp WHERE cas <= @c) AS mensi
		, (SELECT MIN(cas) FROM temp WHERE cas >= @c) AS vetsi
	) q
)
Nahlásit jako SPAM
IP: 85.93.116.–
hlucheucho+10
Posthunter
11. 5. 2016   #4
-
0
-

Dočasná tabulka má několik omezení -  mimo jiné nelze na ní učinit poddotaz nebo ji spojit samu se sebou. Asi mi nezbude nic jiného, než z toho udělat jednoduchou proceduru (jestli to na dočasné tabulce půjde) aby každé volání nebylo jak kopírování románu.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
hlucheucho+10
Posthunter
12. 5. 2016   #5
-
0
-

udělal jsem to jako proceduru

drop procedure if exists ZaokrouhliCas;

delimiter //

create procedure ZaokrouhliCas(inout ncas datetime(3), inout nhodnota double)
  begin
    insert temp (cas, hodnota) values (ncas, nhodnota);      /*vlozi nejnovejsi hodnotu do docasne tabulky*/
    delete from temp where cas < (ncas - interval 20 second);      /*odstrani starsi hodnoty, historie 6 sec postacuje*/
    select (max(zaokrouhleno) - interval 3 second) into ncas from temp;  /*ncas = cas ke kteremu se hleda nejblizsi*/
    select min(abs(timediff(ncas, cas))) into @d from temp;              /*@d = nejmensi diference od pozadovaneho casu*/
    select hodnota into nhodnota from temp where abs(timediff(ncas, cas)) = @d limit 1;
  end;
  //
  
 delimiter ;


jejímu prvnímu volání předchází

create temporary table if not exists temp (cas datetime(3), hodnota float, zaokrouhleno datetime as (cas));


a samotná práce pak 

START TRANSACTION; set @v = ?napeti; set @c = ?cas; call ZaokrouhliCas(@c, @v); insert leva_teploty (cas, teplota) values (@c, TcVoltToTherm(?TcType, @v)) on duplicate key update teplota = teplota; COMMIT;


kde jména začínající otazníkem jsou parametry. Aplikace používá .NET Conector. Když data vkládá aplikace nepravidelně dojde k vynechání záznamu v tabulce leva_teploty. Čas a hodnota aplikace ukládá ještě do jiné tabulky (pomocný log pro hledání příčiny), kde k žádnému vynechání záznamu nedochází. V aplikaci nedojde k vyjímce. Pokud vezmu časový úsek asi 10 sec okolo vynechaného záznamu a provedu skript pro každý záznam z logu ručně, k vynechání záznamu taky nedojde. Zpočátku jsem to neprováděl jako transakci, chování bylo stejné. Jak odhalit příčinu tohoto chování?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Kit+11
Guru
12. 5. 2016   #6
-
0
-

#1 hlucheucho

@c = '2016-05-07 13:44:55';  /*zadany cas*/
SELECT cas, hodnota, abs(timediff(@c, cas)) AS diff FROM temp
    ORDER BY diff LIMIT 1;
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 16 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý