Autor Zpráva
nevimjakdal
Profil *
Dobrý den, mám na webu ruletu a rád bych vypisoval posledních 10 transakcí

V tabulce mám

uzivatel | text | castka | datum | id
test1 | vyhrál | +100 | date | 1
test1 | prohrál | +38 | date | 2
test2 | vyhrál | +85 | date | 3
test1 | vyhrál | +175 | date | 4
test1 | vyhrál | +175 | date | 5
test1 | prohrál | +103 | date | 6
test3 | vyhrál | +47 | date | 7
test1 | vyhrál | +12 | date | 8
test1 | vyhrál | +300 | date | 9

Pokud si na webu udělám výpis prvních 5, co vyhráli, tak vše funguje. Akorát pak tam třeba test1 je 3x za sebou a uživatel test3 už se neukáže. Existuje možnost, ať už na úrovni php nebo spíše na úrovni sql dotazu, pokud budou za sebou 2 a více stejné záznamy od stejného uživatele, aby se sečetli a vypsalo se to jako jeden řádek?

Tedy místo
test1 | vyhrál | +100 | date | 1
test1 | prohrál | +38 | date | 2
test2 | vyhrál | +85 | date | 3
test1 | vyhrál | +175 | date | 4
test1 | vyhrál | +175 | date | 5

by to vypsalo

test1 | vyhrál | +100 | date | 1
test1 | prohrál | +38 | date | 2
test2 | vyhrál | +85 | date | 3
test1 | prohrál | +453 | date | 4
test3 | vyhrál | +47 | date | 5


OPRAVA POSLEDNÍ TABULKY
test1 | vyhrál | +100 | date | 1
test1 | prohrál | +38 | date | 2
test2 | vyhrál | +85 | date | 3
test1 | prohrál | +350 | date | 4
test3 | vyhrál | +47 | date | 5


EDIT: Omlouvám se, v rychlosti psaní jsem zapomněl upravit, že u sloupecku "castka" je +castka a pokdu prohraje tak je -castka, jen pro upresneni
Kajman
Profil
Podporuje databáze window funkce?
Keeehi
Profil
nevimjakdal:
Jako pátý záznam má být test1 | prohrál | +103 | date | 6 ne? Test3 by tedy neměl být i tak vidět.

V sql se to dá udělat pokud daná databáze podporuje window funkce.

V PHP to vypadá takto:
$i = 0;
$previousRow = $result->fetch_assoc();

while($i < 5) {
    $row = $result->fetch_assoc();
    
    if(!is_array($row)) {
        break;
    }
    
    if($previousRow['uzivatel'] === $row['uzivatel'] && $previousRow['text'] === $row['text']) {
        $previousRow['castka'] += (int)$row['castka'];
    } else {
        $i++;
        echo "$previousRow[uzivatel] | $previousRow[text] | $previousRow[castka] | $previousRow[datum] | $i";
        $previousRow = $row;
    }
}

if($i < 5 && is_array($previousRow)) {
    echo "$previousRow[uzivatel] | $previousRow[text] | $previousRow[castka] | $previousRow[datum] | $i";
}
nevimjakdal
Profil *
Jak zjistím, zda databáze podporuje window funkce? Děkuji


Ano, 6 záznam má být tak, jak jste napsal výše. Chtěl jsem jen ukázat, jak to myslím a přeskočil jsem řádek.


Na výpis řádků používám

while ($row = $result->fetch_assoc()) {
//...
}
s LIMIT 5 v sql příkazu.

to $previousRow = $result->fetch_row(); a ten zbytek Vašeho kódu má být uvnitř toho, co používám já? Děkuji


Tedy takto?

$query = "SELECT * FROM rul_history ORDER BY datum DESC";
$result = $mysqli->query($query);
 
 
$i = 0;
$previousRow = $result->fetch_row();
 
while($i < 5) {
    $row = $result->fetch_row();
    
    if(!is_array($row)) {
        break;
    }
    
    if($previousRow['uzivatel'] === $row['uzivatel'] && $previousRow['text'] === $row['text']) {
        $previousRow['castka'] += (int)$row['castka'];
    } else {
        $i++;
        echo "$previousRow[uzivatel] | $previousRow[text] | $previousRow[castka] | $previousRow[datum] | $i";
        $previousRow = $row;
    }
}
 
if($i < 5 && is_array($previousRow)) {
    echo "$previousRow[uzivatel] | $previousRow[text] | $previousRow[castka] | $previousRow[datum] | $i";
}
 
if($i < 5 && is_array($previousRow)) {
    echo "$previousRow[nick_twitch] | $previousRow[akce] | $previousRow[castka] | $previousRow[datum] | $i";
} 



To mi vypíše bez chyby jen
| | | | 0
Tomáš123
Profil
Nebolo by vhodné tabuľky rozdeliť na užívateľskú a hernú? Povedzme:
Užívateľ:
IDuzivatel|meno_uzivatela|vyhral_pocet|prehral_pocet|posledna_hra_pocet

Hry:
ID|stav|datum|IDuzivatel
Keeehi
Profil
Tomáš123:
Možná ano ale rozhodně ne jak navrhuješ. Ty předpočítané sloupce tam nemají co dělat. Tedy mohou tam být ale je to porušení normální formy což se dělá až když jsou potřeba výkonové optimalizace.
Navíc tvůj návrh moc nemění návrh od nevimjakdal. V podstatě správně ubírá zbytečný sloupec text ale jinak jen přidává další tabulku.
Tomáš123
Profil
Keeehi:
Chcel som nastreliť a otvoriť túto možnosť zlepšenia. Môžem ťa poprosiť o tvoj návrh?
Kajman
Profil
nevimjakdal:
Jak zjistím, zda databáze podporuje window funkce?

Podíváte jakou databázi používáte (mariadb, postgresql, mysql, oracle, ...), v jaké verzi. To pak zkonzultujete s manuálem.

Při podpoře by měl jít většinou tento dotaz
select row_number() over(order by 1) from dual
nevimjakdal
Profil *
Tento dotaz vrací bool(false), takže to pravděpodobně nepodporuje. Můžete mi prosím poradit, co je špatně v tom horním kódu, proč to nefunguje a vypisuje to jen pár | a 0? Děkuji
Keeehi
Profil
nevimjakdal:
Můžete mi prosím poradit, co je špatně v tom horním kódu, proč to nefunguje a vypisuje to jen pár | a 0?
Začal bych otestováním, co vlastně databáze vrací.
$query = "SELECT * FROM rul_history ORDER BY datum DESC";
$result = $mysqli->query($query);

var_dump($result);
var_dump($result->num_rows);

$i = 0;
$previousRow = $result->fetch_row();

var_dump($previousRow);

while ...

Tomáš123:
Chcel som nastreliť a otvoriť túto možnosť zlepšenia. Môžem ťa poprosiť o tvoj návrh?
Návrh nevimjakdal je z velké části správný. Je tam pár drobností ale nic extrémně špatného.
uzivatel - Primární klíče (tudíž i tento cizí klíč) bývají většinou číselné takže tento textový je neobvyklý. Nemělo by to však být nic zásadního.
text - Tento sloupec je redundantní, jeho hodnota se dá jednoduchou podmínku určit ze sloupce castka.
castka - Jelikož je v ukázce uvedeno u kladných čísel +, tak se dá asi předpokládat že sloupec je textový. Což je asi největší chyba tohoto návrhu ovšem dá se to velmi jednoduše opravit převedením na číselný sloupec.
datum - Tento sloupec bude asi správně.

Co se týče tabulky uživatelů případně jiných tabulek, tak těžko něco navrhovat jelikož vůbec nemáme informace o zbytku aplikace.
nevimjakdal
Profil *
ve var_dump vrací stránka jen
object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(5) ["lengths"]=> NULL ["num_rows"]=> int(7) ["type"]=> int(0) } int(7) array(5) { [0]=> string(5) "test1" [1]=> string(7) "vyhrál" [2]=> string(3) "100" [3]=> string(19) "2018-08-19 22:46:32" [4]=> string(1) "1" }
Keeehi
Profil
Místo fetch_row je potřeba použít fetch_assoc a nebo indexovat pole číselnými indexy. V [#3] jsem to opravil.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0