WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Avancerad SQL-fråga (https://www.wn.se/forum/showthread.php?t=1057534)

secag 2013-04-11 14:01

Avancerad SQL-fråga
 
Hej, detta kanske inte är så avancerat för vissa men för mig är det så. Vill också bli bättre på SQL.

Jag har 3 tabeller. Dom heter users, items och member_items.

Såhär ser allting ut (.png):http://i.imgur.com/kZ7V3hN.png

Man kan äga flera vapen av samma typ också. Rader i member_items kan då se ut såhär:
:: Där ser ni att user_id kan äga 3 vapen av samma typ.
HTML-kod:

user_id    item_id
4            2
4            2
4            2
4            1
5            2

Om jag nu i en enda query vill få ut hur mycket en user har i attack och defence TILLSAMMANS.
Detta är mitt försök, längre kan jag inte komma.
HTML-kod:

SELECT user.id, SUM( user.attack + user.defence) AS total_power
FROM users
GROUP BY total_power


linusoleander 2013-04-11 14:14

Så här kanske

Kod:

SELECT users.id, SUM(users.attack + users.defence + items.extra_attack + items.extra_defence) AS total_power
INNER JOIN member_items ON users.id = member_items.user_id
INNER JOIN items ON member_items.item_id = items.id
FROM users
GROUP BY users.id


secag 2013-04-11 14:37

Hmm, nu kommer bara de users som har vapen med. Går det att göra om frågan så även dom utan vapen syns i tabellen?

Lyckades lösa det genom några modifieringar, tack för grundstrukturen :)

PHP-kod:

SELECT members.member_id,
members.member_attack,
members.member_defence,
SUM(items.item_stat) + members.member_attack members.member_defence
AS total_power 
FROM members
LEFT JOIN memberitems ON members
.member_id memberitems.memberitems_member
LEFT JOIN items ON memberitems
.memberitems_item items.item_id
GROUP BY members
.member_id
ORDER BY total_power DESC 


secag 2013-04-11 14:54

En följdfråga...
Vill hämta en persons rang(högst total_power = rang #1). Detta funkar men går det att göra på ett snyggare sätt?
Vill undvika att ha en statisk kolumn i usertable som håller reda på rangen.

PHP-kod:

function get_rank($member_id) {
        global 
$db;
        
$i 1;
        
$q $db->query("SELECT members.member_id,
members.member_attack,
members.member_defence,
SUM(items.item_stat) + members.member_attack + members.member_defence
AS total_power 
FROM members
LEFT JOIN memberitems ON members.member_id = memberitems.memberitems_member
LEFT JOIN items ON memberitems.memberitems_item = items.item_id
GROUP BY members.member_id
ORDER BY total_power"
);
        while(
$r $q->fetch_array(MYSQLI_ASSOC)) {
            if(
$r["member_id"] == $member_id) {
                return 
$i;
            } else {
                
$i++;
            }
        }
    } 


Conny Westh 2013-04-11 17:01

Du har ingen PK i member_items och det gör att när du har fler items av samma typ så finns ingen möjlighet att identifiera enskilda tupler (förekomster) och hantera dem individuellt, annat än med rownumber (databasberoende). Du borde lägga till en egen PK i member_items så du kan identifiera enskilda tupler där.

Det verkar inte finnas någon RI (referencial Integrity) definierad på de Främmande nycklarna från member_items till users respektive items.


När du ställer en SQL-fråga här på forumet vore kanonbra om du lägger upp DDL-script för att skapa tabellerna och kanske lite insert-satser med exempeldata. Då det går snabbt för mig att lägga upp en exempeldatabas, och det går då snabbare att hjälpa dig, och du får troligen fler svar. Jag tycker det är kul att lösa SQL-problem så jag hjälper gärna till om jag kan och har tid.

secag 2013-04-12 15:42

Okej, vad betyder tupler? Varför är det i detta fall nödvändigt att skilja alla member_items åt med PK?

Referencial Integrity har jag inte greppat, vill du förklara det för mig och vad som gäller i detta fall?

Och med DDL menar du typ att ja ska skriva upp alla tabellstrukturer? Har hört att man helst ska använda SQL-fiddle? Kommer med alla sannolikhet att fråga mer om SQL så ja vill gärna veta vad det är för något :)

Conny Westh 2013-04-12 18:33

Tupler (plural) -> Är den matematiska benämningen på rader i en tabell.

Grader (plural) -> Den matematiska benämningen på kolumner i en tabell.

Referncial Integrity -> Ett sätt att låta databasen kontrollera att du bara använder giltiga Främmande nycklar (dvs värden som är Primärnyckel i en annan tabell, samt en del andra små trevliga saker som har med uppdatering och borttagning av primärnycklar som samtidigt är främmande nycklar i en annan tabell).

DDL-Script -> De SQL-satser du skriver som innehåller CREATE TABLE... dvs där du definierar strukturen. Detta kallas för Data Definition Language och är en delmängd av det gigantiska SQL-språket.

Varför behövs en primärnyckel i member_items-tabellen?
En viktig anledning till att använda primärnycklar i alla tabeller är att det är en del av den grundläggande databasteorin, och enligt andra och tredje normalformen måste varje tuple (dvs rad i tabellen) kunna identifieras på ett unikt sätt. ett vanligt sätt är att använda ett löpnummer 1,2,3,4... men man kan använda andra datatyper. Du har använd PK (primärnyckel) i tabellerna users och item för att kunna identifiera varje enskild tuple. Om du ska radera en enskild tuple i member_items-tabellen så går inte det därför att det inte går att identifiera en enstaka tuple, det bryter helt enkelt mot de mest elementära normaliseringsreglerna. När du tar bort ett värde idag med en enkel delete-sats så kommer alla värden med samma värden att raderas.

secag 2013-04-12 22:20

Okej, ännu en del saker som är oklara men det fastnar väl inom kort...
Själv stötte jag på ett problem här som jag aldrig tidigare behövt göra. Jag vill radera alla rader i tabellen nedanför FÖRUTOM de 30 senaste raderna som baseras på message_time. Det är väl samma sak med message_id tror jag.

Mitt försök där jag fick stop. Här raderar jag alla förutom den senaste.

PHP-kod:

DELETE FROM shoutbox WHERE message_id NOT IN (SELECT MAX(message_idFROM shoutbox); 

PHP-kod:

CREATE TABLE `shoutbox` (
 `
message_idint(11NOT NULL AUTO_INCREMENT,
 `
message_texttext NOT NULL,
 `
message_timeint(11NOT NULL,
 `
message_authorint(11NOT NULL,
 
PRIMARY KEY (`message_id`)
ENGINE=MyISAM AUTO_INCREMENT=DEFAULT CHARSET=latin1 


Conny Westh 2013-04-13 13:36

Du borde skriva något i stil med det här:

Kod:

-- Kod för MySQL
DELETE
FROM shoutbox
WHERE message_id NOT IN
(
    SELECT message_id
    FROM shoutbox
    ORDER BY message_id DESC
    LIMIT 0,30
);

Kod:

-- Kod för MS SQL-Server
DELETE
FROM shoutbox
WHERE message_id NOT IN
(
    SELECT TOP 30 message_id
    FROM shoutbox
    ORDER BY message_id DESC
);


När du använder max i din subquery så får du bara en tuple, men du ville ha 30.

Conny Westh 2013-04-13 14:39

Efter att jag testkörde frågan såg jag att det var lite trubbel i MySQL, som inte uppträder i MSSQL, så här kommer en uppdaterad SQL-kod som jag har testkört utan data:

Kod:

DELETE FROM `shoutbox`
WHERE message_id NOT IN
(
  SELECT message_id
  FROM
  (
    SELECT message_id
    FROM `shoutbox`
    ORDER BY message_id DESC
    LIMIT 30 -- Behåll så här många tupler
  ) foo
);

Man måste dock gå in i preferences och stänga av "safe mode" för det hindrar borttagning eller updates utan angivande av PK.

Conny Westh 2013-04-13 15:08

Efter lite intrimning så kom jag fram till den här SQL-satsen som blir lite snabbare särskilt om det är många rader man vill behålla:

Kod:

DELETE FROM `shoutbox`
WHERE message_id <=
(
    SELECT message_id
    FROM
    (
      SELECT message_id
      FROM `shoutbox`
      ORDER BY message_id DESC
      LIMIT 1 OFFSET 30 -- Behåll så här många tupler
    ) foo
);


Conny Westh 2013-04-13 15:13

Gör om det hela till en Stored Procedure så blir det enklare att anropa från prograkoden och det blir enklare att göra ändringar:

Kod:

USE `secag`;

DROP procedure IF EXISTS `DeleteAllMessagesButLast30`;

DELIMITER $$
USE `secag`$$
CREATE PROCEDURE `secag`.`DeleteAllMessagesButLast30` ()
BEGIN
        DELETE FROM `shoutbox`
        WHERE message_id <=
        (
                SELECT message_id
                FROM
                (
                  SELECT message_id
                  FROM `shoutbox`
                  ORDER BY message_id DESC
                  LIMIT 1 OFFSET 30 -- Behåll så här många tupler
                ) foo
        );
END$$
DELIMITER ;

För att anropa SPn från ditt program behöver du bara köra denna SQL-sats:

Kod:

CALL `secag`.`DeleteAllMessagesButLast30` ();

secag 2013-04-13 15:19

Conny, efter testast MySQL koden så fick jag detta:
PHP-kod:

#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 


Conny Westh 2013-04-13 15:36

Citat:

Ursprungligen postat av secag (Inlägg 20467357)
Conny, efter testast MySQL koden så fick jag detta:
PHP-kod:

#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 


Jag såg detta fel, har lösningen i inlägg 11 och 12....

secag 2013-04-13 20:38

Såg inte att det fanns en sida 2 när jag postade :-)

Det funkar nu i alla fall. Men PROCEDURE är typ som en funktion fast i SQL? Hur tillämpar jag detta då? Jag kör liksom bara en enkel $db->query("SQL"); i mitt PHP-skript. Ska jag lägga in den där proceduren i SQL innan?

Conny Westh 2013-04-14 01:51

Du måste först lägga in proceduren i MySQL, det gör du från administrationsverktyget och kör detta som en SQL-sats (enligt första Code-rutan i inlägg #12 i denna tråd). När det väl har körts kan du testa att den funkar enligt andra Code-rutan i inlägg #12 i denna tråd.


Så här skriver du i PHP för att anropa en SP:

Kod:

if (!$db->query("CALL DeleteAllMessagesButLast30()"))
{
    echo "CALL failed: (" . $db->errno . ") " . $db->error;
}

Se mer info på länken: http://php.net/manual/en/mysqli.quic...procedures.php

Clarence 2013-04-14 10:31

Stor cred till Conny för hans hjälpsamhet som i många andra SQL-trådar.

Jag vill bara passa på att säga att stored procedures har både många fördelar och nackdelar. För det mesta används de inte för webb-applikationer med MySQL (förutom möjligtvis inom ASP.NET-världen där de nog inte är ovanliga trots MySQL). Men det finns 100 anledningar till att använda dom och 100 anledningar till att inte använda dom beroende av situation, arkitektur, applikation, organisation och inte minst databasmjukvaran.

Conny Westh 2013-04-14 15:58

Eftersom MySQL stöder SP numera så finns möjligheten att använda SP och då höjer du prestanda och förbättrar enkelheten i dina PHP-applikationer samt du kan höja säkerheten.

Man har dessutom möjligheten till att samla all affärslogik på ett enda ställe, i databasen.

Fördelarna är många, nackdelarna väldigt få.

Clarence 2013-04-14 17:51

Citat:

Ursprungligen postat av ConnyWesth (Inlägg 20467391)
Eftersom MySQL stöder SP numera så finns möjligheten att använda SP och då höjer du prestanda och förbättrar enkelheten i dina PHP-applikationer samt du kan höja säkerheten.

Man har dessutom möjligheten till att samla all affärslogik på ett enda ställe, i databasen.

Fördelarna är många, nackdelarna väldigt få.

Regler i all ära. Men svart och vitt är svårt att hitta.

SP anses generellt vara snabbare för att frågan bara behöver parsas och optimeras en gång.

Med MySQL så har varje session (tråd) en egen cache som måste byggas. Det betyder dels att nyttan blir väldigt liten och att det vid hög concurrency och många SPs riskerar att få totalt motsatt effekt då minnesanvändning per tråd riskerar att dra iväg. Detta förutsatt att du inte har någon connection pooling på applikationsnivå, vilket är sant för över 99% av webbapplikationer med PHP.

Så ur prestandasynpunkt finns det för MySQL ingen poäng att använda SPs förutom om man har en effektiv connection pooling för sin applikation.

Angående huruvida det rent arkitekturmässigt är en bra approach finns det många aspekter att väga in, t ex:
- Versionshantering och continous integration - blir mycket mer avancerade och omständiga om man väljer att lägga sin affärslogik i SPs.
- Du blir beroende av en databas. Vill du stödja flera olika databassystem senare med samma mjukvara så är det bara att börja om från början med ALL affärslogik.
- Vill man ha all affärslogik i databasen blir det allt som oftast en konflikt vid hantering av större mängder binär data. I databasen trots att det är ett ineffektivt val eller separera den biten av affärslogiken och därmed inte ha allt i databaslagret.
- Ska flera avdelningar/företag/applikationer osv gå direkt mot samma databas KAN det vara en fördel att använda SPs men det gör inte sällan att det skapas förutsättningar om hur andra ska använda datan.
- SPs är lätta att testa isolerat, men gör integrationstester desto svårare.
- Användande av SPs lägger ofta onödigt mycket last i databaslagret vilket är den svåraste delen att skala och optimera.
- Använder du ett smidigt applikationsspråk så är utvecklingstiden och tiden som går åt till underhåll desto högre i SPs (inkluderar ASP.NET, PHP, RoR etc).

Inte på något sätt uttömmande. Det finns mängder av IFs och BUTs som gör det lämpligare eller olämpligare. Men att blanda affärslogik i applikationen och i SPs skulle jag vilja påstå är något man helt och hållet ska hålla sig borta ifrån. Vilket nog precis blir fallet för TS.

danjel 2013-04-15 11:40

Intressant, har tidigare funderat på varför SP's anses mer av "best practice" i asp.net världen medans det i php/mysql inte är så diskuterat eller använt.

Hur brukar ni hantera stora SQL frågor, lägger ni dem i ett "datalager" ?
Det känns bökigt när man har sql frågor med typ 10 joins att lägga in dem i en vanlig php sträng, jag har tidigare övervägt att lägga in dessa i SP's istället för att få enklare underhåll.

Clarence 2013-04-15 12:18

Citat:

Ursprungligen postat av danjel (Inlägg 20467456)
Intressant, har tidigare funderat på varför SP's anses mer av "best practice" i asp.net världen medans det i php/mysql inte är så diskuterat eller använt.

Hur brukar ni hantera stora SQL frågor, lägger ni dem i ett "datalager" ?
Det känns bökigt när man har sql frågor med typ 10 joins att lägga in dem i en vanlig php sträng, jag har tidigare övervägt att lägga in dessa i SP's istället för att få enklare underhåll.

Vad man generellt föredrar är mycket av en smakfråga, det finns argument åt båda hållen. Jag tror att det mest avgörande är huruvida man oftare jobbat i organisationer med dedikerade DBAs/databasutvecklare eller en organisation där specifikationerna av affärslogiken är väldigt fasta och strukturerade. Då tror jag man oftare föredrar SPs.

Själv föredrar jag generellt att hålla mig borta från SPs av främst 2 anledningar.
- Lättare byggprocess och inget extra att tänka på vid förändringar i affärslogik utan förändringar i databasstruktur (vilket iallafall under mina 15 år med webb varit mycket mycket vanligare).
- Snabbare utvecklings i ett välutvecklat scriptspråk vilket leder till fler personer med kompetens.

Och alternativen är inte SPs eller en sträng i ett scriptspråk. Query builders, content repositories, ORMs osv finns bibliotek för i alla språk.

Vidare vet jag inte huruvida det är så etablerat som best practice generellt i .NET. Använder du entity framework t ex är det väl snarare tvärtom (går att använda men är manuellt extrapill, tror jag?). Och det är väl ändå välanvänt?

danjel 2013-04-15 16:02

Citat:

Ursprungligen postat av Clarence (Inlägg 20467460)
Och alternativen är inte SPs eller en sträng i ett scriptspråk. Query builders, content repositories, ORMs osv finns bibliotek för i alla språk.

Ja, lite off topic men mina erfarenheter av ORM's , Query builders , är inte så omfattande i php men är direkt hemska när det gäller avancerade frågor. Om man nu inte har stenkoll på det verktyg som används.
Men givet att man vill använda ren sql är det väl endast Sp eller sträng sql som gäller,eller Vyer.

Citat:

Ursprungligen postat av Clarence (Inlägg 20467460)
Vidare vet jag inte huruvida det är så etablerat som best practice generellt i .NET. Använder du entity framework t ex är det väl snarare tvärtom (går att använda men är manuellt extrapill, tror jag?). Och det är väl ändå välanvänt?

Ja det är sant , SP's försvinner en del vad gäller EF (eller motsvarande ORM's) som ju är tämligen poulärt nu.
Men har man SQL direkt i c# koden brukar en del tycka det är rätt illa. Säker delvis p.g.a att det krävs omkompilering av Visual Studio projektet för att ändra sql:en.

secag 2013-04-15 22:07

Har ett nytt problem nu.

Koden för att få "total_power" ifrån enskilda spelare fungerar bra. Men nu har jag en tabell med en lista på spelare där jag måste räkna ihop allas "total_power" till en enda stor summa. Vi kan kalla den "MEGA_TOTAL_POWER".

Jag tror att man någonstans skall lägga en s.k. sub-query?

Här är mitt försök vilket ger mig ett felmeddelanden som jag inte kan förstå:
PHP-kod:

SELECT *,
       
SUM
  
(SELECT CASE WHEN items.item_stat IS NULL THEN members.member_attack members.member_defence ELSE SUM(items.item_stat) + members.member_attack members.member_defence END AS total_power
   FROM members
   LEFT JOIN memberitems ON members
.member_id memberitems.memberitems_member
   LEFT JOIN items ON memberitems
.memberitems_item items.item_id
   GROUP BY members
.member_id) AS MEGA_TOTAL_POWER
FROM crews
WHERE id 


Här är tabellen 'crews'. Denna lagras alla olika allianser/grupper/klaner.

PHP-kod:

CREATE TABLE IF NOT EXISTS `crews` (
  `
idint(11NOT NULL AUTO_INCREMENT,
  `
namevarchar(20NOT NULL,
  `
moneyint(11NOT NULL,
  `
taxtinyint(3unsigned NOT NULL,
  `
attackint(10unsigned NOT NULL,
  `
defenceint(10unsigned NOT NULL,
  
PRIMARY KEY (`id`)
ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=;

INSERT INTO `crews` (`id`, `name`, `money`, `tax`, `attack`, `defence`) VALUES
(1'MuggemGansters'0000); 

Här är tabellen som lagras alla som är med i laget.

PHP-kod:

CREATE TABLE IF NOT EXISTS `crew_members` (
  `
crew_idint(11NOT NULL,
  `
user_idint(11NOT NULL,
  `
statustinyint(4NOT NULL
ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `crew_members` (`crew_id`, `user_id`, `status`) VALUES
(119); 

Hittade denna länk om det kan vara till min hjälp?
http://www.sqlteam.com/article/aggre...ed-sub-queries

danjel 2013-04-16 14:15

Jag skulle nog försöka dela upp det i fler queries och undvika sub queries.

Den länken gäller sql server så det kan vara felaktig info även om sql standarden kan vara korrekt.

secag 2013-04-16 14:21

Flera querys har väl en tendens att bli jobbiga? Alltså mer krävande?

danjel 2013-04-16 16:29

Citat:

Ursprungligen postat av secag (Inlägg 20467578)
Flera querys har väl en tendens att bli jobbiga? Alltså mer krävande?

Det beror på. Det man ska undvika är att köra querys i php loopar.
Men det kan faktiskt gå snabbare om du istället för en avancerad sql kör två, tre enskilda queries och kanske gör vissa summeringar i php istället, vilket avlastar databasen.
Det kan även vara lättare att felsöka och optimera de enskilda frågorna mha EXPLAIN Select.
Nu har jag svårt att greppa just detta case, men om det går att dela upp det så tycker jag du ska testa det..

secag 2013-04-16 16:36

Okej men jag kan förklara hur det ska vara.

En tabell heter crews, den hämtar jag all information ifrån "FROM crews"

En tabell som heter crew_members där det kan finnas upp till 80 rader. Här gör jag "JOIN crew_members ON crews.id = crew_members.crew_id"

Och crew_members innehåller endast user_id & crew_id. Ifrån detta user id så vill jag hämta en hel del information(åtminstone username och sen total_power). Vill inte loopa en query 80 gånger, känns som det blir mycket segare då.

Conny Westh 2013-04-17 02:08

Kan du bidra med koden för att få fram total_power som väl fungerar.

Kan du bidra med fler INSERT-satser så man kan få lite testdata att jobba med?

lubic 2013-04-17 08:43

Har inte helt koll på vad du vill göra och eller hur dina tabeller ser ut, men om jag inte är helt fel ute så borde du kunna göra något liknande detta:

SELECT m.username (eller liknande för att plocka ut de kolumner du vill ha)
FROM crew c
JOIN crew_members cm on cm.crew_id = c.crew_id
JOIN members m on m.user_id = cm.user_id
WHERE c.crew_id = 1 (eller vilket id du vill hämta ut medlemmarna ifrån)

Vill du även ta ut t.ex. total_power så får du joina på de tabeller som innehåller informationen om detta (items? om jag minns rätt från tidigare poster?) samt gruppera på m.user_id och göra en summering på alla items för varje medlem.

secag 2013-04-17 10:32

Löste det på egen hand..
PHP-kod:

SELECT SUM(t.totPower) AS total_crew_power
FROM crew_members cm
JOIN members m ON m
.member_id cm.user_id
JOIN
  
(SELECT m.member_id,
          (
SUM(i.item_stat) + MAX(m.member_attack) + MAX(m.member_defence)) AS totPower
   FROM members m
   JOIN memberitems mi ON m
.member_id mi.memberitems_member
   JOIN items i ON i
.item_id mi.memberitems_item
   GROUP BY m
.member_id)t ON t.member_id m.member_id
WHERE cm
.crew_id = {$id}
GROUP BY cm.crew_id 

Nytt problem!

Med denna query:
PHP-kod:

SELECT members.*, 
CASE 
WHEN items.item_stat IS NULL 
THEN 
members
.member_attack members.member_defence
ELSE 
SUM(items.item_stat) + members.member_attack members.member_defence
END 
AS total_power
FROM members
LEFT JOIN memberitems ON members
.member_id memberitems.memberitems_member
LEFT JOIN items ON memberitems
.memberitems_item items.item_id
GROUP BY members
.member_id
ORDER BY total_power DESC
members.member_id LIMIT 20 

så vill jag också hämta memberitems för varje member som jag gör med denna query:

PHP-kod:

SELECT *
FROM `memberitems`
JOIN `itemsON items.item_id memberitems.memberitems_item
WHERE memberitems
.memberitems_member = {MEMBER_ID

Problemet nu är att första queryn ger en row per member men varje member kan ha flera items. Om detta ska gå måste jag då göra en ny tabell i queryn där jag lägger alla memberitems i en column och sedan gör en SELECT på den columnen och sedan tömmer den tabellen mellan varje member och tar bort den när queryn är klar.

Hoppas att någon hänger med i min tankegång eller har en bättre lösning

lubic 2013-04-17 11:18

Hänger inte riktigt med på vilket resultat du vill ha ut i din senaste fråga. Alltså vilka kolumner och data vill du få fram?

Hur ska du använda resultatet? Ska du visa en lista på medlemmar med total power, samt alla items de har? Om det inte är för många medlemmar som ska visas per sida så är det nog enklare/bättre att lösa detta i php-koden med flera querys. Antingen en med alla medlemmar och deras total power och sedan en per medlem för att hämta upp deras items till den medlemmen eller en för alla medlemmarna och en för alla items för dessa medlemmar och sedan php-logik för att sätta ihop resultaten.

Alternativt kan du titta på group_concat, om du bara behöver en textsträng med items dvs.

Då kan också så klart joina ihop member data med total power och items med en subquery för att få ut allt i samma fråga.

Conny Westh 2013-04-17 23:03

Så här skulle du konna lägga in get_crew_power() som en SP:

Kod:

DELIMITER $$

CREATE PROCEDURE `get_crew_power`(in param_crew_id int)
BEGIN
        SELECT SUM(t.totPower) AS total_crew_power
        FROM crew_members cm
        JOIN members m ON m.member_id = cm.user_id
        JOIN
          (SELECT m.member_id,
                          (SUM(i.item_stat) + MAX(m.member_attack) + MAX(m.member_defence)) AS totPower
          FROM members m
          JOIN memberitems mi ON m.member_id = mi.memberitems_member
          JOIN items i ON i.item_id = mi.memberitems_item
          GROUP BY m.member_id)t ON t.member_id = m.member_id
        WHERE cm.crew_id = param_crew_id
        GROUP BY cm.crew_id  ;

END$$

För att anropa SPn från PHP MED felhantering skriver du så här:

Kod:

if (!$db->query("CALL get_crew_power(" . crew_id . ")"))
{
    echo "CALL failed: (" . $db->errno . ") " . $db->error;
}


För att anropa SPn från PHP UTAN felhantering skriver du så här:

Kod:

$db->query("CALL get_crew_power(" . crew_id . ")")


Alla tider är GMT +2. Klockan är nu 14:04.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson