1

Temat: Wynik dzielenia 6/24, godziny nocne

Witam
select cast(6/24 as numeric)
select 6/24

dają w wyniku 0 zamiast 0,25, wie ktoś może dlaczego?

select 24/6 działa normalnie i daje wynik 4

W ogóle to potrzebuje policzyć godziny nocne z przepracowanego czasu od do, może ktoś robił coś takiego.

Z góry dzięki za pomoc
Adam

2

Odp: Wynik dzielenia 6/24, godziny nocne

To podstawowy błąd wynikający z niezrozumienia konwersji typów jakie dokonuje komputer w twoim przypadku maszyna zakłada, że skoro dzieli dwie liczby integer to wynik też musi być integer i nawet jak go przekonwertujesz na numeric to dostajesz wynik już przekonwertowany. Popatrz poniżej

select 6/24,cast(6/24 as numeric),6/24.0,cast(6/24.0 as numeric)

musisz więc dokonaj konwersji jawnej

select 6/24::double precision, cast(6/24::double precision as numeric)

Ostatnio edytowany przez c_michal (2013-02-27 18:35:52)

3

Odp: Wynik dzielenia 6/24, godziny nocne

Dzięki, działa
MsAccess działa trochę inaczej

Pozdrawiam
Adam

4

Odp: Wynik dzielenia 6/24, godziny nocne

Witam ponownie
Mam tabele i w niej pola czas_wyjscia,czas_wejscia typu time

SELECT  least(czas_wyjscia,czas_wejscia)
  from  tabela;
 
Działa
---------------------------
   
   SELECT case when cast(czas_wejscia as time) < cast('06:00:00' as time) then
            2  ELSE 1 end as n1
   from  tabela;

Działa
---------------------------

   SELECT czas_wejscia<'06:00:00' then
            2  ELSE 1 end as n1
   from  tabela;

Działa
---------------------------

   SELECT case when cast(czas_wejscia as time) < cast('06:00:00' as time) then
           least(czas_wyjscia,czas_wejscia) ELSE 1 end as n1
       from  tabela;

Nie działa, błąd:
ERROR:  CASE types integer and time without time zone cannot be matched
LINE 1: ..._wejscia as time) < cast('06:00:00' as time) then least(czas...

Nie mam pojęcia dlaczego osobno działa, a razem nie. Może ktoś mi podpowie
Z góry dzięki za pomoc
Adam

5

Odp: Wynik dzielenia 6/24, godziny nocne

Każdą kolumna musi mieć jakiś typ danych, a w Twoim przypadku po THEN zwracasz time, a po ELSE 1 czyli integer. Zmień typ danych na takich sam, a wszystko będzie działało

6

Odp: Wynik dzielenia 6/24, godziny nocne

Dzięki, działa

Mam jeszcze taki problem, potrzebuje uzyskać ilość dni z godzin

SELECT  sum(czas_wyjscia) as czas,  extract(hours from sum(czas_wyjscia)) as godziny,
  extract(minutes from sum(czas_wyjscia)) as minuty,  extract(seconds from sum(czas_wyjscia)) as sekundy,
  extract(hours from sum(czas_wyjscia))/24 as dni,  extract(days from sum(czas_wyjscia)) as dni2 ,
   sum(czas_wyjscia)/24 as dni3,  justify_hours(interval '5561 hours') as _dni_5561
   from  tabela

Wynik
czas                   godziny      minuty      sekundy     dni                            dni2           dni3     
5561:10:37       5561          10                  37          237,7083333333       0            231:42:56:541667

dni_5561
231 days 17:00:00

Wynik  dni_5561 mnie satysfakcjonuje, ale jest on uzyskany na sztywno z funkcji --  justify_hours(interval '5561 hours')
Chce go uzyskać dynamicznie  --  justify_hours(interval 'extract(hours from sum(czas_wyjscia)) || hours ')  ale dostaje błąd

ERROR:  syntax error at or near "extract"
LINE 1: ...61 hours') as _dni_5561 ,justify_hours(interval ''extract(ho...

Nie wiem jak to ugryźć, może jest jakieś inne rozwiązanie

Jakoś czasu nie mogę zakumać, wynik dni i dni3 to już całkiem dziwny

7

Odp: Wynik dzielenia 6/24, godziny nocne

zobacz poniższy przykład (niby to samo a jednak co innego) poczytaj helpa o zapisie bitowym zmiennych typu interval
with tabela as (select '23:10:10'::time as czas_wyjscia union all
                select '23:11:01'::time as czas_wyjscia
                )
SELECT
sum(czas_wyjscia) as czas_przed_konwersja
,justify_hours(sum(czas_wyjscia)) as czas_po_konwersji
,extract(days from justify_hours(sum(czas_wyjscia))) as dni
,extract(hours from justify_hours(sum(czas_wyjscia))) as godziny
,extract(minutes from justify_hours(sum(czas_wyjscia))) as minuty
,extract(seconds from justify_hours(sum(czas_wyjscia))) as sekundy
   from  tabela

8

Odp: Wynik dzielenia 6/24, godziny nocne

Wielkie dzięki
Mała podpowiedź, a jaki krok do przodu

Pozdrawiam
Adam

9

Odp: Wynik dzielenia 6/24, godziny nocne

Witam
Mam jeszcze takie pytanie
Kiedy zakomentuję linię nr 3 to jest ok
Kiedy zakomentuje linię nr 2 zamiast 3 to już wynik funkcji jest błędny, sprawdzałem ,że linia nr 3 i 2 zwracają to samo
Jednak w funkcji nie wiem dlaczego wynik końcowy jest różny w zależności czy zakomentowana jest linia nr 2 czy 3
Chciałbym zastąpić linię nr 2 linią nr 3 w funkcji

Do funkcji podaję wartość z tabeli np '2011-07-01 08:00:52'

CREATE OR REPLACE FUNCTION funkcja (
  zm_od_kiedy timestamp
)
RETURNS TIME WITHOUT TIME ZONE AS
$body$
     declare
      zmw_data_od_kiedy date;
      zmw_czas_od_kiedy TIME;

  begin

    zmw_data_od_kiedy = CAST(zm_od_kiedy as date);  ---linia 1
    zmw_czas_od_kiedy = zm_od_kiedy - zmw_data_od_kiedy;---linia 2
    zmw_czas_od_kiedy = CAST(zm_od_kiedy as TIME);---linia 3

.........


Pozdrawiam
Adam

Ostatnio edytowany przez adamleon (2013-03-08 15:23:23)

10

Odp: Wynik dzielenia 6/24, godziny nocne

u mnie działa w obu przypadkach (założyłem, że funkcja ma zwrócić wynik funkcji zmw_czas_od_kiedy) , może załącz dalszą część funkcji bo nie widzę problemu
PS
Podejście z linii 3 jest jak najbardziej OK. Może to jakiś problem z konwersją typu zauważ, że timestamp-date w wyniku daje interval, a nie time jak by się wydawało

11

Odp: Wynik dzielenia 6/24, godziny nocne

Może to i ten interval

Cała funkcja

CREATE OR REPLACE FUNCTION fgodziny_dzienne (
  zm_od_kiedy timestamp,
  zm_do_kiedy timestamp
)
RETURNS TIME WITHOUT TIME ZONE AS
$body$
     declare
      zmw_od_kiedy_dzienne TIME;
      zmw_od_kiedy_nocne TIME;
      wynik_funkcji TIME;
      zmw_data_od_kiedy date;
      zmw_data_do_kiedy date;
      zmw_czas_od_kiedy TIME;
      zmw_czas_do_kiedy TIME;

  begin

wynik_funkcji = cast('00:00:00' as time);

      zmw_od_kiedy_dzienne:=cast('06:00:00' as time);  ----poczatek dnia
        zmw_od_kiedy_nocne:=cast('22:00:00' as time);  ---poczatek nocnych

    zmw_data_od_kiedy = CAST(zm_od_kiedy as date);
    zmw_data_do_kiedy = CAST(zm_do_kiedy as date);

    zmw_czas_od_kiedy = zm_od_kiedy - zmw_data_od_kiedy;
    zmw_czas_do_kiedy = zm_do_kiedy - zmw_data_do_kiedy;
   
   ---zmw_czas_od_kiedy = CAST(zm_od_kiedy as TIME);
  ---- zmw_czas_do_kiedy = CAST(zm_od_kiedy as TIME);
   
    If zmw_data_od_kiedy = zmw_data_do_kiedy Then
        If zmw_czas_od_kiedy >= zmw_od_kiedy_nocne Then
            ElseIf zmw_czas_do_kiedy < zmw_od_kiedy_dzienne Then
            ElseIf zmw_czas_od_kiedy >= zmw_od_kiedy_dzienne And zmw_czas_do_kiedy <= zmw_od_kiedy_nocne Then 
                wynik_funkcji = zmw_czas_do_kiedy - zmw_czas_od_kiedy;
            ElseIf zmw_czas_od_kiedy >= zmw_od_kiedy_dzienne And zmw_czas_do_kiedy > zmw_od_kiedy_nocne Then 
                wynik_funkcji = zmw_od_kiedy_nocne - zmw_czas_od_kiedy;
            ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_nocne Then   
                wynik_funkcji = zmw_czas_do_kiedy - zmw_od_kiedy_dzienne;
            ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_dzienne And zmw_czas_do_kiedy > zmw_od_kiedy_nocne Then   
                wynik_funkcji = cast('12:00:00' as time);
        End If;
    Else
        If zmw_czas_od_kiedy > zmw_od_kiedy_nocne And zmw_czas_do_kiedy < zmw_od_kiedy_dzienne Then 
        ElseIf zmw_czas_od_kiedy > zmw_od_kiedy_nocne And zmw_czas_do_kiedy > zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_nocne Then
            wynik_funkcji = zmw_czas_do_kiedy - zmw_od_kiedy_dzienne;
        ElseIf zmw_czas_od_kiedy > zmw_od_kiedy_nocne And zmw_czas_do_kiedy > zmw_od_kiedy_nocne Then
            wynik_funkcji = cast('12:00:00' as time);
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_nocne And zmw_czas_od_kiedy > zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_dzienne Then
            wynik_funkcji = zmw_od_kiedy_nocne - zmw_czas_od_kiedy;
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_nocne And zmw_czas_od_kiedy > zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_nocne Then
            wynik_funkcji = zmw_od_kiedy_nocne - zmw_czas_od_kiedy + zmw_czas_do_kiedy - zmw_od_kiedy_dzienne;
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_dzienne And zmw_czas_do_kiedy > zmw_od_kiedy_nocne Then
            wynik_funkcji = cast('23:59:59' as time);
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_dzienne And zmw_czas_do_kiedy > zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_nocne Then
            wynik_funkcji = cast('12:00:00' as time) + zmw_czas_do_kiedy - zmw_od_kiedy_dzienne;
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_nocne And zmw_czas_do_kiedy > zmw_od_kiedy_nocne Then
            wynik_funkcji = zmw_od_kiedy_nocne - zmw_czas_od_kiedy + cast('12:00:00' as time);
        ElseIf zmw_czas_od_kiedy < zmw_od_kiedy_dzienne And zmw_czas_do_kiedy < zmw_od_kiedy_dzienne Then   
            wynik_funkcji = cast('12:00:00' as time);
        End If;
    End If;


    return wynik_funkcji;


  end;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY DEFINER
COST 100;

12

Odp: Wynik dzielenia 6/24, godziny nocne

13

Odp: Wynik dzielenia 6/24, godziny nocne

Dzięki, nie ma to jak świeże spojrzenie

Już kilka razy "barowałem" się z takimi błędami.