Vinnaren i pepparkakshustävlingen!
2008-12-24, 14:25
  #1
Medlem
z0mfg(ish)s avatar
En fråga om en MySQL-fråga, hehe.

God jul föresten. Här sitter jag hemma och har tråkigt och försöker lösa en till synes enkel sql-grej, men kommer inte riktigt på hur jag ska göra.

Jag har ett kundvagnssystem där informationen finns lagrad i databas (även innehållet i användarnas kundvagnar). För att hålla koll på enskild användares kundvagn har jag ett fält "cookie" som överensstämmer med användarens cookie lagrad på datorn.
Men jag vill inte att kundvagnar ska ligga och skräpa i all evighet, så jag tänkte ha ett engångsskript som ska köras en gång per dag eller liknande.
I min databas har jag förutom "cookie" även "time", som innehåller tiden då senaste ändring skedde för den raden. Om en produkt läggs till så kommer tidpunkten då produkten lades till att läggas in, om en produkt uppdateras (till exempel kvantiteten) så kommer tidpunkten då produkten uppdaterades läggas in.

Så mitt problem är att jag inte riktigt vet hur jag ska göra för att se när sista produkten ändrades. Jag har försökt med GROUP BY men det vill sig inte riktigt.
Tänkte mig något där alla rader i tabellen "cart" grupperas på "cookie" och senaste "time" är den som räknas. Sen använder jag helt enkelt en SQL Delete-fråga där WHERE-klausulen får vara att "time" ska vara inom en viss tidsperiod (en vecka eller liknande).
Tacksam för hjälp!
Citera
2008-12-24, 14:27
  #2
Medlem
blaus avatar
Kod:
ORDER BY time ASC/DESC 

Borde väl lösa det.

Men du behöver väl egentligen varken sortera eller gruppera datan:

Kod:
DELETE FROM tblCartItems WHERE time DATE_SUB(NOW(), INTERVAL 1 DAY
__________________
Senast redigerad av blau 2008-12-24 kl. 14:30.
Citera
2008-12-24, 14:38
  #3
Medlem
z0mfg(ish)s avatar
Får "GROUP BY" att funka, men "ORDER BY time" ger bara samma resultat, vare sig det är ASC eller DESC. Den verkar sortera på ID-fältet, men det kan jag inte sortera på eftersom den senaste uppdaterade inte behöver vara den tidigaste tillagda.

Varför jag vill gruppera kundvagnen är för att en hel kundvagn ska försvinna, skulle vara aningen konstigt om det började försvinna produkter helt plötsligt ur kundvagnen.

Kanske går att lösa genom att kolla alla produkter i kundvagns-tabellen där senaste tillagda är innan ett visst datum och ta bort alla kundvagnar som har samma "cookie" som den.

Blev såhär, kanske ful lösning, men funkar gör det:
Kod:
$qry mysql_query("SELECT * FROM cart WHERE cartTime < DATE_SUB(NOW(), INTERVAL 1 day) GROUP BY cookieID") or die(mysql_error());

$numrows mysql_num_rows($qry);

if(
$numrows == 0)
{
    echo 
"No result";
}
else
{
    while(
$row mysql_fetch_array($qry))
    {
        
mysql_query("DELETE FROM cart WHERE cookieID = '".$row['cookieID']."'") or die(mysql_error());
    }

__________________
Senast redigerad av z0mfg(ish) 2008-12-24 kl. 14:48.
Citera
2008-12-24, 14:56
  #4
Medlem
(Har inte MySQL tillgängligt så kan ej testa om följande queries fungerar. Dock fungerar motsvarande queries i PostgreSQL)

Lista kundvagnar:
Kod:
SELECT cookie
FROM cart
GROUP BY cookie
HAVING MAX(time) <= DATE_SUB(NOW(), INTERVAL 1 DAY);

Delete:a dem:
Kod:
DELETE FROM cart
WHERE cookie IN (
   SELECT cookie
   FROM cart
   GROUP BY cookie
   HAVING MAX(time) <= DATE_SUB(NOW(), INTERVAL 1 DAY)
);

Citat:
Ursprungligen postat av z0mfg(ish)
Varför jag vill gruppera kundvagnen är för att en hel kundvagn ska försvinna, skulle vara aningen konstigt om det började försvinna produkter helt plötsligt ur kundvagnen.
Din databas är feldesignad. Du vill ha en tabell med kundvagnar, och en tabell med varor som ligger i kundvagnar. Vidare så vill du uppdatera ett datum som ligger i kundvagnstabellen när en produkt tas bort, läggs till, eller ändras.

Exempel: (otestad SQL som jag skriver direkt i webläsaren)
Kod:
CREATE TABLE cart (
   id SERIAL NOT NULL PRIMARY KEY,
   change_time TIMESTAMP
);

CREATE TABLE cart_products (
   id SERIAL NOT NULL PRIMARY KEY,
   product_id INT NOT NULL,
   cart_id INT NOT NULL,
   FOREIGN KEY (product_id) REFERENCES product (id),
   FOREIGN KEY (cart_id) REFERENCES cart (id) ON DELETE CASCADE
);

-- Lägg till trigger/rule som automatiskt uppdaterar cart.change_time när något ändras i cart_products... kan ej syntax i huvudet, så du får Googla.

-- Sen kan expire:ade carts tas bort mycket enkelt:
DELETE FROM carts WHERE change_time < NOW() - '1 day'::interval;
Citera
2008-12-24, 15:58
  #5
Medlem
z0mfg(ish)s avatar
Citat:
Ursprungligen postat av aidsbarn
Din databas är feldesignad. Du vill ha en tabell med kundvagnar, och en tabell med varor som ligger i kundvagnar. Vidare så vill du uppdatera ett datum som ligger i kundvagnstabellen när en produkt tas bort, läggs till, eller ändras.
Nja inte direkt. Jag har en tabell med produkter där all information finns. I kundvagnstabellen finns produktens ID som binds mha SQL JOIN till produkten i produkt-tabellen. Så min tabell "cart" är helt enkelt cartID, cartQty, productID, cookieID och tillsist cartTime. Då slipper jag ha ännu fler tabeller, men en (vad jag kallar) join-tabell skulle också funka, men känns onödig i mitt fall.

Men eftersom jag har fått det att funka så nöjer jag mig med min lösning. Tack för hjälpen!
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback