Gå til innhold

Hjelp med count() til å telle opp fra database(PHP, MySQL)


Anbefalte innlegg

Skrevet

Heisann!

 

Har en database med forskjellige kunder som jeg vil telle opp. Fant scriptet under på nett, men jeg sliter litt med det. Er sikkert ikke store problemet jeg gjør, men jeg finner rett og slett ikke ut av det.

 

 

Det som kommer ut av scriptet nå, er "Det er 1 kunder.". Men dette er feil, for det er rundt 50 kunder i databasen, som den ikke teller med.

 

fname = fornavn

_databasen_ = databasen jeg bruker. Har valgt å sensurere denne.

kundenr = kundenummer

 

 

<?php

// Make a MySQL Connection

 

$query = "SELECT fname, COUNT(fname) FROM _databasen_ GROUP BY kundenr";

 

$result = mysql_query($query) or die(mysql_error());

 

// Print out result

while($row = mysql_fetch_array($result)){

echo "Det er ". $row['COUNT(fname)'] ." kunder.";

echo "<br />";

}

 

 

Hva gjør jeg feil? Hvordan skal jeg få denne til å telle alle kundene i fname?

Videoannonse
Annonse
Skrevet (endret)

Det går ikke an å gjøre det slik du gjør (d'oh). Det du gjør feil er at du vil hente ut alle radene og samtidig få med deg antall rader. Korrekt? Isåfall fjerner du COUNT(fname) siden det ikke vil fungere. I stedet kan du bruke mysql_num_rows(...).

 

Red.: Skal du bare ha ut antall kunder kan du bruke følgende spørring:

SELECT COUNT(*) FROM table

Endret av Ernie
Skrevet (endret)

Dette blir feil, eller?

 

<?php
// Make a MySQL Connection

$query = "SELECT COUNT(*) FROM _database_";

$result = mysql_query($query) or die(mysql_error());

// Print out result
while($row = mysql_fetch_array($result)){
echo "Det er ". $result ." kunder.";
echo "<br />";
}?>

 

Det kommer nemlig bare ut "Det er Resource id #5 kunder."

Endret av AnaXyd
Gjest Slettet+142
Skrevet

<?php
// Make a MySQL Connection

$query = "SELECT COUNT(*) FROM _database_";

$result = mysql_query($query) or die(mysql_error());

// Print out result
$row = mysql_fetch_array($result);
echo "Det er ". $row[0] ." kunder.";
echo "<br />";
?>

:)

Skrevet
Aha! Det var det feilen lå ja.. :) Hvorfor $row[0] egentig? For at denne er default, eller standardverdi?

Fordi det er 1. felt returnert i raden.

Skrevet

bruk print_r til å se arrayer når du utvikler.

 

hadde du kun brukt $row ville du fått "Det er Array kunder!"

 

en print_r ville vist deg at $row så slik ut:

 

Array (
 [0] -> 51
)

 

(dersom var 51 rader i tabellen din)

 

derfor må du bruke $row[0] for å hente ut antallet.

 

gjør du for eksempel:

 

$res = mysql_query('select id, brukernavn, epost from brukere;');
$row = mysql_fetch_row($res);

 

ville $row vært noe liknende:

 

Array (
 [0] -> 1
 [1] -> AnaXyd
 [2] -> [email protected]
)

 

gjør du $row = mysql_fetch_row($res); en gang til vil du få et liknende array med info fra neste bruker.

 

mysql_fetch_assoc() gjør det samme, bortsett fra at den returnerer et navn assosiert array, med feltnavnene som navn liknende:

 

Array (
 ['id'] -> 1
 ['brukernavn'] -> AnaXyd
 ['epost'] -> [email protected]
)

Skrevet

Aha, ble litt mer forståelig nå.. :) Takk for grundig forklaring! :)

 

Kom på en ting til:

 

Er det mulig å telle opp hvor mange som kunder som har betalt? Hvis jeg har en kolonne som heter "Betalt?", og innholdet i radene er enten ja eller nei. Kan den telle hvor mange som har "ja" i seg?

Skrevet

feltet betalt bør være av typen BIT(1) DEFAULT NULL og være 1 for de som har betalt.

 

BIT(1) bruker max 1 bit med plass i databasen

VARCHAR(3) (som du trenger for ja og nei) bruker max 3*8 = 24 bit

 

dette ganger du opp med radene for å få totalen. kanskje ubetydelig for 50 rader, men har du 250 000 rader for eksempel kan dette ha en del å si på hastighet osv.

 

select count(kundenr) from _databasen_ where betalt = 1;

Skrevet
Ja, jeg tror det bare skal være å slenge på en WHERE i SQL-spørringen. Altså
SELECT COUNT(*) FROM table WHERE field = 'value'

Denne fungerte utmerket.. :) Takk!

 

Koden:

 

<?php
			$query = "SELECT COUNT(*) FROM _database_ WHERE betalt = 'Ja'";
			$result = mysql_query($query) or die(mysql_error());
			// Print out result
			$row = mysql_fetch_array($result);
			echo "<p>Antall betalende: ". $row[0] ." stk.</p>";
			echo "<br />";
			?>

 

feltet betalt bør være av typen BIT(1) DEFAULT NULL og være 1 for de som har betalt.

 

BIT(1) bruker max 1 bit med plass i databasen

VARCHAR(3) (som du trenger for ja og nei) bruker max 3*8 = 24 bit

 

dette ganger du opp med radene for å få totalen. kanskje ubetydelig for 50 rader, men har du 250 000 rader for eksempel kan dette ha en del å si på hastighet osv.

 

select count(kundenr) from _databasen_ where betalt = 1;

Denne skjønte jeg ikke helt? Dette er en bedre måte å løse det på, om det er flere kunder? Så hvis det er 250 000 kunder, kan det ta uhorvelig lang tid med koden jeg har benyttet nå?

Skrevet (endret)

nei. det ville ikke ta veldig lang tid. litt avhengig av trafikk, kunne du fått et lite problem. men tenk sider som mail.google.com og www.facebook.com som har milioner av brukere og milliarder av database rader for diverse ting. de er avhengig av å spare inn der det er mulig. så det er like greit å gjøre det en vane å forsøke å skrive så effektivt som mulig.

 

du har en tabell med rader av informasjon (brukere) og du ønsker et nytt felt som forteller om status på en bruker er betalt eller ikke betalt.

 

her er det to muligheter. ja (betalt) eller nei (ikke betalt).

 

den mest effektive måten er å lage et felt av typen bit med lengde 1, altså BIT(1)

 

dette feltet kan være 0 eller 1.

 

det gjør det samme som nei eller ja, men det bruker kun 1 bit på å gjøre det.

 

en bokstav er vanligvis 1 byte (det finnes mange unntak. UTF-8 kan ha et enkelt tegn på opp til 4 bytes). 1 byte er 8 bit. så man kan lagre betaling status til 8 brukere i en bokstav med andre ord. ordet "nei" som betalt status for en bruker krever like mye plass som betalt status på 24 brukere dersom bit(1) hadde blitt brukt.

 

bruker du tekst for å vite om en rad har betalt eller ikke bruker du unødig plass. spiller sikkert ingen rolle for ditt bruk.

Endret av grimjoey
Skrevet

Skjønner... Kanskje jeg skal prøve å gjøre som ditt eksempel med det samme, slik at jeg lærer meg å skrive mest effektiv kode som mulig.. :)

 

Uansett skal du ha takk som gidder å skrive så grundige innlegg! Takk for hjelpen! :)

Skrevet (endret)

grimjoey: Jeg synes du er en smule paranoid her. Jeg påstår overhode ikke at jeg er noen database-guru, heller tvert imot. Dog, at 1 bit kontra 3 byte pr. rad skal ha noen betydningsfullt utslag på ytelsen er helt på jordet for meg. Ut fra min kunnskap har diskforbruk ytterst lite å si i forhold til indekser og korrekt bruk av de. I tillegg er det vel en fordel å få indeks inn i minnet også. Jeg vil tro at innen 1 bit vs. 3byte for en effekt på ytelsen har man allerede fått ytelsesproblemer grunnet helt andre ting, men det er såklart mulig tar feil der.

 

PS: BIT er før MySQL 5.0.3 et alias for TINYINT(1), og tar da 1 byte.

 

Red.: Misforstå meg rett. Jeg er forsåvidt enig i at bit er bedre enn å ha et char/varchar felt for det, men å argumentere med at bit gir bedre ytelse blir for meg veldig uten rot i virkeligheten. Personlig ville jeg vel gått for enum da det er mer logisk enn å bruke *int eller bit.

Endret av Ernie
Skrevet

Ernie: det er mest prinsippet jeg vil fremheve. ikke bruke LONGBLOB for å lagre en id liksom. det kan være nyttig å påpeke slike ting som dette for brukere som ikke er noe særlig oppmerksomme på datatyper. kan få de til å lære seg litt om det dersom de er interesert, og det vil føre til bedre databaser. kan ikke du fortelle litt om indekser? for der er jeg ganske blank.

Skrevet (endret)

Som sagt er jeg ikke akkurat noen database-guru, men her er nå greia:

Uten indekser må man gå igjennom hele tabellen for å hente ut rader, og naturlig nok blir det ganske treigt etterhvert. For å bøte på det kan man lage indekser over tabellen. Disse kan gjøres over en eller flere felter og fungerer som en oppslagstabell over radene. Hvis du nå har en indeks på felt1 og kjører spørringen "SELECT * FROM tabell WHERE felt1 = 'verdi'" vil man kunne slippe å gå igjennom hele tabellen, som kan være veldig stor, og i stedet gå igjennom indeksen som er mye mindre. Her vil man da finne de radene som har felt1 med verdien 'verdi'. Disse vil så referere til plasseringer i tabellen.

 

Nå vil noen fort tro at det bare er å sette en indeks på alle mulige felter og kombinasjoner av de, men fult så enkelt er det ikke. Ulempen med indekser er blant annet at operasjoner som INSERT og DELETE blir tregere siden man i tillegg til å måtte vedlikeholde tabellen også må vedlikeholde x antall indekser. Videre er det heller ikke sånn at man alltid har nytte av flere indekser siden man til enhver tid bare kan velge en indeks (iallfall i MySQL). Med andre ord er det med indekser en balansegang mellom hva du trenger og har nytte av både i praksis og i forhold til ytelse. En ting man bør legge merke til er at primærnøkler og fremmednøkler er indekser. I tillegg er EXPLAIN nyttig i forhold til å finne ut hvilken indeks man har tilgjengelig og hvilken MySQL bruker i en SQL-spørring.

 

Sånn i forhold til ytelse og optimalisering av mysql-tabeller og spørringer så er dokumentasjonen for mysql et fint sted å starte.

 

Red.: Bare for å ha sagt det: Det er ingen fasit på når man skal og ikke skal bruke indekser. Riktignok kan man som hovedregel sette indeks på felter man bruker i en JOIN, men med riktig oppsett er dette primærnøkler og fremmednøkler (hvis man ikke bruker MyISAM da selvsagt).

Endret av Ernie

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...