Grupowanie, sortowanie, ostatnie 3 wyniki MySQL |
Grupowanie, sortowanie, ostatnie 3 wyniki MySQL |
16.06.2014, 09:40:14
Post
#1
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
Witam po raz pierwszy
Niestety poległem w prostej sprawie, jak mi się przynajmniej wydawało..: Mam następującą tabelę zakupu2014: |id |indeks |nazwa_towaru |jm |il0osc |cena_zakupu |nazwa_kontrahenta |data_realizacji| |0 |121 |aaa |kg |12 |12.1 |hh |2014-01-24| |1 |121 |aaa |kg |12 |13.1 |hh |2014-01-23| |2 |122 |bbb |szt |12 |14.1 |hh |2014-01-24| |3 |121 |aaa |kg |12 |10.1 |hh |2014-01-01| |4 |122 |bbb |szt|12 |9.1 |hh |2014-01-10| |5 |122 |bbb |szt|12 |1.1 |hh |2014-01-12| potrzebuje osiągnąc taki wynik jak daje: Select indeks,cena_zakupu,avg(cena_zakupu),min(cena_zakupu) from zakupy2014 group by indeks ale zamiast np avg ostatnią cenę zakupu, przedostatnia cenę zakupu i przedprzedostatnia cenę zakupu -w jednym rekordzie jak to jest właśnie w tym zapytaniu Oczywiście biorę po uwagę wariant ze zbudowaniem osobnej tabeli z takimi wynikami. Podkreślam, że dla niektórych indeksów może być tylko ostatnia cena_zakupu. Ma ktoś pomysł jak to rozwiązać? Pozdrawiam |
|
|
16.06.2014, 13:12:46
Post
#2
|
|
Grupa: Zarejestrowani Postów: 63 Pomógł: 3 Dołączył: 27.08.2008 Ostrzeżenie: (0%) |
Jedyne rozwiązanie, jakie mi przychodzi do głowy, to leftjoin z samym sobą, ale to na pewno nie będzie bardzo wydajne.
Powyższego nie sprawdziłem w praktyce, więc może coś działać źle, ale generalnie idea jest poprawna. Tyle, że powyższy przypadek będzie miał problem, jeśli coś usuniesz z tabeli, wówczas trzeba by go jeszcze bardziej skomplikować. Chyba, że potrzebujesz tą średnią + ostatnie 3 wyniki, to wówczas po prostu zrób 2 zapytania, powinno to działać szybciej, niż na tych joinach. |
|
|
16.06.2014, 22:14:51
Post
#3
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
Dzięki za podpowiedź ale dalej nie wiem jak skonstrowac warunki do tego, żeby było poprawnie. Piszesz, że można to rozwiązać przez 2 zapytania i szybciej to działa..przy ilości rekordów sięgających nawet 200 000 moze być to istotne. Mógłbyś rozwinąc ten temat.
Pozdrawiam |
|
|
17.06.2014, 07:47:22
Post
#4
|
|
Grupa: Zarejestrowani Postów: 63 Pomógł: 3 Dołączył: 27.08.2008 Ostrzeżenie: (0%) |
|
|
|
17.06.2014, 14:36:24
Post
#5
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
To zapytanie zwróci informacje o trzech wierszach największym id. Wcale nie muszą to być trzy ostatnie zakupy. Dzięki za podpowiedź ale dalej nie wiem jak skonstruować warunki do tego, żeby było poprawnie. Same zapytanie jest niepoprawne więc warunki w nim nic nie pomogą.Swoją drogą to tabela też nie jest poprawna - np. możesz dopisać towar raz w litrach, a przy kolejnym zakupie w kg. Chyba, że jest to celowe. Jeśli nie to poczytaj o postaciach normalnych. Jeśli zależy ci na wydajności to trzy ostatnie ceny możesz przechowywać w osobnej tabeli. Ich aktualizacje najwygodniej obsłużyć bezpośrednio w bazie danych, za pomocą wyzwalaczy. Trzeba wziąć pod uwagę, że dane w tabeli mogą być zaktualizowane lub usunięte więc i dla tych zdarzeń trzeba napisać wyzwalacze. Jeśli masz pewnośc, że nie będzie żadnych aktualizacji lub kasowania wtedy to co jest wystarczy. -------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 16:49:29
Post
#6
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
Dzięki bo już zastanawiałem sie nad pivot table żeby zrobic. Mam jednak problem:
CREATE TABLE `ostatnie_ceny` ( `indeks` int(11) NOT NULL, `cena_ost` decimal(8,2) NOT NULL, `cena_przedost` decimal(8,2) DEFAULT NULL, `cena_przedprzedost` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`indeks`), FOREIGN KEY (`indeks`) REFERENCES `zakupy2014` (`indeks`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB; MySQL zwrócił komunikat: Dokumentacja #1005 - Can't create table 'carboceny.ostatnie_ceny' (errno: 150) (Szczegóły…) Co może być nie tak? Nie wiem czy to istotne, ale w tabeli kolumne indeks musialem zmienic na varchar bo niestety kolumna ta może posiadać znaki wymieszane z cyframi:/ Co do budowy bazy to budowa jest importowana z pewnego "magicznego" systemu (skazana jest na jego ułomności) i nie będzie ulegała zmianie czy usuwaniu rekordów. Jako ciekawostka dodam, że poszczególne jm moga być litr i l, ale to temat na kiedy indziej. BTW Teraz zauważyłem, że wątek ująłem nie w tym dziale co powinienem za co przepraszam. |
|
|
17.06.2014, 17:05:00
Post
#7
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
Kolumna indeks musi być w obu tabelach tego samego typu. Poza tym na tą w tabeli zakupy2014 musi być nałożony indeks.
-------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 17:24:14
Post
#8
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
No tak myslalem, wiec ten wariant tez sprawdzilem jak tylko ten bład mi wyskoczył. Po uruchomieniu kodu, indeksy założyła ta procedura przez ciebie napisana. Zatrzymuje sie na create table..
CREATE TABLE `ostatnie_ceny` ( `indeks` varchar(15) NOT NULL, `cena_ost` decimal(8,2) NOT NULL, `cena_przedost` decimal(8,2) DEFAULT NULL, `cena_przedprzedost` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`indeks`), FOREIGN KEY (`indeks`) REFERENCES `zakupy2014` (`indeks`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB; MySQL zwrócił komunikat: Dokumentacja #1005 - Can't create table 'carboceny.ostatnie_ceny' (errno: 150) (Szczegóły…) |
|
|
17.06.2014, 17:28:36
Post
#9
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
Kod błędu ewidentnie mówi, że jest problem z kluczem obcym. Napisz co zwróci zapytanie.
-------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 17:37:32
Post
#10
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
Takie cuś
Table Create Table zakupy2014 CREATE TABLE `zakupy2014` ( `id` int(11) NOT NULL AUTO_INCREMENT, `indeks` varchar(15) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, `nazwa_towaru` text CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, `jm` tinytext CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, `ilosc` float NOT NULL, `cena_zakupu` float NOT NULL, `nazwa_kontrahenta` tinytext CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, `data_realizacji` date NOT NULL, PRIMARY KEY (`id`), KEY `indeks` (`indeks`) ) ENGINE=InnoDB AUTO_INCREMENT=11539 DEFAULT CHARSET=latin1 |
|
|
17.06.2014, 17:44:48
Post
#11
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
Więc jednak kolumny indeks w obu tabelach nie są tego samego typu. Popraw to i wtedy zadziała.
-------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 18:01:50
Post
#12
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
[quote name='diodadioda' date='17.06.2014, 18:24:14 ' post='1111477']
CREATE TABLE `ostatnie_ceny` ( `indeks` varchar(15) NOT NULL, no w kodzie co uruchamiam jest varchar(15) CREATE TABLE `ostatnie_ceny` ( `indeks` varchar(15) NOT NULL, `cena_ost` decimal(8,2) NOT NULL, `cena_przedost` decimal(8,2) DEFAULT NULL, `cena_przedprzedost` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`indeks`), FOREIGN KEY (`indeks`) REFERENCES `zakupy2014` (`indeks`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB; DROP TRIGGER IF EXISTS ostatnie_ceny; DELIMITER // CREATE TRIGGER ostatnie_ceny AFTER INSERT ON zakupy2014 FOR EACH ROW BEGIN DECLARE v_cena_przedost, v_cena_przedprzedost DECIMAL(8,2) DEFAULT NULL; SELECT cena_ost, cena_przedost INTO v_cena_przedost, v_cena_przedprzedost FROM ostatnie_ceny WHERE indeks = NEW.indeks; REPLACE ostatnie_ceny (indeks, cena_ost, cena_przedost, cena_przedprzedost) VALUE (NEW.indeks, NEW.cena_zakupu, v_cena_przedost, v_cena_przedprzedost); END// DELIMITER ; Chyba ze coś przeoczylem..moze musi byc inny typ zmiennej, ale jaki co by też znaki obsłużył? |
|
|
17.06.2014, 18:15:30
Post
#13
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
Zadanie dla spostrzegawczych. Znajdź różnice pomiędzy pierwszym a drugim wierszem:
-------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 18:20:08
Post
#14
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
Przepraszam ...
Teraz powstaly indeksy, wyzwalacze i ..pusta tabela: CREATE INDEX indeks ON zakupy2014 (indeks);# MySQL zwrócił pusty wynik (zero wierszy). CREATE TABLE `ostatnie_ceny` ( `indeks` varchar(15) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, `cena_ost` decimal(8,2) NOT NULL, `cena_przedost` decimal(8,2) DEFAULT NULL, `cena_przedprzedost` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`indeks`), FOREIGN KEY (`indeks`) REFERENCES `zakupy2014` (`indeks`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB;# MySQL zwrócił pusty wynik (zero wierszy). DROP TRIGGER IF EXISTS ostatnie_ceny;# MySQL zwrócił pusty wynik (zero wierszy). DELIMITER // CREATE TRIGGER ostatnie_ceny AFTER INSERT ON zakupy2014 FOR EACH ROW BEGIN DECLARE v_cena_przedost, v_cena_przedprzedost DECIMAL(8,2) DEFAULT NULL; SELECT cena_ost, cena_przedost INTO v_cena_przedost, v_cena_przedprzedost FROM ostatnie_ceny WHERE indeks = NEW.indeks; REPLACE ostatnie_ceny (indeks, cena_ost, cena_przedost, cena_przedprzedos[...] |
|
|
17.06.2014, 18:25:48
Post
#15
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 79 Dołączył: 25.05.2010 Ostrzeżenie: (0%) |
Teraz dodaj sobie coś do tabeli zakupy2014.
-------------------- Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ... |
|
|
17.06.2014, 18:52:23
Post
#16
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 16.06.2014 Ostrzeżenie: (0%) |
No super Teraz już wiem dlaczego nie mogę usuwać wierszy..
Wielkie Dzieki, Szacun za wiedzę. Wreszcie sie wyśpie |
|
|
Wersja Lo-Fi | Aktualny czas: 27.04.2024 - 08:34 |