Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: UPDATE + COUNT (+ JOIN ?)
Forum PHP.pl > Forum > Bazy danych > MySQL
#luq
Hej mam taki problem:

credit
creditId | cntDoneInstalment (...)

instalmnet
instalmentId | creditId | isDone (...)

relacja jeden (kredyt) do wielu (raty)

Pole cntDoneInstalment jest polem pomocniczym do innego zapytania, bo po co to w tamtym zapytaniu liczyć, prawda?...
I teraz chce aby po zedytowaniu rekordu raty była przeliczana liczba spłaconych rat (cntDoneInstalment)

No i teraz problem w tym, że robię sobie transakcję:
1. edytuje ratę
2. edytuje pole cntDoneInstalment tego kredytu

No i jak zrobić zapytanie 2, mając jedynie instalmentId?

Napisałem coś takiego:
  1. UPDATE
  2. credit
  3. SET
  4. credit.cntDoneInstalment = (
  5. SELECT COUNT( instalment.instalmentId )
  6. FROM instalment
  7. WHERE
  8. instalment.isDone = 1 AND
  9. instalment.creditId = (
  10. SELECT instalment.creditId FROM instalment WHERE instalment.instalmentId = 14
  11. )
  12. )
  13. WHERE
  14. credit.creditId = (
  15. SELECT instalment.creditId FROM instalment WHERE instalment.instalmentId = 14
  16. )


Ale raz, że nie działa - nic nie modyfikuje biggrin.gif
Dwa, nawet jakby działało to mam 2 razy podzapytanie o creditId:

  1. SELECT instalment.creditId FROM instalment WHERE instalment.instalmentId = 14


a więc jak to przy UPDATE wrzucić jakoś w zmienną?
A może zupełnie coś innego?

EDIT
Aj sorry, podane przeze mnie zapytanie jednak działa. Po prostu jak zapytanie ma zmodyfikować tabele w taki sposób, że wszystkie rekordy pozostaną bez zmian to dostaje, że zedytowano rekordów = 0. No tak słusznie smile.gif

A więc chodzi o optymalizację tego. Jak wplątać tą zmienną?
Mchl
Można na przykład tak. Chociaż mogłem coś pochrzanić winksmiley.jpg

Kod
UPDATE
  credit AS c
CROSS JOIN (
  SELECT
    creditid, COUNT(*) AS cnt
  FROM
    instalment AS i
  CROSS JOIN (
    SELECT
      creditid
    FROM
      instalment
    WHERE
      instalmentid = 14
  ) USING (creditid)
  WHERE instalment.isDone = 1
) AS sq
USING (creditId)
SET c.cntDoneInstalment = sq.cnt


P.S. A po co to optymalizować? Takie wolne? Może trzeba się tabelom przyjżeć?
#luq
Nie wolne to to nie jest (~0.02 sek.).

W Twojej wersji są 2 podzapytania w mojej 3, czyli Twoja jak dla mnie okej, bo głównie mi chodzi o to, że u mnie jest 2 razy to samo, a i po co, jak można raz. Dlatego moja wersja zapytania mi się nie podoba.

U Ciebie dostaje
Kod
Every derived table must have its own alias

Chodzi o to, że najbardziej wewnętrzny CROSS JOIN nie ma aliasu, ale po tym to też kicha bo dostaje
Kod
Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

USING z COUNT nie zadziała, trzeba by zrobić jakiegoś tempa co daje 3 podzapytanie.

Eee, chyba zostanę przy swoim.

Mchl
Dodaj po prostu GROUP BY creditid do tego podzapytania. Masz ustawiony tryb zgodności ze standardami, który wymusza taką składnię.
#luq
Przeprojektowałem to co miałem zrobić. Mam teraz dostęp do creditId bez żadnego podzapytania.
Wszystko działa jak należy. Dzięki za zainteresowanie smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.