Avatar billede Mik2000 Professor
09. december 2021 - 16:34 Der er 5 kommentarer og
2 løsninger

SUM i SQL og id

Er der en smart måde at lave noget a la

tabel
---------
id
felt1


SELECT id (LISTE), SUM(felt1) FROM tabel WHERE //her er en masse WHERE

Hvor id (LISTE) er en liste med alle de id'er der er brugt til at danne summen?

... helst uden at skulle lave subquery med en ny select, da der som sagt er mange where som i så fald også skal med i den

På forhånd tak for hjælpen :)
Avatar billede arne_v Ekspert
09. december 2021 - 16:55 #1
SELECT SUM(felt1) FROM tabel WHERE ...

finder summen

SELECT id WHERE FROM tabel WHERE ...

finder id'erne

2 queries??

Den sidste query og tæl sammen i applikation??
Avatar billede arne_v Ekspert
09. december 2021 - 17:02 #2
Hvis applikation skal tæælse sammen skal det naturligvis være:

SELECT id, felt1 WHERE FROM tabel WHERE ...
Avatar billede Mik2000 Professor
09. december 2021 - 18:07 #3
Ja men det var for at undgå at skulle køre 2 sql sætninger

Hvis man f.eks. kunne gøre noget i stil med

SELECT LIST(id) as ids, SUM(felt1) as sumTotal FROM tabel WHERE //her er en masse WHERE

og så få

ids: 1,2,5,8,10,15
sumTotal: 50.052,05
Avatar billede arne_v Ekspert
09. december 2021 - 18:46 #4
Du kan muligvis sende 2 SQL sætninger i 1 kald.

"SELECT ...; SELECT ..."

(det afhnger af API og konfiguration)

Ellers du kan hacke det med en UNION:

(SELECT SUM(felt1) FROM tabel WHERE ...)
UNION
(SELECT id WHERE FROM tabel WHERE ...)

Eller du kan lave en stored procedure.

Eller du kan vælge at leve med 2 kald!!
Avatar billede Mik2000 Professor
10. december 2021 - 11:51 #5
Okay så man er ligesom nødt til at have 2 kald. Håbede der var noget smart i SQL der kunne klare opgaven :)
Avatar billede arne_v Ekspert
12. december 2021 - 01:06 #6
SQL kan hvad SQL kan. Jeg har outlined nogle forskellieg løsninger.

Her er demo:


<?php
function get_connection() {
    $con = new PDO('mysql:host=localhost;dbname=Test', 'root', '');
    $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $con;
}

function two() {
    $con = get_connection();
    $stmt = $con->prepare('SELECT SUM(f1) AS sum FROM T1 WHERE f2 >= :f2');
    $stmt->execute(array(':f2' => 'C'));
    $row = $stmt->fetch();
    $sum = $row['sum'];
    echo "sum = $sum\r\n";
    echo "f2 =";
    $stmt = $con->prepare('SELECT f2 FROM T1 WHERE f2 >= :f2');
    $stmt->execute(array(':f2' => 'C'));
    while($row = $stmt->fetch()) {
        $f2 = $row['f2'];
        echo " $f2";
    }
    echo "\r\n";
}

function multi() {
    $con = get_connection();
    $stmt = $con->prepare('SELECT SUM(f1) AS sum FROM T1 WHERE f2 >= :f2; SELECT f2 FROM T1 WHERE f2 >= :f2');
    $stmt->execute(array(':f2' => 'C'));
    $row = $stmt->fetch();
    $sum = $row['sum'];
    echo "sum = $sum\r\n";
    echo "f2 =";
    $stmt->nextRowSet();
    while($row = $stmt->fetch()) {
        $f2 = $row['f2'];
        echo " $f2";
    }
    echo "\r\n";
}

/*

DELIMITER //
CREATE PROCEDURE sp_two(_f2 varchar(50))
BEGIN
SELECT SUM(f1) AS sum FROM T1 WHERE f2 >= _f2;
SELECT f2 FROM T1 WHERE f2 >= _f2;
END//
DELIMITER ;

*/
function sp() {
    $con = get_connection();
    $stmt = $con->prepare('CALL sp_two(?)');
    $arg = 'C';
    $stmt->bindParam(1, $arg, PDO::PARAM_STR);
    $stmt->execute();
    $row = $stmt->fetch();
    $sum = $row['sum'];
    echo "sum = $sum\r\n";
    echo "f2 =";
    $stmt->nextRowSet();
    while($row = $stmt->fetch()) {
        $f2 = $row['f2'];
        echo " $f2";
    }
    echo "\r\n";
}

function union() {
    $con = get_connection();
    $stmt = $con->prepare('(SELECT CAST(SUM(f1) AS CHAR) AS sumorf2 FROM T1 WHERE f2 >= :f2) UNION (SELECT f2 AS sumorf2 FROM T1 WHERE f2 >= :f2)');
    $stmt->execute(array(':f2' => 'C'));
    $first = true;
    while($row = $stmt->fetch()) {
        if($first) {
            $sum = $row['sumorf2'];
            echo "sum = $sum\r\n";
            $first = false;
            echo "f2 =";
        } else {
            $f2 = $row['sumorf2'];
            echo " $f2";
        }
    }
    echo "\r\n";
}

two();
multi();
sp();
union();
?>


2 kald er den portable løsning. 1 kald med 2 result set og SP er ikke portable. Union hacket er bare så grimt.
Avatar billede Mik2000 Professor
12. december 2021 - 23:43 #7
Tak for det Arne :)
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

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