Newsgroup: it.comp.www.php
Titolo: [mysql] Comparare velocemente Variabili "Allow Null": quale migliore?

Ciao a tutti, ho bisogno di voi!
Ho una tabella mysql 4.1 con due campi di tipo tinyint "Allow Null".
Chiamiamo i campi flag_utente e flag_gruppo.
Essi contengono valori 1 oppure 0 oppure NULL.
Devo valutarli e restituire vero o falso (1 o 0).
Questa la tavola di verità:
flag_utente  flag_gruppo  return
           0            0       0
           0            1       0
           0         null       0
           1            0       0
           1            1       1
           1         null       1
        null            0       0
        null            1       1
        null         null       0
in pratica devo ottenere 1 se e solo se sono entrambe 1 oppure se uno è 
1 e l'altro e null.
Il metodo più veloce che o trovato è:
SELECT
   IFNULL( flag_utente AND flag_gruppo, 1 )
   AND NOT ( flag_utente IS NULL
             AND
             flag_gruppo IS NULL )
oppure questo
SELECT
   IFNULL( CASE WHEN flag_utente < 1 THEN NULL ELSE flag_utente END
           OR
           CASE WHEN flag_gruppo < 1 THEN NULL ELSE flag_gruppo END, 0)
Quale è migliore?
Qualcuno sa fare di meglio?
grazie veramente un sacco grosso!


sono un babbeo, scusate tutti:
SELECT
   IFNULL(flag_utente OR flag_gruppo, 0)


sono un babbeo al quadrato.... 0 or 1 = 1 invece devo avere 0....

1 e l'altro e null.
Quindi basta che nessuno sia 0.
Select * from tabella where flag_utente!=0 and flag_gruppo!=0
-- 
Per rispondermi togli il cappello

 
non credo che risponderebbe bene..
io direi..
SELECT * FROM tabella WHERE flag_utente OR flag_gruppo;
-- 
www.iuz-lab.info


non è proprio vero... ecco cosa ritorna la tua funzione:
flag_utente  flag_gruppo  ->> tua_funzione <<-
           0            0             0
           0            1             0
           0         null             0
           1            0             0
           1            1             1
           1         null          null   invece di 1
        null            0             0
        null            1          null   invece di 1
        null         null          null   invece di 0
dai, so che potete fare di meglio!!

 
idem come prima...

 idem come prima...
posta la versione di MySQL che usi e la definizione della tabella compresi i
relativi insert..
MySQL 4.0.21
CREATE TABLE `flag` (
  `flag0` int(11) default NULL,
  `flag1` int(11) default NULL
) TYPE=MyISAM;
INSERT INTO `flag` VALUES (NULL, NULL);
INSERT INTO `flag` VALUES (0, NULL);
INSERT INTO `flag` VALUES (1, NULL);
INSERT INTO `flag` VALUES (0, 0);
INSERT INTO `flag` VALUES (1, 1);
INSERT INTO `flag` VALUES (NULL, 1);
SELECT * FROM `flag` WHERE `flag0` OR `flag1`;
+-------+-------+
| flag0 | flag1 |
+-------+-------+
|     1 |  NULL |
|     1 |     1 |
|  NULL |     1 |
+-------+-------+
3 rows in set (0.00 sec)
-- 
www.iuz-lab.info

 idem come prima...
SELECT * 
FROM `flag` 
WHERE (flag0 OR ISNULL(flag0)) AND (flag1 OR ISNULL(flag1)) AND 
(ISNULL(flag0) AND ISNULL(flag1))
SELECT * 
FROM `flag` 
WHERE (flag0 OR flag1) AND ((ISNULL(flag0) XOR ISNULL(flag1)) OR (flag1 AND
flag0))
ma se fossi in te eliminerei l'ambiguita' tra 0 e NULL..
che significati hanno questi flag?
-- 
www.iuz-lab.info


purtroppo non posso eliminare null, i flag rappresentano dei permessi 
dati a livello di utente e/o di gruppo: 1 = ha accesso, 0 = non ha 
accesso, null ha accesso se il gruppo ha accesso. E quindi devo valutare 
l'ambiguità del null (che comunque può sempre essere presente in quanto 
ho delle left join)
Però riflettendo potrei assegnare dei valori diversi... mi spiego meglio:
se assumo
   accesso negato            = 0 (invece di 0)
   accesso dipende da gruppo = 1 (invece di null)
   accesso negato            = 3 (invece di 1)
posso scrivere
   case when ifnull(flag0,0)+ifnull(flag1,0)<2 then 0 else 1 end
E poi come faccio a sapere quale è la più veloce???

   case when ifnull(flag0,0)+ifnull(flag1,0)<2 then 0 else 1 end
fai cosě invece
accesso negato            = 0 (invece di 0)
accesso negato            = 1 (invece di 1)
accesso dipende da gruppo = 2 (invece di null)
In questo modo devi modificare ancora meno il codice.
Alla luce di questo cambiamento la tabella sarebbe:
flag_utente  flag_gruppo  ->> tua_funzione <<-
           0            0             0
           0            1             0
           0            2             0
           1            0             0
           2            0             0
           2            2             0
           1            1             1
           1            2             1
           2            1             1
o sbaglio?
In questo caso hai autorizzazione solo nel caso in cui
(flag_utente!=0 AND flag_gruppo!=0) AND (flag_utente+flag_gruppo!=4)
Spero di aver capito bene.
Lo so che la soluzione sembrerebbe hard coded, ma credo funzioni.
Ciao