linq to sql - year,month

linq to sql - year,month
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Mam problem z jednym zapytaniem SQL, przerabiam do linq ale nie bardzo wiem jak poradzić sobie z klauzulami YEAR,MONTH:
SQL:

Kopiuj
SELECT MONTH(DATA),AVG(temp) AS srednia FROM `tabela` WHERE miejsce = 'M1' GROUP BY YEAR(DATA),MONTH(DATA) ORDER BY srednia DESC LIMIT 1

próba w linq:

Kopiuj
from z in tabela where z.Miejsce =="M1" group date by new { date.Year, date.Month }

Prosze o pomoc. Generalnie chodzi o to aby pobrać miesiąc z najwyższą średnią temperaturą. Poniżej tabela:

edytowany 3x, ostatnio: Sebastiano
Zobacz pozostały 1 komentarz
Sebastiano
faktycznie, już zmieniam
Sebastiano
a jak ze średnią w tym przypadku sobie poradzić?
dam1an
Jak byś podał przykładową tabele z danymi to mógłbym się z tym pobawić.
Sebastiano
Jasne:) Już wrzuciłem.
Sebastiano
Jak licze całą średnią to robie to tak: var i = (from z in tabela where z.Miejsce== "M1" select z.Temp).Average(); - ale nie wiem jak całe zapytanie poskładać
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
1

Wyszły mi takie potworki. Trochę na czuja:

Kopiuj
         var result = (from z in se.Wiatrs
            where z.miejsce == "M1"
            group z.data by new {z.data.Year, z.data.Month} into g
            select new
            {
             Miesiac = g.Key.Month,
             Srednia = (from z in se.Wiatrs
             where z.miejsce == "M1"
             select z.temp).Average(x=>x)
            }).OrderBy(x => x.Srednia).First();
// LUB
         var result = (se.Wiatrs.Where(z => z.miejsce == "M1")
            .GroupBy(z => new {z.data.Year, z.data.Month}, z => z.data)
            .Select(g => new
            {
               Miesiac = g.Key.Month,
               Srednia = (se.Wiatrs.Where(z => z.miejsce == "M1").Select(z => z.temp)).Average(x => x)
            })).OrderBy(x => x.Srednia).First();

Yubby dibby dibby dibby dibby dibby dibby dum..
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Dzięki za 2 rozwiązania. Tylko coś nie działa do końca, testowałem też pod linqPadem i czepia się Year i Month. Poniżej screen z VS:

edytowany 1x, ostatnio: Sebastiano
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0

A jak dasz group z.data by new { z.data.Value.Year, z.data.Value.Month }
Albo inaczej jakiego typu masz z.data?


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

baza MySql typ 'data'

DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0

To powinno zdziałać po stronie C# powinno być z mapowanie do DateTime. Nie wiem skąd wynika ten błąd.


Yubby dibby dibby dibby dibby dibby dibby dum..
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0
DibbyDum napisał(a):

To powinno zdziałać po stronie C# powinno być z mapowanie do DateTime. Nie wiem skąd wynika ten błąd.

W ten sposób jest w porządku:)

Kopiuj
 group z.data by new { z.data.Value.Year, z.data.Value.Month } into g

Tylko nie wiedzieć czemu dostaje NULLa na wyjściu;/ Ale to raczej wynika z tego że źle się łącze z bazą..

EDIT: Już działa:)

edytowany 2x, ostatnio: Sebastiano
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0

W sensie Miesiac i Srednia i jest nullem? Jesteś pewien że zapytanie powinno coś zwrócić?
Jak nie jesteś pewien czy zapytanie coś zwróci zamień First(); na FirstOrDefault(); wtedy się nie wywali błędem.


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 2x, ostatnio: DibbyDum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Teraz jest w porządku, źle łączyłem się z bazą - poniżej screen:

EDIT: Mam jeszcze pytanie, jak przeglądać tą kolekcję? Na foreachu dostaje:

Kopiuj
foreach statement cannot operate on variables of type 'AnonymousType#1' because 'AnonymousType#1' does not contain a public definition for 'GetEnumerator'

Da się to jakoś obejść? W zasadzie nie ma takiej potrzeby bo normalnie można odczytać te dane ale zaciekawił mnie ten błąd

edytowany 5x, ostatnio: Sebastiano
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
1
  1. Jak chcesz mieć kolekcje to możesz wyrzucić FirstOrDefault(); i wtedy błąd nie wystąpię ponieważ result będzie IOrderedQueryable<T>. Jak się spodziewasz pojedynczego elementu daj FirstOrDefault();
  2. Możesz też zrobić select new JakaśTwojaKlas { Miesiac= .. Srednia= .. } do której wrzucisz dane i dodasz jej implementacje IEnumerable.

To jest to samo jak byś próbował zrobić coś takiego:

Kopiuj
   class Program
   {
      static void Main(string[] args)
      {
         A a = new A();
         foreach (var c in a)
         {
           // ...
         }
      }
   }

   class A
   {
      public int A1;
      public double A2;
   }

Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum
Sebastiano
teraz wszystko jasne:)
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0
DibbyDum napisał(a):

Wyszły mi takie potworki. Trochę na czuja:

Kopiuj
         
         var result = (se.Wiatrs.Where(z => z.miejsce == "M1")
            .GroupBy(z => new {z.data.Year, z.data.Month}, z => z.data)
            .Select(g => new
            {
               Miesiac = g.Key.Month,
               Srednia = (se.Wiatrs.Where(z => z.miejsce == "M1").Select(z => z.temp)).Average(x => x)
            })).OrderBy(x => x.Srednia).First();

Teraz dla odmiany wyciągam najniższą wartość (wstawiam OrderByDescending) lecz dostaje taki sam wynik

DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0
  1. Powód: http://msdn.microsoft.com/en-us/library/vstudio/bb738550%28v=vs.100%29.aspx Last nie jest wspierane w Linq To Entity. Czyli najprościej mówiąc nie ma jak przetłumaczyć metody Last na SQL Query.
  2. Najprostsze obejście. .OrderBy(x => x.Srednia).ToList() i potem result.Last(); albo OrderByDescending i First

Więcej na temat: http://stackoverflow.com/a/3850254

EDIT:
Widocznie query zwraca tylko jeden wynik. Pod SQL masz więcej wyników?


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 2x, ostatnio: DibbyDum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Tym sposobem daje dobry miesiąc ale średnia jest (Wszędzie) najwyższa a nie najniższa <?>. Dane wiem jakie powinny być zwrócone bo do wszystkiego mam osobno zapytania SQL dla sprawdzenia wyników z linq :)

edytowany 1x, ostatnio: Sebastiano
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0

Okej teraz rozumiem:

Kopiuj
where z.miejsce == "M1" && z.data.Value.Month == g.Key.Month

dodaj tam gdzie masz query do Srednia


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 2x, ostatnio: DibbyDum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0
DibbyDum napisał(a):

Okej teraz rozumiem:

Kopiuj
where z.miejsce == "M1" && z.data.Value.Month == g.Key.Month

dodaj tam gdzie masz query do Srednia

W tamtych przykładach jak listuję całość to efekt jest osobny z tym że to w niczym nie przeszkadza, natomiast z najniższą wartościa jest problem.:) Poniżej SQL:

Kopiuj
SELECT MONTH(DATA),AVG(temp) AS srednia FROM `tabela` WHERE miejsce = 'M1' GROUP BY YEAR(DATA),MONTH(DATA) ORDER BY srednia ASC LIMIT 1;
edytowany 2x, ostatnio: Sebastiano
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
0

Odnośnie ostatniego elementu to zamień tylko OrderBy na OrderByDescending i zostaw FirstOrDefault.


Yubby dibby dibby dibby dibby dibby dibby dum..
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Próbowałem w ten sposób i cały czas dostaje miesiąc w którym była najwyższa średnia + najwyższa średnia miesięczna, więc bez zmian :( Wrzucam co dostaje z linq i osobno z phpMyAdmina wynik zapytania

Edit: Obecnie wygląda to tak:

Kopiuj
var resultMonthTempMin = (from z in _context.pomiary
                                                where z.miejsce == "GOR"
                                                group z.data by new { z.data.Value.Year, z.data.Value.Month } into g
                                                select new
                                                {
                                                    Miesiac = g.Key.Month,
                                                    Srednia = (from z in _context.topr_pomiary
                                                               where z.miejsce == "GOR"
                                                               select z.temp).Average(x => x)
                                                }).OrderByDescending(x => x.Srednia).FirstOrDefault();

Wynik jaki dostaje jest na screenie(jest to najwyższa średnia a nie najmniejsza):

edytowany 4x, ostatnio: Sebastiano
DibbyDum
Edytuj post i pokaż swoje zapytanie co aktualnie masz. Bo już nie wiem czy dałeś wszystko o czym pisałem czy nie. :P
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
2
Kopiuj
         var resultMonthTempMin = (from z in _context.pomiary
                                   where z.miejsce == "GOR"
                                   group z.data by new { z.data.Value.Year, z.data.Value.Month } into g
                                   select new
                                   {
                                      Miesiac = g.Key.Month,
                                      Srednia = (from z in _context.topr_pomiary
                                                 where z.miejsce == "GOR" && z.data.Value.Month == g.Key.Month
                                                 select z.temp).Average(x => x)
                                   }).OrderByDescending(x => x.Srednia).FirstOrDefault(); // OrderBy(x => x.Srednia).FirstOrDefault();

Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum
Sebastiano
i wszystko teraz super działa, dzięki za pomoc!:)
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

@DibbyDum padłem jeszcze przy jednym zapytaniu. Chodzi o to żeby wyświetlić kierunek wiatru który był przeważający w danym miejscu. Proszę o pomoc.

Kopiuj
SELECT kierunekWiatr, COUNT( kierunekWiatr ) AS ilosc FROM  `_pomiary` WHERE miejsce =  'M1' GROUP BY kierunekWiatr ORDER BY ilosc DESC LIMIT 1

moja nieudana próba linq:

Kopiuj
string resultDominandWind = (from z in _pomiary
                                                       where z.miejsce == "M1"
                                                       group z.kierunekWiatr by new { z.kierunekWiatr} into g
                                                       select new
                                                       {
                                                           Kierunek = g.Key.kierunekWiatr,
                                                           Ilosc = (from z in _pomiary
                                                                      where z.miejsce == "M1" 
                                                                      select z.kierunekWiatr).Count()
                                                       });
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
1

Wygląda okej nie licząc tego że zapomniałeś o OrderBy(x => x.Ilosc); Chyba. Było by łatwiej jak byś podawał jaki jest wynik oczekiwany a jaki dostajesz.
A tak w ogóle poćwicz gdzieś to LINQ bo nie chce mi się poprawiać każdego zapytania. ;)


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum
Sebastiano
w linqPadzie sobie ćwicze, ale mam jeszcze problemy z tego typu zapytaniami;)
DibbyDum
Ok. To jak tylko o OrderBy się rozchodziło? :P Czy dalej coś jest nie tak?
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Próbuje w ten sposób:

Kopiuj
 string resultDominandWindGoryczkowa = (from z in _pomiary
                                                       where z.miejsce == "M1"
                                                       group z.kierunekWiatr by new { z.kierunekWiatr} into g
                                                       select new
                                                       {
                                                           Kierunek = g.Key.kierunekWiatr,
                                                           Ilosc = (from z in _pomiary
                                                                      where z.miejsce == "M1"
                                                                    select z.kierunekWiatr).Count()
                                                       }).OrderBy(x => x.Ilosc).FirstOrDefault();

Zapytanie cały czas daje mi ilość wszystkich odczytów z miejsca M1. Natomiast powinno dać najwyższą ilość kierunku wiatru który był przeważający+ten kierunek:P

edytowany 2x, ostatnio: Sebastiano
DibbyDum
Edytuj post i zdefiniuj "coś jest nie tak". ;)
Sebastiano
poprawiłem, ale nie wiem czy zrozumiale opisałem:P
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
1

Nie rozumiem że takie coś chcesz osiągnąć?

Kopiuj
 string resultDominandWindGoryczkowa = (from z in _pomiary
                                                       where z.miejsce == "M1"
                                                       group z.kierunekWiatr by new { z.kierunekWiatr} into g
                                                       select new
                                                       {
                                                           Kierunek = g.Key.kierunekWiatr,
                                                           Ilosc = (from z in _pomiary
                                                                      where z.miejsce == "M1" && z.kierunekWiatr ==g.Key.kierunekWiatr
                                                                    select z.kierunekWiatr).Count()
                                                       }).OrderByDescending(x => x.Ilosc).FirstOrDefault();

Yubby dibby dibby dibby dibby dibby dibby dum..
Sebastiano
No dokładnie o to chodziło:) Zapomniałem o najważniejszym "z.kierunekWiatr == g.Key.kierunekWiatr", to też wyświetlały się wszystkie wyniki. Dzięki!:)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.