Avatar billede terrak Nybegynder
06. juni 2006 - 17:10 Der er 7 kommentarer og
1 løsning

Antal varer tilbage

Jeg har to tabeller, "varer" og "varesalg".

Tabellen varer indeholder information om en bestemt var, deriblandt antal, dvs. antallet der var til at starte med.
Hver gang der sælges en vare, oprettes der en post i tabellen varesalg.

Tabelstrukturen er som følger.

CREATE TABLE `varer` (
  `id` int(6) NOT NULL auto_increment,
  `kategori` varchar(16) NOT NULL,
  `navn` varchar(32) NOT NULL,
  `antal` int(3) NOT NULL,
  `pris` float NOT NULL,
  `købspris` float NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `navn` (`navn`)
)

CREATE TABLE `varesalg` (
  `id` int(6) NOT NULL auto_increment,
  `vareid` int(6) NOT NULL,
  `tid` time NOT NULL,
  `dato` varchar(10) NOT NULL,
  PRIMARY KEY  (`id`)
)

Jeg vil gerne lave en forespørgsel, som viser antallet af varer tilbage, af hver vare, men det jeg kan ikke lige finde en komplet løsning på dette.

Det tætteste jeg er kommet på, er en forespørgsel der viser antallet af varer tilbage, for de varer der er blevet købt noget af. Af der ikke købt noget af en vare, kommer den ikke med i forespørgslen.
Ind til videre ser det sådan ud:

select varer.`navn`,varer.`antal`-count(varesalg.`vareid`) as `tilbage` from `varer`,`varesalg` where varer.`id` = varesalg.`vareid` group by varer.`navn`

Jeg tænkte så at man kunne fjerne where betingelsen, men så trækker den antallet af poster i tabellen varesalg, fra antallet af hver vare i tabellen varer.

Er der nogen der kan hjælpe mig?

Jeg kører MySQL 5.0.18
Avatar billede terrak Nybegynder
06. juni 2006 - 17:19 #1
Jeg kan selvfølgelig løse problemet med PHP, men det ville kræve mindre kode og være mere simpelt at bruge en MySQL løsning.
Avatar billede arne_v Ekspert
06. juni 2006 - 18:09 #2
her er en loesnings ide:

mysql> CREATE TABLE vare (
    ->    vareid INTEGER PRIMARY KEY,
    ->    navn VARCHAR(50),
    ->    antal INTEGER
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql>
mysql> CREATE TABLE salg (
    ->    salgid INTEGER PRIMARY KEY,
    ->    vareid INTEGER,
    ->    antal INTEGER
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql>
mysql> INSERT INTO vare VALUES (1, 'A', 10);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO vare VALUES (2, 'B', 10);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO vare VALUES (3, 'C', 10);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> INSERT INTO salg VALUES (1, 1, 2);
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO salg VALUES (2, 1, 2);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO salg VALUES (3, 2, 2);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT vare.vareid,vare.navn,vare.antal-IFNULL(x.totalsalg, 0) AS antaltilbage
    -> FROM vare LEFT JOIN (SELECT vareid,SUM(antal) AS totalsalg FROM salg GROUP BY vareid) x ON vare.vareid=x.vareid;
+--------+------+--------------+
| vareid | navn | antaltilbage |
+--------+------+--------------+
|      1 | A    |            6 |
|      2 | B    |            8 |
|      3 | C    |          10 |
+--------+------+--------------+
3 rows in set (0.00 sec)

mysql>
mysql> DROP TABLE vare;
Query OK, 0 rows affected (0.02 sec)

mysql> DROP TABLE salg;
Query OK, 0 rows affected (0.01 sec)
Avatar billede zappa Nybegynder
06. juni 2006 - 18:21 #3
Her er en anden:

select navn, (sum(antal) - vareid)
from varer
inner join varesalg
on varer.id = varesalg.id
group by varer.id

Ovenstående er ikke testet grundigt - dette overlader jeg til dig :)
Avatar billede terrak Nybegynder
06. juni 2006 - 23:57 #4
Måske er jeg lidt stædig, men jeg ville altså finde min egen løsning og det lykkedes også til sidst.

Arne_v: Det første jeg så ved dit forslag, var at begge tabeller indeholdte "antal", så jeg var lidt i tvivl om det ville virke som jeg ville, uden jeg skulle ændre noget. Jeg prøvede at bruge noget af det, men jeg forstår stadig ikke hvordan alle trinene i forespørgslen virker, og det lykkedes heller ikke at finde noget.

Zappa: Jeg så at at du tog summen af antal, fra tabellen varer (?) og trak vareid'et fra denne sum (??), så jeg brugte ikke mange forsøg for jeg gik bort fra det.

Selv om jeg fandt løsningen på egen hånd, så lærte jeg også lidt mere MySQL og syntaks ved at studere dit eksempel, Arne_v. Så hvis du vil smide et svar, vil jeg blive glad :-)

Løsningen jeg fandt frem til (som ligner min originale idé meget) er:
select varer.`navn`,varer.`antal`-count(varesalg.`vareid`) as `tilbage` from `varer` left join `varesalg` on varer.`id` = varesalg.`vareid` group by varer.`navn`

Det er næsten taget direkte fra eksemplet på http://dev.mysql.com/doc/refman/5.0/en/create-table.html nederst (ikke kommentarer) hvor der laves en tabel "artists_and_works".
Avatar billede arne_v Ekspert
07. juni 2006 - 08:28 #5
svar
Avatar billede arne_v Ekspert
07. juni 2006 - 08:28 #6
din loesning er faktisk udmaerket - den udnytter at alle salg kun er af 1 styk, hvilket
goer det lidt nemmere
Avatar billede arne_v Ekspert
07. juni 2006 - 08:30 #7
det jeg goer er at lade output fra

SELECT vareid,SUM(antal) AS totalsalg FROM salg GROUP BY vareid

blive til en fiktiv tabel ved navn x
Avatar billede terrak Nybegynder
07. juni 2006 - 13:41 #8
Det var også noget i den retning jeg kom frem til at den gjorde :-)

Det eneste jeg ikke helt forstår i min egen løsning, er hvordan den kan vælge et felt fra tabellen varesalg, uden at fortælle at den skal bruge denne tabel. Det kan vel kun være fordi at dette felt er med i min left join?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester