Grupowanie po dwóch kolumnach

0

Mam taki problem mam kilka tabel i w tych tabelach wszystko jest w miarę dobrze, ale w momencie jak do danego nastroju jest przydzielona liczba akcji większa niż jedna to traktuje dany rekord jak dwa np. jest nastrój i to niego są przydzielone dwie akcji to automatycznie ten rekord jest traktowany jako dwa rekordy i to da w konsekwencji inną wartość nastroju bo jak jest grupowany wg daty to będzie inna wartość nastroju (bo zliczy ten nastrój jako dwa ) i będzie tez inna wartość count() o jeden większa w przypadku dwóch nastrjów dla jednego jest jedna akcja a dla drugiego są dwie akcje.

Tabela wygląda tak.

tabela moods.

id date_start date_end level_mood Nagłówek 2
1 2019-12-12 1200 2019-12-12 1400 5
2 2019-12-12 1400 2019-12-12 1600 -5
3 2019-12-12 1600 2019-12-12 1600 5

tabela moods_actions

id id_mood id_actions
1 1 1
2 2 2
3 3 3
4 3 4

tabela actions

id name
1 ten
2 tos
3 tak
4 nein

I teraz jak w wyniku na stronie grupuje do wg daty Y-m-d

To ma pokazac na stronie

data level_mood count
2019-12-12 2.5 4

A powinno być coś takiego

data level_mood count
2019-12-12 1.66 3

I teraz nie wiem czy jest sens pokazania kodu źródłowego, jak będzie tAKA KONIECZNOŚć to pokażę, dodam tylko, że w zapytanie grupuję to wg daty bo muszę to pogrupować wg daty natomiast jak jeszcze grupuje to wg pola . moods.id to wtedy nie grupuje to wg daty i nie wiem co trzeba zrobić, żeby pogrupowało to jednoczesnie po tych dwóch polach ?

Kod MySQL to

select sum(TIMESTAMPDIFF (minute, moods.date_start , moods.date_end)) as longMood, round((sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_mood) / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) ),3 )as level_mood , round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_anxiety) / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_anxiety , round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_nervousness ) / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_nervousness , round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_stimulation) / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_stimulation , (count(moods.id ) ) as count, min(moods.date_start) minMood, max(moods.date_end) maxMood, (DATE(IF(HOUR( moods.date_start) >= '5', moods.date_start,Date_add(moods.date_start, INTERVAL - 1 DAY) )) ) as datStart , (DATE(IF(HOUR( moods.date_end) >= '5', moods.date_end,Date_add(moods.date_end, INTERVAL - 1 DAY) )) ) as datEnd from `moods` left join `moods_actions` on `moods_actions`.`id_moods` = `moods`.`id` left join `actions` on `actions`.`id` = `moods_actions`.`id_actions` where `moods_actions`.`id` != and `moods`.`id_users` = 1 and `moods`.`type` = mood group by (DATE(IF(HOUR( moods.date_end) >= '5', moods.date_end,Date_add(moods.date_end, INTERVAL - 1 DAY) ))) order by `moods`.`date_end` desc)
0
select trim(czas), sum(levelek) / count(*) level_mood, count(*) 
  from test
 group by czas

czy ja tu czegoś nie ogarniam?

http://sqlfiddle.com/#!9/2ac988/4

0

@woolfik: Ale są jeszcze dwie inne tabele

0

@tomixtomi0001: weź teraz zobacz poprawiłem.

http://sqlfiddle.com/#!9/31a17c/1

0

Albo ja nie rozumiem ciebie albo ty mnie. Poprosiłeś o zadany wynik wiec jak rozumiem z tabeli moods bierzesz sumę level-moods i dzielisz przez count aby uzyskać co chcesz pozostałe tabele nie są potrzebne aby uzyskać ten efekt. Moods_actions to jak rozumiem tabela spięcia między actions i moods ale co z tych actions mam wyciągnąć i jak to zsumowac/podzielic aby uzyskać level_moods? Tego nie kumam kompletnie z tej struktury tabel. Po co ci te actions aby co z nimi zrobić?

0

No bo to jest potrzebne w wyszukiwaniu po nazwie akcji albo po tym, że musi nastrój posiadać jakąs akcje.

0

