PDA

View Full Version : [MySQL]Non riesco a fare questa query mi aiutate?


mcHorney
09-06-2004, 23:06
Io proprio non ci riesco mi aiutate?

Tabella Contract
ContractCode | Description | Location | ecc
123 | vendita lana | Genova
256 | vendita tv | Genova
276 | vendita pc | Roma
896 | vendita pane | Roma
741 | vendita dolci | Milano
357 | vendita radio | Milano

Tabella UserContract
Login | ContractCode
Rossi | 123
Neri | 256
Neri | 123

Ecc ecc

In pratica io vorrei sapere per quali contratti relativamente per esempio a Genova NON è abilitato Rossi

In questo caso la risposta sarebbe 256.

Se chiedessi la medesima cosa ma riferita a Neri avrei come risposta un result set vuoto, infatti Neri è abilitato a tutti i contratti relativi alla zona di Genova.

Grazie, Mc

mailand
10-06-2004, 10:44
select contractcode, description from contract where contractcode<> (select distinct contractcode from usercontract )

mcHorney
10-06-2004, 10:49
Ti ringrazio ma il problema era proprio che con mysql non si possono usare le subquery :(

Purtroppo non posso usare la 4.1 che le supporta perchè è ancora alpha :(

Grazie, Mc

mcHorney
10-06-2004, 19:53
Ammeto che è una settimana che lavoro 16 ore al giorno ma si sorge il dubbio di esser diventato stupido ed anche molto.

Continuo a non riuscire a risolvere questo problema maledetto.

Allora senza considerare la tabella user e considerando solo:

CREATE TABLE UserContract(
Login VARCHAR(50) NOT NULL,
ContractCode int(11) NOT NULL,
PRIMARY KEY(Login,ContractCode),
INDEX(Login),
FOREIGN KEY(Login) REFERENCES Users(Login)
ON DELETE RESTRICT
ON UPDATE CASCADE,
INDEX(ContractCode),
FOREIGN KEY(ContractCode) REFERENCES Contract(ContractCode)
ON DELETE RESTRICT
ON UPDATE CASCADE) TYPE=INNODB;

e

CREATE TABLE Contract(
ContractCode INT NOT NULL,
Description VARCHAR(50) NOT NULL,
Location VARCHAR(50) NOT NULL,
ContractCurrency VARCHAR(3) NOT NULL,
CustomerCode VARCHAR(16) NOT NULL,
PRIMARY KEY (ContractCode),
INDEX(Location),
FOREIGN KEY (Location) REFERENCES Location(Location)
ON DELETE RESTRICT
ON UPDATE CASCADE) TYPE=INNODB;

Per ottenere quello che voglio, ossia i numeri di contratto per cui un determinato utente non è abilitato basterebbe una semplicissima query del tipo:

SELECT contractcode, description
FROM contract
WHERE contractcode NOT IN (SELECT contractcode FROM usercontract WHERE logi='rosssi')

Che avendo le subquery sarebbe una boiata ma io le subquery nonle ho, per cui dovrei riuscire ad arrangiarmi con un LEFT JOIN.

Farei:

SELECT contractcode, description
FROM contract
LEFT JOIN usercontract
ON contract.contractcode=usercontract.contractcode
WHERE usercontract.contract IS NULL
and usercontract.login='rossi'

Ebbe non funziona, però ho notato che se faccio

SELECT contractcode, description
FROM contract
LEFT JOIN usercontract
ON contract.contractcode=usercontract.contractcode
WHERE usercontract.contract IS NULL

Mi restiuisce tutti i contretti contenuti in contract ma non presenti in usercontract.

Spero solo che qualcuno abbia l' idea buona, in ogni caso grazie a tutti per l' attenzione e gli aiuti.

cionci
10-06-2004, 20:23
In MySQL ci sono le variabili utente...puoi utiizzare queste per creare una stringa con CONCAT in modo da immettere la stringa ottenuta (e memorizzata nella variabile utente) nella seconda query immettendola come parametro della NOT IN...

mcHorney
10-06-2004, 20:33
Cionci non vorrei approfittare della tua genitlezza ma non è che potresti farmi vedere come si fa, perchè non l' ho mai fatto e non ho ben capito il tuo discorso.

Io uso la versione 4.0.18

Grazie di cuore per l' aiuto, Mc

mcHorney
10-06-2004, 20:51
Ho guardato il manuale di MySQL ma nonsono sicuro che la cosa possa funzionare, infatti supponiamo che nella variabile pippo abbia i seguneti valori (ma è possibile inserire più valori sempre nella stessa variabile?)

@pippo=512,523,518,788

Poi dovrei fare una cosa del tipo

SELECT contractcode, description
FROM contract
WHERE contractcode NOT IN @pippo

Ma lo statement NOT IN non è supportato solo dala 4.1 che è in alpha?

Io sono obbligato ad usare la 4.0.18.

Ciao, Mc

mcHorney
10-06-2004, 21:00
Come mi avevi suggertio con CONCAT posso inserire tutti i valori che mi servono in una variabile ma poi?

Ora provo poi posto i risultati.

Ciao; Mc

mcHorney
10-06-2004, 21:19
Come faccio con concat ad avere una cosa simile?

@pippo=512,523,518,788

SELECT @pippo:=CONCAT(contractcode) FROM usercontract WHERE login='rossi' (non va bene)

In pratica come faccio a mettere i risultati di una query del tipo:

SELECT contractcode FROM usercontract WHERE login='rossi' (1)

in una variabile @pippo? ed avere quindi @pippo=512,523,518,788 che poi sarebbe il result set della query (1)

A questo punto dovrei fare una cosa del tipo

SELECT contractcode, description
FROM contract
WHERE contractcode NOT IN @pippo

Ma non usando NOT IN

cionci
11-06-2004, 02:18
IN e NOT IN sono supportate anche dalla 4.0 soltanto non ci si possono fare subquery...

Comnque ti faccio un esempio di come creo la variabile...

mysql> set @c = NULL;
Query OK, 0 rows affected (0.00 sec)

mysql> select @c := CONCAT_WS(',',IDProdotto, @c) FROM Prodotti LIMIT 10;
+-------------------------------------+
| @c := CONCAT_WS(',',IDProdotto, @c) |
+-------------------------------------+
| 1 |
| 2,1 |
| 3,2,1 |
| 4,3,2,1 |
| 5,4,3,2,1 |
| 6,5,4,3,2,1 |
| 7,6,5,4,3,2,1 |
| 8,7,6,5,4,3,2,1 |
| 9,8,7,6,5,4,3,2,1 |
| 10,9,8,7,6,5,4,3,2,1 |
+-------------------------------------+
10 rows in set (0.00 sec)

Ho fatto LIMIT 10 solamente per creare un risutato nella seconda query...
Il problema è che non mi considera @c nella seconda query ?!?!?
Se scrivo:

SELECT * FROM Prodotti WHERE IDProdotto IN (10, 9);

funziona perfettamente...

Se scrivo:

SELECT * FROM Prodotti WHERE IDProdotto IN (@c);

non funziona...mi rende solamente il prodotto con ID = 10... Probabilmente è un problema di conversione in stringa... Ci sta che il tutto venga convertito in stringa e quando viene "stampato" all'interno della query è come se ci venisse scritto IN ('10,9.....') :confused:

Eppure sono convinto di averlo usato senza problemi una volta...

cionci
11-06-2004, 02:28
Risolto, ma sono convinto di non aver fatto così l'altra volta...

mysql> set @c = NULL;
Query OK, 0 rows affected (0.00 sec)

mysql> select @c := CONCAT_WS(',',IDProdotto, @c) FROM Prodotti LIMIT 10;
+-------------------------------------+
| @c := CONCAT_WS(',',IDProdotto, @c) |
+-------------------------------------+
| 1 |
| 2,1 |
| 3,2,1 |
| 4,3,2,1 |
| 5,4,3,2,1 |
| 6,5,4,3,2,1 |
| 7,6,5,4,3,2,1 |
| 8,7,6,5,4,3,2,1 |
| 9,8,7,6,5,4,3,2,1 |
| 10,9,8,7,6,5,4,3,2,1 |
+-------------------------------------+
10 rows in set (0.00 sec)

mysql> select * from Prodotti WHERE FIND_IN_SET(IDProdotto, @c) > 0;
+------------+-----------+----------------+
| IDProdotto | IDTabella | Tabella |
+------------+-----------+----------------+
| 1 | 1 | FioriRecisi |
| 2 | 2 | FioriRecisi |
| 3 | 3 | FioriRecisi |
| 4 | 4 | FioriRecisi |
| 5 | 5 | FioriRecisi |
| 6 | 1 | UtensiliManico |
| 7 | 2 | UtensiliManico |
| 8 | 6 | FioriRecisi |
| 9 | 7 | FioriRecisi |
| 10 | 8 | FioriRecisi |
+------------+-----------+----------------+
10 rows in set (0.00 sec)

mysql> select * from Prodotti WHERE FIND_IN_SET(IDProdotto, @c) = 0;
+------------+-----------+-------------+
| IDProdotto | IDTabella | Tabella |
+------------+-----------+-------------+
| 11 | 9 | FioriRecisi |
| 12 | 10 | FioriRecisi |
| 13 | 11 | FioriRecisi |
| 14 | 12 | FioriRecisi |
| 15 | 13 | FioriRecisi |
| 16 | 14 | FioriRecisi |
| 17 | 15 | FioriRecisi |
| 18 | 16 | FioriRecisi |
+------------+-----------+-------------+
8 rows in set (0.00 sec)

Ovviamente la penultima fa un IN e l'utlima un NOT IN...

mcHorney
11-06-2004, 10:10
Cionci grazie mille, mi hai insegnato una cosa nuova che non avevo mai usato.

Ciao, Mc

P.S. Ma la 4.1 di MySQL è in alpha da quasi un anno, ma quando uscirà mai la versione definitiva?