[PHP] selezionare colonne in comune con un altra tabella

samurai.sette

Utente Attivo
17 Dic 2015
204
5
18
Ciao a tutti. Avrei bisogno di un vostro aiutino.
Nel mio database ho due tabelle così composte.
Tab 1
id | nomi_colonne | visibilità

1 | valore1 | SI
2 | valore2 | NO
3 | valore3 | NO
4 | valore4 | SI

Tab 2
id | valore1 | valore2 | valore3 | valore4

Quello che dovrei fare è questo: dalla tabella2 devo selezionare soltanto le colonne che hanno "visibilità" uguale a SI nella tabella1. Nel caso in esame, selezionare soltanto le colonne "valore1" e "valore4".
Secondo voi come potrei fare?
Ciao, grazie mille a tutti.
 

Eduadie

Utente Attivo
22 Mar 2013
58
7
8
www.mrrobotbet.altervista.org
Una prima soluzione che mi viene in mente è di lanciare una query per controllare quale dei valori ha SI e costruire una seconda query selezionando solo le colonne della tab2 con valore attraverso una semplice concatenazione di stringhe.

$sql1 = "SELECT visibilità FROM tab1"
$testo = "";
creo l'array dei risultati e lo itero.
per ogni visibilità uguale a SI
$testo .= valore1, ;
alla fine creo la query finale
$sql2 = "SELECT " . $testo . "FROM tab2"

Spero di essere stato chiaro.
 

marino51

Utente Attivo
28 Feb 2013
2.597
132
63
Lombardia
queste sono le tabelle come le hai descritte, con i relativi valori

Codice:
DECLARE @tab1 TABLE
(
id           int,
nomi_colonne varchar(10),
visibilita   varchar(2)
);

DECLARE @tab2 TABLE
(
id           int,
valore1      varchar(10),
valore2      varchar(10),
valore3      varchar(10),
valore4      varchar(10)
);

INSERT INTO @tab1 ( id, nomi_colonne, visibilita ) VALUES (11, 'valore1', 'SI');
INSERT INTO @tab1 ( id, nomi_colonne, visibilita ) VALUES (12, 'valore2', 'NO');
INSERT INTO @tab1 ( id, nomi_colonne, visibilita ) VALUES (13, 'valore3', 'NO');
INSERT INTO @tab1 ( id, nomi_colonne, visibilita ) VALUES (14, 'valore4', 'SI');

INSERT INTO @tab2 ( id, valore1, valore2, valore3, valore4 ) VALUES (1, 'colonna1', 'colonna2', 'colonna3', 'colonna4');
questa è la query, scritta in modo da semplificare la select, vedi se riesci ad implementarla (tutti i comandi costituiscono un'unica query)

Codice:
DECLARE @col1 AS NVARCHAR(2),
        @col2 AS NVARCHAR(2),
        @col3 AS NVARCHAR(2),
        @col4 AS NVARCHAR(2);

set @col1 = ( SELECT visibilita FROM @tab1 WHERE nomi_colonne = 'valore1' );
set @col2 = ( SELECT visibilita FROM @tab1 WHERE nomi_colonne = 'valore2' );
set @col3 = ( SELECT visibilita FROM @tab1 WHERE nomi_colonne = 'valore3' );
set @col4 = ( SELECT visibilita FROM @tab1 WHERE nomi_colonne = 'valore4' );

SELECT
    ( CASE WHEN @col1 = 'SI' THEN valore1 ELSE null END ) valore1,
    ( CASE WHEN @col2 = 'SI' THEN valore2 ELSE null END ) valore2,
    ( CASE WHEN @col3 = 'SI' THEN valore3 ELSE null END ) valore3,
    ( CASE WHEN @col4 = 'SI' THEN valore4 ELSE null END ) valore4
FROM @tab2;
questo è il risultato

upload_2018-4-4_20-51-18.png
 

samurai.sette

Utente Attivo
17 Dic 2015
204
5
18
Ciao a tutti e grazie per l'aiuto.
Ho provato a fare in questo modo ma ciò non mi convince del tutto.
PHP:
<?php
    if (isset ($_POST['bottone']))
    {
        $con = mysqli_connect ("localhost","root","","database");
        $array_colonne = array();
        $db = mysqli_query ($con, "SELECT nomi_colonne FROM tabella_ok");
        while ($row = mysqli_fetch_array($db))
        {
            $array_colonne[] = $row['nomi_colonne'];
        }
      
        $num_colonne = count($array_colonne);
        $i = 0;
      
        for ($i = 0; $i <= ($num_colonne - 1); $i++)
        {
            $nomi_col = $array_colonne[$i];
            $db1 = mysqli_query ($con, "SELECT $nomi_col FROM tabella1 ORDER BY id");
            while ($row1 = mysqli_fetch_array($db1))
            {
                echo $row1[0] . "<br />";
            }     
        }     
    }
?>
Quello che non mi convince è il ciclo for. Facendo in questo modo l'estrazione dei dati dalla tabella è più lenta.
Secondo voi come potrei migliorare la cosa?
Ciao, grazie mille a tutti.
 

macus_adi

Utente Attivo
5 Dic 2017
1.030
59
48
IT/SW
Verticalizzando il DB l'accesso seppur all'aumentare dei dati diventa sensibilmente più lento, hai la possibilità di non rimanere bloccato con una struttura impostata (bloccata) e soprattutto non devi mettere mani alla query.
Parametrizzando bene i problemi sopra citati (seppur argomentati con valide soluzioni) bloccano la struttura dati rendendo l'ampliamento (aggiunta di un valore) di difficile gestione.
Credo che il Modello Wordpress sia da prendere in considerazione per la memorizzazione dei dati, ossia

id|ref_ |meta_key|meta_value|status
1 |1 | valore_1 | valore memorizzato| 1
2 |1 | valore_2 | valore memorizzato |0
etc....
In questo modo aggiungendo e/o eliminando chiavi "meta_key" non dovrai rimettere mani al codice.

Banalmente sia se aggiungi o elimini chiavi, la query sarà sempre questa:
Codice:
SELECT * FROM TBL WHERE status = 1
 

marino51

Utente Attivo
28 Feb 2013
2.597
132
63
Lombardia
Ho provato a fare in questo modo ma ciò non mi convince del tutto
mi sembra che il risultato sia l' elenco dei valori senza considerare se visibili o no,
e senza considerare che si perde il legame con id della riga

upload_2018-4-5_22-38-13.png

avevo capito che ti servisse una soluzione che potesse estrarre le righe selezionate, senza visualizzare le colonne "NO"

upload_2018-4-5_22-42-16.png

Visto che preferisci la soluzione con php, la trovi di seguito, a te rimettere "msqli"
PHP:
$select_colonne = "";
$sth = $db->query("SELECT nomi_colonne, visibilita FROM tabella_ok");
while( $row = $sth->fetch() )
{
    if ( !empty($select_colonne) ) $select_colonne .= ", ";
    $select_colonne .= ( $row['visibilita'] == "NO" ?  "null as " : "" ) . $row['nomi_colonne'];
}

$sth = $db->query("SELECT id, " . $select_colonne . " FROM tabella1 ORDER BY id");
while ( $row = $sth->fetch() )
{
    echo json_encode($row, JSON_PRETTY_PRINT)."<br />";
}
è chiaro che guida la "tabella_ok", per creare la query di selezione dei valori,
una soluzione che offre diverse opportunità
per esempio avere gruppi di colonne ..... per creare dinamicamente query di selezione diverse
 
Ultima modifica: