Witam,
sam nie wiedziałem jak trafnie nazwać temat tego posta, jednak sam wątek nawiązuje do innego mojego wątku niedawno tutaj poruszanego.. (link: Procedura i zmienna liczba zmiennych ).
Z nieocenioną pomoca osoby @Marcin.Miga w zalinkowanym temacie, zostało zaproponowane zastąpienie procedury "zwykłym" zapytaniem SQL..
Na początku, uwzględniając podstawowe założenia* , wszystko było ok, jednak gdy próbowałem uściślić owe założenia to pojawił się problem..
Przechodząc do konkretów..
Kod zapytania wygląda tak:
(ps. kod tabel i reszty wymaganego 'koda' poniżej..)
select pivot.* from
(
SELECT wyniki.id_wynik, wyniki.id_strzelca, wyniki.ilosc_punktow,
sum(wynik*(1-abs(sign(numer_strzalu-1)))) as strzal1,
sum(wynik*(1-abs(sign(numer_strzalu-2)))) as strzal2,
sum(wynik*(1-abs(sign(numer_strzalu-3)))) as strzal3,
sum(wynik*(1-abs(sign(numer_strzalu-4)))) as strzal4,
sum(wynik*(1-abs(sign(numer_strzalu-5)))) as strzal5,
sum(wynik*(1-abs(sign(numer_strzalu-6)))) as strzal6,
sum(wynik*(1-abs(sign(numer_strzalu-7)))) as strzal7,
sum(wynik*(1-abs(sign(numer_strzalu-8)))) as strzal8,
sum(wynik*(1-abs(sign(numer_strzalu-9)))) as strzal9,
sum(wynik*(1-abs(sign(numer_strzalu-10)))) as strzal10
FROM strzaly
INNER JOIN wyniki
ON wyniki.id_strzelca = strzaly.id_strzelca
GROUP BY id_strzelca ) pivot
INNER JOIN wyniki w
ON w.id_wynik = pivot.id_wynik
ORDER BY w.ilosc_punktow DESC, w.ilosc_10 DESC, w.ilosc_9 DESC, w.ilosc_8 DESC, w.ilosc_7 DESC, w.ilosc_6 DESC,
w.ilosc_5 DESC, w.ilosc_4 DESC, w.ilosc_3 DESC, w.ilosc_2 DESC, w.ilosc_1 DESC;
Trochę informacji..
A więc zaproponowano mi, abym do wyświetlenia tabeli skorzystał z konstrucji pivot (cross-table), aby otrzymać taką "budowę" tabeli:
+--------+---------------+--------------+--------+--------+--------+--------+--------+--------+--------+--------+--------+---------+
| id_wynik | id_strzelca | ilosc_punkow | value1 | value2 | value3 | value4 | value5 | value6 | value7 | value8 | value9 | value10 |
+----------+-------------+--------------+--------+--------+--------+--------+--------+--------+--------+--------+--------+---------+
Jednakże przy tej zamianie pojawia się problem dla strzelców, którzy mają kilka "serii" strzałów, ponieważ wyniki są "sumowane" w jeden wiersz, a założenia są takie:
*
-dla posortuj malejąco według kolumny ilosc_punkow
-jesli kilku strzelcow ma ten sam wynik "rozstrzygnij" kto ma być wyżej.. (sprawdz najpierw liczbę 10-tek, potem (jesli jest konieczne) sprawdź liczbę 9-tek, 8-ek, etc.. (w kodzie załatwia to ORDER BY .. DESC))
-jesli dany strzelec bierze kilka razy udział (wykonuje kilka serii), to zostaw tylko jeden, najwyższy uzyskany przez niego wynik w "wyniku końcowym"
I właśnie z tym ostatnim założeniem jest problem.. (przynajmniej w tym momencie, w którym jestem..)..
Wcześniej próbowałem to robić za pomocą procedury i wykorzystywałem do tego m.in. zapytanie:
SELECT * FROM wyniki AS t1
WHERE (SELECT count(1) FROM wyniki AS t2 WHERE t2.id_strzelca = t1.id_strzelca AND t2.ilosc_punktow > t1.ilosc_punktow AND t2.id_strzelca ) = 0
które zdawało egzamin ale w ostatecznym rozrachunku procedura w zastosowaniach stała się mało "uniwersalna"...
Podsumowując: przedstawiam problem Wam (forumowiczom) z nadziejami na pomoc :)
REATE TABLE `wyniki` (
`id_wynik` int(11) NOT NULL auto_increment,
`id_strzelca` int(11) NOT NULL,
`ilosc_punktow` decimal(11,3) NOT NULL,
`ilosc_10` int(11) NOT NULL default '0',
`ilosc_9` int(11) NOT NULL default '0',
`ilosc_8` int(11) NOT NULL default '0',
`ilosc_7` int(11) NOT NULL default '0',
`ilosc_6` int(11) NOT NULL default '0',
`ilosc_5` int(11) NOT NULL default '0',
`ilosc_4` int(11) NOT NULL default '0',
`ilosc_3` int(11) NOT NULL default '0',
`ilosc_2` int(11) NOT NULL default '0',
`ilosc_1` int(11) NOT NULL default '0',
`ilosc_0` int(11) NOT NULL default '0',
PRIMARY KEY (`id_wynik`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci
CREATE TABLE `strzaly` (
`id_strzalu` int(11) NOT NULL auto_increment,
`id_wyniki` int(11) NOT NULL,
`id_strzelca` int(11) NOT NULL,
`numer_strzalu` int(11) NOT NULL default '0',
`wynik` decimal(5,3) NOT NULL default '0.000',
PRIMARY KEY (`id_strzalu`),
UNIQUE KEY `id_wyniki` (`id_wyniki`,`numer_strzalu`),
KEY `id_strzelca` (`id_strzelca`),
KEY `id_wyniki_2` (`id_wyniki`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci
DROP TRIGGER IF EXISTS `tr_bi_strzaly`;
DELIMITER $$
CREATE TRIGGER `tr_bi_strzaly` BEFORE INSERT ON `strzaly`
FOR EACH ROW begin
UPDATE wyniki SET ilosc_punktow=ilosc_punktow+NEW.wynik WHERE id_wynik=NEW.id_wyniki;
if NEW.wynik >= 10 then
UPDATE wyniki SET ilosc_10=ilosc_10+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 9 and 10 then
UPDATE wyniki SET ilosc_9=ilosc_9+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 8 and 9 then
UPDATE wyniki SET ilosc_8=ilosc_8+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 7 and 8 then
UPDATE wyniki SET ilosc_7=ilosc_7+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 6 and 7 then
UPDATE wyniki SET ilosc_6=ilosc_6+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 5 and 6 then
UPDATE wyniki SET ilosc_5=ilosc_5+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 4 and 5 then
UPDATE wyniki SET ilosc_4=ilosc_4+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 3 and 4 then
UPDATE wyniki SET ilosc_3=ilosc_3+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 2 and 3 then
UPDATE wyniki SET ilosc_2=ilosc_2+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 1 and 2 then
UPDATE wyniki SET ilosc_1=ilosc_1+1 WHERE id_wynik=NEW.id_wyniki;
else
if NEW.wynik between 0 and 1 then
UPDATE wyniki SET ilosc_0=ilosc_0+1 WHERE id_wynik=NEW.id_wyniki;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end $$
DELIMITER ;
INSERT INTO wyniki(id_wynik, id_strzelca) VALUES(1,7);
INSERT INTO wyniki(id_wynik, id_strzelca) VALUES(2,8);
INSERT INTO wyniki(id_wynik, id_strzelca) VALUES(3,8);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 1, 5);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 2, 9);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 3, 9.2);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 4, 5);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 5, 10.001);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 6, 9.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 7, 8);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 8, 6);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 9, 7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(1, 7, 10, 5);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 1, 6.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 2, 8);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 3, 5.2);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 4, 5.7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 5, 10.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 6, 10.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 7, 10.001);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 8, 9);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 9, 7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(2, 8, 10, 7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 1, 5.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 2, 7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 3, 5.2);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 4, 7.7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 5, 10.7);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 6, 8.1);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 7, 6);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 8, 8);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 9, 9);
insert into strzaly(id_wyniki, id_strzelca, numer_strzalu, wynik)
values(3, 8, 10,9);