Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [MySQL] Problema JOIN unica tabella e logica particolare recupero dati granulare

    Salve,
    titolo dubbio perchè non so se è corretto dire "recupero dati granulare" MA vi illustro il problema che probabilmente risolvo con una singola query.

    Ho questa tabella strutturata così.

    Tabella X
    codice:
    +---+---------+----+------+----+-----+-------+------+
    | id | name   | f1 | f2   | f3 | tag | field | value |
    +---+---------+----+------+----+-----+-------+------+
    | 1  | test   | 13 |      |    |  A  |   C   |  1    |
    | 2  | test   | 13 | 10   |    |  A  |   C   |  2    |
    | 3  | test   | 13 | 10   |  5 |  A  |   C   |  3    |
    +---+---------+----+------+----+-----+-------+------+
    In pratica vado a salvare i valori (value) di alcuni campi (field) in funzione di name, f1 e tag.
    Ho però la possibiltà di salvare per la stessa terna di dati name, f1 e tag, altri valori in funzione di f2 e f3

    Ammettendo per esempio come nello schema che:
    name: test
    f1: 13
    tag: A
    Value = 1

    Nel caso però che:
    f2: 10
    Value = 2

    E infine che
    f2: 10
    f3: 5
    Value = 3

    Il mio problema è che vorrei fare una query che all'inserimento di valori errati di f2 OPPURE di f3, mi ritornasse il primo valore valido.

    ESEMPIO in pseudo codice:


    // recupera un valore in funzione del match dei valori $f1, $f2, $f3 e $tag nella tabella X
    // $f2 e $f3 sono entrambi opzionali
    // $f1, $tag e $field devono obbligatoriamente esistere (natural join)
    function get_value($f1, $f2, $f3, $tag, $value);


    get_value(13, 60, 20, 'A', 'C');
    // f2=60 e f3=20 non sono presenti quindi deve ritornare 1


    get_value(13, 10, 20, 'A', 'C');
    // f2=10 è prensete ma f3=20 non è presente quindi deve ritornare 2


    get_value(13, 10, 5, 'A', 'C');
    // tutti i valori f2, f3 sono presenti quindi deve ritornare 3


    E' possibile giocando un pò con LEFT join sulla sola tabella X ottenere un risultato come illustrato?
    Grazie mille, intanto continuo a fare test

    (p.s. con 3 query avrei risolto ma vorrei evitare inutile overhead)
    Ultima modifica di PazZII; 20-07-2014 a 22:26

  2. #2
    mmmm
    nessun ha qualche suggerimento?
    Stavo cercando di vedere se CASE THEN oppure IF THEN ELSE facessero al caso mio ma non capisco.
    In pratica la query dovrebbe essere


    codice:
    // function get_value($f1, $f2, $f3, $tag, $value);
    get_value(13, 60, 20, 'A', 'C');
    SELECT * FROM tabella X
    WHERE
    name = test AND
    f1 = 13 AND 
    tag = A
    IF f2=60 AND f3 = 20 THEN ( AND f2=60 AND f3=20)  // doppia condizione valida
    ELSE
    	f3 = NULL // taglia via il valore più profondo
    
    
    IF f2=60 THEN ( AND f2=60)		// singola condizione valida
    ELSE
    	f2 = NULL	// taglia via il valore medio

    In pratica:


    SE f2 e f3 esistono la query diventa:
    codice:
    SELECT * FROM tabella X WHERE  name = test AND f1 = 13 AND tag = A AND f2=60 AND f3=20

    Altrimenti


    SE esiste solo f2 la query diventa:
    codice:
    SELECT * FROM tabella X WHERE  name = test AND f1 = 13 AND tag = A AND f2=60 AND f3 = null

    SE non esistono nè f2 nè f3 la query diventa
    codice:
    SELECT * FROM tabella X WHERE  name = test AND f1 = 13 AND tag = A AND f2=null AND f3 = null

    Scala indietro il VALUE da prendere andando verso il più globale e il meno specifico
    Che casino da spiegare...

  3. #3
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Prova...

    codice:
    select *, case when f2 is null then 3 when f3 is null then 2 else 1 as pertinenza
    from tabella where name = $name and f1 = $f1 and ((f2 = $f2 and f3 = $f3) or (f2 = $f2 and f3 is null) or (f2 is null and f3 is null))
    order by pertinenza limit 1

  4. #4
    AH!
    faccio subito prove e ti faccio sapere.
    Grazie!

    p.s.
    tosto però come problema.
    Ultima modifica di PazZII; 23-07-2014 a 13:41

  5. #5
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    ...quindi?

  6. #6
    Stavo cercando di armeggiare con EXIST
    Ti spiego (nota END prima di as pertinenza):
    codice:
    select *, case when f2 is null then 3 when f3 is null then 2 else 1 END as pertinenzafrom tabella where name = $name and f1 = $f1 and ((f2 = $f2 and f3 = $f3) or (f2 = $f2 and f3 is null) or (f2 is null and f3 is null))
    order by pertinenza limit 1
    In pratica funziona ma non contempla l'eventualità che $f3 si sbagliato.
    Nel senso o esiste e c'è (caso =$f3) oppure è null ($f3 is null)
    Stesso discorso per $f2.
    Infatti nel caso in cui $f2 e/o $f3 siano inesistenti, dovrebbe scattare la clausola con pertinenza successiva e cioè quella dove prende i valori di $f2 e/o $f3 null

    E' questa l'utilità del meccanismo.
    Scalare indietro se il valore o i valori inseriti di $f2 e/o $f3 sono null OPPURE inesistenti.
    Intanto provo a pasticciare ancora e ti ringrazio comunque

  7. #7
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Sull'END hai ragione, me lo sono fumato. Ma sul resto non capisco quale sia il problema. Mi posti un caso in cui non esce quello che ti aspetti? Quello di cui parli dovrebbe essere il penultimo esempio che hai fatto nel primo post, non ti restituisce la seconda riga in quel caso?

  8. #8
    Lavorando con i dati della tabella del mio primo post questa query mi dà problemi:
    codice:
    select *, 
    case 
    when 
    f2 is null then 3 
    when f3 is null then 2 
    else 1 
    END as pertinenza
    from tabella 
    where 
    name = 'test' and f1 = 13 and ((f2 = 10 and f3 = '9999') or (f2 = 10 and f3 is null) or (f2 is null and f3 is null))
    order by pertinenza limit 1

    Dovrebbe restituire:
    codice:
    2  | test   | 13 | 10   |  null  |  A  |   C   |  2

    ma invece dà zero risultati.


    CREDO sia perchè non contempli il caso in cui ... and f3 not exist perchè nel secondo OR tu metti (f2 = 10 and f3 is null) ma '9999' non è null, semplicemente non esiste.

    O detto in altri termini....mettendo fr = '9999', nessuna di queste tre condizioni è vera.

    codice:
    ((f2 = 10 and f3 = '9999') or (f2 = 10 and f3 is null) or (f2 is null and f3 is null))
    Mannaggia non mi riesce di spiegarmi bene ...
    Ultima modifica di PazZII; 25-07-2014 a 12:05

  9. #9
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Quote Originariamente inviata da PazZII Visualizza il messaggio
    Tabella X
    codice:
    +---+---------+----+------+----+-----+-------+------+
    | id | name   | f1 | f2   | f3 | tag | field | value |
    +---+---------+----+------+----+-----+-------+------+
    | 1  | test   | 13 |      |    |  A  |   C   |  1    |
    | 2  | test   | 13 | 10   |    |  A  |   C   |  2    |
    | 3  | test   | 13 | 10   |  5 |  A  |   C   |  3    |
    +---+---------+----+------+----+-----+-------+------+
    Fammi capire: in questa tabella, nelle colonne f2 e f3, dove non hai indicato valori, cosa c'è?

  10. #10
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    Per qualche strano motivo ho risposto ma non ha aggiornato la data dell'ultimo post....

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.