Scalanie wielu podobnych rekordów

0

Witam,
przeszukałem trochę internet oraz w3school i nie znalazłem odpowiedzi na swoje pytanie. Szukam metody na połączenie kilku identycznych rekordów, zmieniając tylko ilość + usunięcie nadmiernych rekordów. Normalnie trzeba:

  1. zgrupować wszystkie rekordy po odpowiednich polach i zrobić COUNT(ilosc)
  2. zrobić UPDATE po id wstawiając sumę z COUNT(ilosc)
  3. usunąć niepotrzebne pozycje

Baza wygląda tak:

id nazwa kolor ilosc
1 pilka zolta 3
2 pilka zolta 1
3 rakietka zolta 8
4 pilka czerwona 5
5 rakietka zolta 11

A po wykonaniu tego zapytania ma zostać:

id nazwa kolor ilosc
1 pilka zolta 4
3 rakietka zolta 19
4 pilka czerwona 5

Czy jest na to jakaś prostsza metoda, by wykonać wszystko w jednym zapytaniu a nie w 3 + pętle ?

0

zwykły, prosty select z group by i sum

0

Przy tabeli np: z 1 000 000 elementów to trochę głupio jest tworzyć i usuwać tabele. Wole zrobić tak jak napisałem.

0
UPDATE tabela t1
JOIN
   (SELECT id, SUM(t2.ilosc) AS suma
   FROM tabela t2
   GROUP BY t2.nazwa, t2.kolor) t3
ON t1.id = t3.id
SET t1.ilosc = suma
DELETE t1 FROM tabela t1
WHERE EXISTS (
   SELECT 'x' FROM tabela t2
   WHERE t1.nazwa = t2.nazwa
   AND t1.kolor = t2.kolor
   AND t1.id > t2.id)

Drugie zapytanie w MySQL nie działa, bo nie można używać w podzapytaniu FROM z tabeli, którą uaktualniamy. Udało mi się z JOIN w pierwszym zapytaniu, ale w drugim już nie miałem pomysłu. Może sam coś wymyślisz. Albo zastosujesz tabelę tymczasową.

0
Zi00mal napisał(a)

Przy tabeli np: z 1 000 000 elementów to trochę głupio jest tworzyć i usuwać tabele. Wole zrobić tak jak napisałem.

wiesz, tu nie chodzi o to czy to jest głupie czy mądre tylko o to czy da oczekiwany rezultat przy wykorzystaniu najmniejszej ilości zasobów (w tym głównie czasu)

Rev napisał(a)
UPDATE tabela t1
JOIN
   (SELECT id, SUM(t2.ilosc) AS suma
   FROM tabela t2
   GROUP BY t2.nazwa, t2.kolor) t3
ON t1.id = t3.id
SET t1.ilosc = suma

ale to CI niczego nie zsumuje (chyba, że jak zwykle w mysqlu to działa inaczej) bo id jest unikalne i SUM(t2.ilosc) będzie równe tyle co t2.ilosc

BTW jak widzicie potem usuwanie "niepotrzebnych" rekordów? Bo chyba nie z warunkiem ilość < max(ilosc) group by ... bo jakoś wątpię aby na kolumnie ilość ktoś miał indeks założony a bez indeksu to przy tych magicznych 1 000 000 rekordach będzie się nadawało do odstrzelenia delikwenta, który by to zapuścił

0

Najpierw wykona się podzapytanie (suma zwróci poprawy wynik), a dopiero później będzie dopasowywać.

0

to niech zrobi create table new_table z tego selecta, potem drop old_table i rename new_table to old_table czy jak tam się to zwie w jego bazie. Nie da się tego zrobić jednym zapytaniem bo trzeba jednocześnie zrobić update i delete

Też jestem za takim rozwiązaniem i myślę, że to powinno działać najszybciej spośród podanych tu rozwiązań.

0

czyli mówisz o TYM podzapytaniu

SELECT id, SUM(t2.ilosc) AS suma
   FROM tabela t2
   GROUP BY t2.nazwa, t2.kolor

to powiedz mi jakie ID zwróci ono dla takich rekordów

id nazwa kolor ilosc
1 pilka zolta 3
2 pilka zolta 1
bo coś czuję, że jakąś magiczną (dowolną z tych, losową, najmniejszą, największą, ...) wartość

BTW skąd wiesz, że to mysql skoro pytacz tego nie napisał, a w normalnej bazie to zapytanie nawet nie przejdzie

0

Niezdefiniowane, sorki, powinno tam być MIN(id) as id.

(SELECT MIN(id) as id, SUM(ilosc) AS suma
   FROM tabela
   GROUP BY nazwa, kolor) t2

A ten delete przejdzie chociażby w MSSQL.

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