[MYSQL4.1] - Update where IN voor elke waarde

Pagina: 1
Acties:

  • Facer
  • Registratie: Januari 2002
  • Niet online

Facer

Ken net.....

Topicstarter
Na enig google werk en nog een boek over SQL doorgelezen te hebben kom ik maar niet tot een oplossing van het volgende probleem.

Ik heb een aantal user id's waardes waarvan de dummy waarde verhoogd moet worden. Dit moet zovaak gebeuren als het user id's voorkomt in de IN.

De query waar het over gaat:
SQL:
1
2
3
4
5
6
UPDATE
  user
SET
  user_dummy = user_dummy + 1
WHERE
  user_id IN (1,1,2);


Het nadeel van deze setup is dat er user_dummy van user ID 1 maar 1x wordt verhoogd en niet 2x wat wel de bedoeling was met deze query. Is er een manier zodat SQL geen soort van "DISTINCT" uitvoert op de WHERE IN?

offtopic:
Waarom niet een lus maken die de userID uitleest die geupdate moeten worden en dan steeds een update doen?
Dit omdat ik de server belasting zo mimimaal mogelijk wil houden.

[ Voor 0% gewijzigd door Facer op 14-07-2007 16:42 . Reden: Typo ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

Volgens mij kan wat jij wil niet. Sowieso kan het niet met IN, want zoals je gemerkt hebt zitten de waarden die je daarmee doorgeeft in een set, en waarden daarin kunnen alleen aan of uit zijn, ze hebben verder geen waarde AFAIK.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • robbert
  • Registratie: April 2002
  • Laatst online: 18:50
De enige oplossing die ik zou kunnen bedenken is wat te klungelen met een CASE, dus iets in de volgende richting:
SQL:
1
2
3
4
5
UPDATE user
SET user_dummy = CASE user_id
  WHEN 1 THEN user_dummy + 1
  WHEN 2 THEN user_dummy + 2
  ELSE user_dummy END

  • Deikke
  • Registratie: Juni 2004
  • Laatst online: 20:38
WHERE zal alle records opzoeken die aan het vereiste voldoen, en daarna worden deze records geupdate volgens de opdrachten die je gezet hebt, dus nee. Het zal zo niet werken. Je zal voor nummer dus de query apart moeten uitvoeren. Of de manier gebruiken zoals hierboven wordt aangegeven.

Verwijderd

Ik weet niet hoeveel records je tegelijk wil updaten, maar mijn intuïtie zegt mij dat het sneller is om een lus door de user id's te doen dan de (wel correcte) manier van robbert.

Je hoeft dan toch niet per sé het bestaande record 'uit te lezen' (ik gok dat je daarmee bedoelt een SELECT)? Stel dat je PHP gebruikt, dan doe je een array_count_values() op je array met user id's, en dan doe je voor elke user id een UPDATE met dummy = dummy + aantal.

Hoe dan ook, als je de database server wil ontlasten, zul je meer werk moeten verrichten in je aanroepende code. En dan zal het voor ons misschien handig zijn om te weten wat dit precies is, een PHP script, of...?

  • robbert
  • Registratie: April 2002
  • Laatst online: 18:50
Verwijderd schreef op zaterdag 14 juli 2007 @ 20:51:
Ik weet niet hoeveel records je tegelijk wil updaten, maar mijn intuïtie zegt mij dat het sneller is om een lus door de user id's te doen dan de (wel correcte) manier van robbert.

Je hoeft dan toch niet per sé het bestaande record 'uit te lezen' (ik gok dat je daarmee bedoelt een SELECT)? Stel dat je PHP gebruikt, dan doe je een array_count_values() op je array met user id's, en dan doe je voor elke user id een UPDATE met dummy = dummy + aantal.

Hoe dan ook, als je de database server wil ontlasten, zul je meer werk moeten verrichten in je aanroepende code. En dan zal het voor ons misschien handig zijn om te weten wat dit precies is, een PHP script, of...?
Voor alle users een query uitvoeren lijkt me nou ook niet echt efficiënt. In mijn oplossing zul je een super lange query krijgen, maar die hoeft maar 1 keer uitgevoerd te worden.

Als je dan met php wat wilt gaan klungelen zou ik de users gaan groeperen op de aantal verhogingen. Dus een query uitvoeren voor alle users die 1 keer voorkomen, 1 voor alle die 2 keer voorkomen, etc..

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:08
Verwijderd schreef op zaterdag 14 juli 2007 @ 20:51:
Stel dat je PHP gebruikt, dan doe je een array_count_values() op je array met user id's, en dan doe je voor elke user id een UPDATE met dummy = dummy + aantal
Als je dan aan het tellen slaat in je programmeertaal dan kun je af met een query per gevonden aantal. In PHP zou dat zoiets zijn:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//container for queries
$sql = array();

//calculate count per id
$idCounts = array_count_values($inputArray);

//get all counts
$counts = array_unique($idCounts);

//generate SQL for each count
foreach($counts as $count) {
  //get ids that need to be updated with the current $count
  $ids = array_keys(array_intersect($idCounts, array($count)));

  $sql[] = sprintf('UPDATE `foo` SET `bar`=bar+%d WHERE `id` in (%s)',
    $count,
    implode($values)
  );
}

--edit--
robbert schreef op zaterdag 14 juli 2007 @ 21:17:Als je dan met php wat wilt gaan klungelen zou ik de users gaan groeperen op de aantal verhogingen. Dus een query uitvoeren voor alle users die 1 keer voorkomen, 1 voor alle die 2 keer voorkomen, etc..
Dat dus :)

[ Voor 15% gewijzigd door T-MOB op 14-07-2007 21:24 ]

Regeren is vooruitschuiven


Verwijderd

@robbert, maar, zoals ik zei, ik weet niet hoeveel users tegelijk geupdate moeten worden. Als het er maar 20 zijn dan is een simpele UPDATE naar mijn mening de makkelijkste en schoonste oplossing.

Groeperen op aantal en dan een query per aantal had ik ook al bedacht, maarja dan moet je een hoop van die array_ functies gebruiken waar je ook niet blij van wordt qua snelheid.
Pagina: 1