aiuto query mysql

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

aiuto query mysql

Messaggioda darkstaring » lun feb 06, 2017 22:26

Buonasera, vorrei fare una query ma non sò da dove iniziare...

Ho una tabella Dipendenti ed una altra contratti, dove contratti ha all'interno id_dipendente come chiave esterna.....
Ora mi chiedo come posso sapere i dipendenti che non sono presenti nella tabella contatti senza l'uso di php ma con solo mysql?

spero di esser stato chiaro......
non ho mai fatto niente di simile :D

Grazie
Francesco

Avatar utente
conraid
Staff
Staff
Messaggi: 12933
Iscritto il: gio lug 14, 2005 0:00
Nome Cognome: Corrado Franco
Slackware: current64
Località: Livorno
Contatta:

Re: aiuto query mysql

Messaggioda conraid » mar feb 07, 2017 9:55

Oddio, mi son reso conto che dopo tanto tempo senza lavorare con sql mi son dimenticato le basi :/

Comunque dovrebbe essere questo
https://dev.mysql.com/doc/refman/5.7/en ... eries.html

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » mar feb 07, 2017 11:24

Grazie della risposta conraid .. ma non riesco..sapresti aiutarmi?
Ho messo giu questo
SELECT * FROM scadenza_contratti WHERE id_dip NOT EXISTS IN (SELECT id FROM dipendenti);
ma non funziona...
Sai aiutarmi?

Avatar utente
conraid
Staff
Staff
Messaggi: 12933
Iscritto il: gio lug 14, 2005 0:00
Nome Cognome: Corrado Franco
Slackware: current64
Località: Livorno
Contatta:

Re: aiuto query mysql

Messaggioda conraid » mar feb 07, 2017 11:51

Così su due piedi no, ho veramente rimosso tutto dal cervello, però la sottoquery non è come hai fatto tu, più una cosa simile a questa (sicuramente sbagliata eh :) tanto per farmi capire):

SELECT * FROM scadenza_contratti WHERE NOT EXISTS (SELECT * FROM dipendenti scadenza_contratti.id_dip = dipendenti.id)

al limite prova a mettere un esempio, popolo un database e provo (che mi serve anche per riprendere un po')

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » mar feb 07, 2017 12:07

Ti mostro la mia struttura

Codice: Seleziona tutto

CREATE TABLE IF NOT EXISTS dipendenti
                (
               id INTEGER primary key AUTO_INCREMENT,
               nome varchar(50) NOT NULL,
               cognome varchar(50) NOT NULL,
               data_nascita date,
               cod_fiscale varchar(16),
               telefono varchar(30) DEFAULT NULL,
               telefono_urgenza VARCHAR(30) DEFAULT NULL,
               email varchar(30) DEFAULT NULL,
               via varchar(30) DEFAULT NULL,
               citta varchar(30) DEFAULT NULL,
               cap varchar(5) DEFAULT NULL,
               descrizione TINYTEXT DEFAULT NULL,
               attivo BOOL not null,
               username VARCHAR(50) NOT NULL,
               passwd VARCHAR(50) NOT NULL,
               img_profile VARCHAR(30) DEFAULT NULL,
               UNIQUE (username)
                ) ENGINE=MyISAM;
               
               
CREATE TABLE IF NOT EXISTS scadenza_contratti
                (
               id INTEGER primary key AUTO_INCREMENT,
               id_dip INT NOT NULL,
               descrizione TINYTEXT DEFAULT NULL,
               data_inizio_contratto DATE NOT NULL,
               data_fine_contratto DATE NOT NULL,
               FOREIGN KEY (id_dip) REFERENCES dipendenti(id) ON DELETE CASCADE ON UPDATE CASCADE
                ) ENGINE=MyISAM;

agharta
Linux 1.0
Linux 1.0
Messaggi: 81
Iscritto il: lun dic 17, 2007 13:58
Località: Bassano del grappa

Re: aiuto query mysql

Messaggioda agharta » mer feb 08, 2017 8:56

select dip.* from dipendenti dip
left join scadenza_contratti sc on (dip.id = sc.id_dip)
where sc.id is null


Così è molto più veloce di un not exists/in(select...)

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » mer feb 08, 2017 22:54

agharta ha scritto:select dip.* from dipendenti dip
left join scadenza_contratti sc on (dip.id = sc.id_dip)
where sc.id is null


Così è molto più veloce di un not exists/in(select...)

Bravo agharta complimenti :D , ho appena visto e sto cercando di capire...
vorrei anche modificare in modo da avere tutti i dipendenti sia con contratto scaduto che senza...
Per ora facevo una query che mi restituisse i dipendenti e un ciclo tra di essi per vedere se con contratto regolare..
provo a modificare quel che mi hai scritto....
Grazie 1000 =D>

agharta
Linux 1.0
Linux 1.0
Messaggi: 81
Iscritto il: lun dic 17, 2007 13:58
Località: Bassano del grappa

Re: aiuto query mysql

Messaggioda agharta » gio feb 09, 2017 9:13

Codice: Seleziona tutto

select dip.* from dipendenti dip
left join scadenza_contratti sc on (
dip.id = sc.id_dip
)
where sc.id is null or sc.data_fine_contratto < CURRENT_DATE /*o la data che ti interessa*/


Provo a spiegarmi.
La tabella principale è quella dei dipendenti.
con la left join ci attacchi la scadenza_contratti matchando x id della tabella dei dipendenti.
In questo modo hai tutti i dipendenti con collegati i record di scandenza_contratti.
where sc.id_dip is null mi da i dipendenti che NON hanno dati in scadenza_contratti
or sc.data_fine_contratto < CURRENT_DATE mi da anche chi ha la data_fine_contratto inferiore ad oggi (scaduti)
select dip.* ....beh, ti da fuori la solo tabella dipendenti. se ti serve anche la colonna sc.data_fine_contratto basta che aggiungi un ", sc.data_fine_contratto"


Allo stesso modo puoi escludere quelli che hanno data_inizio_contratto > della data che ti interessa

Codice: Seleziona tutto

select dip.* from dipendenti dip
left join scadenza_contratti sc on (
dip.id = sc.id_dip
and sc.data_inizio_contratto <= CURRENT_DATE /*o la data che ti interessa*/
)
where sc.id is null or sc.data_fine_contratto < CURRENT_DATE /*o la data che ti interessa*/


La condizione or non è molto performante in sql, ti conviene inserire un indice nel campo data_fine_contratto e data_inizio_contratto.

Non conoscendo la versione di mysql utilizzata non posso ottimizzarla ulteriormente, spero ti basti.

Ciao

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » gio feb 09, 2017 13:47

Grazie ..funziona :D
Dovrei fare delle lezioni sulle join...Chissa quanto processore potrei rispiarmiare con un uso corrertto di mysql....

Grazie

agharta
Linux 1.0
Linux 1.0
Messaggi: 81
Iscritto il: lun dic 17, 2007 13:58
Località: Bassano del grappa

Re: aiuto query mysql

Messaggioda agharta » gio feb 09, 2017 17:40

Di nulla!

darkstaring ha scritto:---Chissa quanto processore potrei rispiarmiare con un uso corrertto di mysql....


Tantissimo! Personalmente, lavorando con i maggiori db vendor posso assicurarti un fattore velocità almeno 10x (ho casi di 2000x !!!!).

Ricordati di creare gli indici, in linea di massima le query vanno più veloci se utilizzano gli indici (e il motore db li usa in modo corretto....)

Ciaooo

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » sab giu 10, 2017 9:52

Salve a tutti...
vorrei prelevare dei record da diverse tabelle..

immagino una query simile a questa:

Codice: Seleziona tutto

select ind.*, orari.*
from cat_zone, zone,  dipendenti
left join indisponibilita as ind on ind.id_dipendente=dipendenti.id
LEFT JOIN orari on  orari.id_dipendente=dipendenti.id
WHERE orari.id_zona=zone.id AND zone.id_cat_zone=cat_zone.id AND date(orari.tempo_inizio) >= '2017-06-05' AND date(orari.tempo_fine) <= '2017-06-12' AND dipendenti.id=orari.id_dipendente ORDER BY orari.tempo_inizio, ind.tempo_inizio, dipendenti.cognome ;

Mi aspettavo NULL tra i record di indisponibilitama quando era presente un orario e viceversa...
invece tutti i record sono pieni:

Codice: Seleziona tutto

+------+-------------+---------------+---------------------+---------------------+------+---------+---------------+---------------------+---------------------+------------+
| id   | id_tipo_ind | id_dipendente | tempo_inizio        | tempo_fine          | id   | id_zona | id_dipendente | tempo_inizio        | tempo_fine          | definitivo |
+------+-------------+---------------+---------------------+---------------------+------+---------+---------------+---------------------+---------------------+------------+
|    2 |           1 |             3 | 2017-03-29 00:00:00 | 2017-03-31 23:59:00 |  108 |       1 |             3 | 2017-06-05 00:00:00 | 2017-06-05 11:00:00 |          0 |
|    3 |           1 |             3 | 2017-06-07 00:00:00 | 2017-06-09 23:59:00 |  108 |       1 |             3 | 2017-06-05 00:00:00 | 2017-06-05 11:00:00 |          0 |
|    1 |           1 |             2 | 2017-03-24 00:00:00 | 2017-03-25 23:59:00 |  109 |       2 |             2 | 2017-06-06 00:00:00 | 2017-06-06 10:00:00 |          0 |
|    1 |           1 |             2 | 2017-03-24 00:00:00 | 2017-03-25 23:59:00 |  110 |       2 |             2 | 2017-06-08 00:00:00 | 2017-06-08 10:00:00 |          0 |
|    1 |           1 |             2 | 2017-03-24 00:00:00 | 2017-03-25 23:59:00 |  111 |       2 |             2 | 2017-06-09 00:00:00 | 2017-06-09 10:00:00 |          0 |
|    1 |           1 |             2 | 2017-03-24 00:00:00 | 2017-03-25 23:59:00 |  112 |       2 |             2 | 2017-06-11 00:00:00 | 2017-06-11 10:00:00 |          0 |
+------+-------------+---------------+---------------------+---------------------+------+---------+---------------+---------------------+---------------------+------------+

Se non sono stato chiaro chiedete...Grazie

---
Allego il db

---
Ultima modifica di darkstaring il sab giu 17, 2017 12:55, modificato 1 volta in totale.

agharta
Linux 1.0
Linux 1.0
Messaggi: 81
Iscritto il: lun dic 17, 2007 13:58
Località: Bassano del grappa

Re: aiuto query mysql

Messaggioda agharta » sab giu 10, 2017 14:27

Ciao,
Io non vedo il problema: nel tuo file sql il campo indisponibilita.id_dipendente è not null e sempre valorizzato.
La left join è basata sull'id del dipendente, quindi sempre valida. Non viene mai filtrata dalla clausola where.
Ti consiglio di:
1. USARE LE PARENTESI NEI JOIN DOPO 'ON'
2. NON fare un prodotto cartesiano tra cat_zone, zone e dipendenti in quanto il risultato aumenta esponenzialmente all'aumentare dei record. Usa una inner join piuttosto, così sostituisci un po' di clausole where e non massacri cpu, disco e ram.
3. Crea degli indici. Non ne ho trovati nel tuo script. A runtime avrai problemi di presentazione se non li usi. Magari mettili sulle date e sul cognome, visto che è nell'order by.
4. Usa gli alias per tutte le tabelle.

Ciao

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » lun giu 12, 2017 12:29

agharta ha scritto:1. USARE LE PARENTESI NEI JOIN DOPO 'ON'
2. NON fare un prodotto cartesiano tra cat_zone, zone e dipendenti in quanto il risultato aumenta esponenzialmente all'aumentare dei record.
Usa una inner join piuttosto, così sostituisci un po' di clausole where e non massacri cpu, disco e ram.
3. Crea degli indici. Non ne ho trovati nel tuo script. A runtime avrai problemi di presentazione se non li usi. Magari mettili sulle date e sul cognome, visto che è nell'order by.
4. Usa gli alias per tutte le tabelle.


Grazie Agharta, ma non riesco...
1. USARE LE PARENTESI NEI JOIN DOPO 'ON' => OK
2. NON fare un prodotto cartesiano tra cat_zone, zone e dipendenti in quanto il risultato aumenta esponenzialmente all'aumentare dei record.
Usa una inner join piuttosto, così sostituisci un po' di clausole where e non massacri cpu, disco e ram.

Quà ho difficolta non ho capito...

3. Crea degli indici. Non ne ho trovati nel tuo script. A runtime avrai problemi di presentazione se non li usi. Magari mettili sulle date e sul cognome, visto che è nell'order by.

Quà ho difficolta non ho capito...


4. Usa gli alias per tutte le tabelle. => Credo ok se intendi "as"

------------------------------
In pratica vorrei avere come risultato una tabella con i record da orari e da indisponibilita... e se è un orario, devo avere anche tutte le info su zone e cat_zone...
Altrimenti tutto a null.. in modo da capire in php se è un orario oppure una indisponibilita
Spero di essere stato chiaro
------------------------------
Grazie

agharta
Linux 1.0
Linux 1.0
Messaggi: 81
Iscritto il: lun dic 17, 2007 13:58
Località: Bassano del grappa

Re: aiuto query mysql

Messaggioda agharta » lun giu 19, 2017 10:04

Ciao,
Perdonami ma ero in ferie.

2. Allora, quando fai un "from tabella1, tabella2" il motore sql moltiplica internamente le righe della tabella1 x la tabella 2 (tralascio volutamente le condizioni di where in quanto alcuni db ottimizzano in parte la moltiplicazione).
Questo significa che se tabella1 ha 10 record e tabella2 ne ha 100, il risultato in memoria prima del where sarà 1000 record. Viene da se che se le tabelle sono 3, come nel suo caso, ti troverai migliaia (milioni?) di record in memoria o in file temporanei del db per nulla, con notevole spreco di tempo/risorse.
Nel tuo caso la tabella cardine è la tabella dei dipendenti. Ti consiglio di partire da quella e fare degli inner/left join includendo le clausole where. Qui delle linee guida sui join http://www.w3resource.com/sql/joins/sql-joins.php

3. Il motore database tende ad usare degli indici, se presenti. Gli indici (almeno quelli standard) vengono aggiornati al momento dell'insert/update/delete di un record nella tabella. Se non ci sono gli indici il motore db dovrà scansionare riga per riga e campo per campo, rallentando di molto. Guarda qui http://www.w3resource.com/sql/creating- ... -index.php

Per il risultato, non trovo più il tuo script sql. Se lo ripubblichi (anche solo in parte) o me lo mandi in pv, vedo di prepararti una query ottimizzata.

Ciao

Avatar utente
darkstaring
Linux 2.6
Linux 2.6
Messaggi: 583
Iscritto il: mer ott 13, 2010 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: aiuto query mysql

Messaggioda darkstaring » lun giu 19, 2017 17:49

Sei stato chiarissimo....cercherò di risolvere con le join...
Allego il db
db.txt
(28.53 KiB) Scaricato 25 volte


Torna a “Programmazione”

Chi c’è in linea

Visitano il forum: Google [Bot] e 3 ospiti