No dobrze ale dalej nie podajesz jak chcesz to uzyskać? Jak to policzyć .... przykładowo ktoś podaje, że co? Chce policzyć level_mood w dniu 2019-12-12 w godzinach między 1200 a np 1200 dla akcji = nein? O to chodzi? Napisałeś że masz tabele, że masz taki a taki wynik, a potrzebujesz inny więc na podstawie danych podałem Ci wynik, który chciałeś, teraz mówisz o jakimś wyszukiwaniu. Jak w pełni nie powiesz o co Ci chodzi to nie będę w stanie Ci podpowiedzieć jak masz to zrobić.

Natomiast co do counta ... no to tutaj trzeba pokombinować bo jak robisz select z 1 tabeli to count będzie sumą rekordów z tej 1 tabeli. Jak natomiast zrobisz zwykły join (bez kombinowania) do drugiej tabeli I TA TABELA JEST W RELACJI 1 DO WIELU Z TABELA nr 1 to tutaj zawsze Ci się count zwiększy właśnie o tą ilość WIELE oczywiście można to odpowiednio ograniczyć używając złożonych warunków, cts'ów, warunków where itd ale nie znając DOKŁADNIE potrzeby nie mogę Ci podać rozwiązania, a z Twoich przykładów i opisów takiej potrzeby nie widzę

0

Całą idea tego wyszukiwania jest taka, żeby wyszukać nastroje w okręslonych data poziomach nastroju, ale ja bym chciAŁ OMÓWIĆ tylko te kryteria, które są potrzebne teraz do wytłumaczenia i do sporządzenia algorytmu.

Jest sobie panel wyszukiwania i w tym panelu jest dodatkowa opcja grupuj wg dnia i wszystko działa dobrze w momencia jak do nastroju jest przyporządkowana tylko jedna akcja lub nie ma żadnej, ale w monecie jak jest >= 2 akcje to dany rekord bierze jako dwa rekordy. Ja może dam kod źródłowy.

$startDay = $this->startDay;
         $moodModel = new  MoodModel;
         $bool = $this->searchAction($request->get("action"));
         $moodModel->createQuestionGroupDay($this->startDay,$bool,$request->get("ifAction"));

         if (($request->get("ifAction")) == "on" ) {
             $moodModel->groupMoodAction();
         }
         if (!empty($request->get("action")) and ($request->get("action") != "undefined") ) {

             $moodModel->searchActionGroup($request->get("action"),(array)$request->get("actionFrom"),(array)$request->get("actionTo"));
         }
 



         $moodModel->setGroupDay(Auth::User()->start_day);

      


         $this->count = $moodModel->questions->get()->count();
         return $moodModel->questions->paginate(15);

Teraz kod funkcji modelu

    public function createQuestionGroupDay(int $startDay,bool $ifAction,$actionOn) {
        $this->questions =  self::query();


            $this->questions
                ->selectRaw("sum(TIMESTAMPDIFF (minute, moods.date_start , moods.date_end)) as longMood")
                //->selectRaw("sum(moods.level_mood)  as level_mood")
                ->selectRaw(" round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_mood)  / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_mood ")
                ->selectRaw(" round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_anxiety)  / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_anxiety ")
                ->selectRaw(" round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_nervousness )  / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_nervousness ")
                ->selectRaw(" round(sum( ( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ) * moods.level_stimulation)  / sum( unix_timestamp(moods.date_end) - unix_timestamp(moods.date_start) ),3 ) as level_stimulation ")
            ->selectRaw("(count(moods.id ) ) as count")

            ->selectRaw("min(moods.date_start) minMood")

            ->selectRaw("max(moods.date_end) maxMood")
            ->selectRaw(DB::Raw("(DATE(IF(HOUR(    moods.date_start) >= '" . $startDay . "', moods.date_start,Date_add(moods.date_start, INTERVAL - 1 DAY) )) ) as datStart " ))
            ->selectRaw(DB::Raw("(DATE(IF(HOUR(    moods.date_end) >= '" . $startDay . "', moods.date_end,Date_add(moods.date_end, INTERVAL - 1 DAY) )) ) as datEnd" ));
//        if ($ifAction == true or $actionOn == "on") {
//            $this->questions->crossjoin("moods_actions","moods_actions.id_moods","moods.id");
//            //->join("actions","actions.id","moods_actions.id_actions");
//
//        }
    }



    public function groupMoodAction() {
    $this->questions->whereExists(function ($query) {
        $query
            ->select(DB::raw(1))
            ->from('moods_actions')
            ->whereColumn('moods_actions.id_moods', 'moods.id');
    });
    //$this->questions->groupBy("moods_actions.id_actions");
}




public function searchActionGroup(array $action,array $actionFrom,array $actionTo)
{

    $this->questions->whereExists(function ($query) use ($action, $actionFrom, $actionTo) {
        $query
            ->select(DB::raw(1))
            ->from('actions');
        for ($i = 0; $i < count($action); $i++) {
            if ($action[$i] == "NULL") {
                continue;
            }
            if ($action[$i] != "" and (!empty($actionFrom) and (!empty($actionTo))) and ($actionFrom[$i] != "" and $actionTo[$i] != "")) {
                $query->orwhereRaw("("
                    . "actions.name like '%" . $action[$i] . "%'  and  (" .
                    "(CASE "
                    . " WHEN moods_actions.percent_executing is NULL && moods_actions.minute_exe is  NULL THEN (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) ) "
                    . " WHEN moods_actions.minute_exe is NOT NULL  THEN (moods_actions.minute_exe)    "
                    . " WHEN moods_actions.percent_executing is NOT NULL THEN     (  moods_actions.percent_executing / 100) * (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) )  "
                    . " "
                    . " END)  >='" . $actionFrom[$i] . "')"
                    . "and ("
                    . "(CASE "
                    . " WHEN moods_actions.percent_executing is NULL && moods_actions.minute_exe is  NULL THEN (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) ) "
                    . " WHEN moods_actions.minute_exe is NOT NULL  THEN (moods_actions.minute_exe)    "
                    . " WHEN moods_actions.percent_executing is NOT NULL THEN     (  moods_actions.percent_executing / 100) * (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) )  "
                    . " "
                    . " END)  <='" . $actionTo[$i] . "')"
                    . ""
                    . ")"

                );

            } else if ($action[$i] != "" and ((!empty($actionTo))) and ($actionTo[$i] != "")) {
                $query->orwhereRaw("("
                    . "actions.name like '%" . $action[$i] . "%'  and  (("
                    . " CASE "
                    . " WHEN moods_actions.percent_executing is NULL && moods_actions.minute_exe is  NULL THEN (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) ) "
                    . " WHEN moods_actions.minute_exe is NOT NULL  THEN (moods_actions.minute_exe)    "
                    . " WHEN moods_actions.percent_executing is NOT NULL THEN     (  moods_actions.percent_executing / 100) * (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) )  "
                    . ""
                    . " END)"
                    . ")  <= '" . $actionTo[$i] . "')"
                    . " ");
            } else if ($action[$i] != "" and (!empty($actionFrom)) and ($actionFrom[$i] != "")) {
                $query->orwhereRaw("("
                    . "actions.name like '%" . $action[$i] . "%'  and  (("
                    . " CASE "
                    . " WHEN moods_actions.percent_executing is NULL && moods_actions.minute_exe is  NULL THEN (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) ) "
                    . " WHEN moods_actions.minute_exe is NOT NULL  THEN (moods_actions.minute_exe)    "
                    . " WHEN moods_actions.percent_executing is NOT NULL THEN     (  moods_actions.percent_executing / 100) * (TIMESTAMPDIFF(minute,moods.date_start,moods.date_end) )  "
                    . " "
                    . " END)"
                    . ")  >= '" . $actionFrom[$i] . "')"
                    . " ");
            } else if ($action[$i] != "") {

                $query->orwhereRaw("actions.name like '%" . $action[$i] . "%'");
            }


        }
    });
}



public function setGroupDay(int $startDay) {
    $this->questions->groupBy(DB::Raw("(DATE(IF(HOUR(    moods.date_end) >= '" . $startDay . "', moods.date_end,Date_add(moods.date_end, INTERVAL - 1 DAY) ))) "));
}

I generalnie wcześniej nie miałem tej funkcji groupMoodAction (ta funkcja daje nam zapytanie w zapytaniu ) po jej dodaniu uwzględnia to ale teraz za to nie działa wyszukiwanie po nazwie akcji czyli funkcja searchActionGroup w momencie kiedy jest dana nazwa funkcji w którymś rekordzie to zwróci wszystkie rekordy które mają jakąś przypisaną akcje a nie tylko te które mają taką nazwę, ale co ciekawe jak wpisze nazwę akcji której nie ma żaden nasatrój to nic nie wyszuka.

Generalnie teraz tylko z tym mam problem czyli wyszukiwanie po nazwie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1