2 messaggi dal 04 luglio 2009
ho alcuni problemi con delle query in sql ...chi mi aiuta….mi lascia una mail e spedirò li il testo…sono solo poche query. Grazie aiutatemi!....risp anke su quell'email...per piacere..
Modificato da multimedia00 il 04 luglio 2009 18.09 -
salve,
multimedia00 wrote:
ho alcuni problemi con delle query in sql ...chi mi aiuta….mi lascia una mail e spedirò li il testo…sono solo poche query. Grazie aiutatemi!....risp anke su quell'email...per piacere.. )  Modificato da multimedia00 il 04 luglio 2009 18.09 -

no, facciamo il contrario... postale qui e vediamo se ci sono anime gentili
diversamente non e' piu' "supporto" ma diventa "lavoro", e quello si "paga"
saluti

Andrea Montanari (Microsoft MVP - SQL Server)
http://www.asql.biz - http://italy.mvps.org
http://www.hotelsole.com - http://www.hotelsolericcione.de
non mi "piace" fare "i compiti" agli studenti, in quanto e' corretto che
"studino" e che eventualmente propongano le loro soluzioni da "correggere",
diversamente il tutto non ha senso..

per tua formazione, e' bene indicare quale dbms tu stia utilizzando, in modo
da far si che si possa eventualmente utilizzare il dialetto SQL preposto per
il motore..
e' altresi' bene postare il DDL ridotto di creazione delle tabelle coinvolte
in modo che chi si appresta ad aiutarti non debba inventarsi lo scenario di
esecuzione, ed ovviamente, oltre al DDL, e' bene specificare gli opportuni
comandi INSERT INTO al fine di prepopolare lo scenario senza far
"arrampicare sugli specchi" chi ti voglia aiutare...

detto cio', visto che sono le ore 22:30, vado a presentarti delle soluzioni
in Transact-SQL e quindi valide in SQL Server.. ho anche utilizzato una
common table expression che risulta utilizzabile solo a partire dalla
versione 2005 del motore relazionale..
ovviamente ci possono essere altre soluzioni, come sempre accade in
linguaggio SQL, ed ovviamente non ho fatto ricerca specifica e validazione
dei piani di esecuzione generati..
ho pero' utilizzato anche una tecnica di filtro specifica nella clausola di
JOIN che, seppure non direttamente ortodossa poiche' non espressa
formalmente nella clausola WHERE del comando, solitamente in SQL Server
riduce il prodotto cartesiano risultante dall'esplosione di join e quindi
produce una work table di cardinalita' inferiore nel risultato di join
finale, risultando quindi in "meno righe" prodotte da poi nuovamente
filtrare secondo la clausola WHERE..

SET NOCOUNT ON;
USE tempdb;
GO
CREATE TABLE dbo.Giornalista (
Id_Giornalista int NOT NULL,
Nome varchar(10),
Cognome varchar(10),
AnnoNascita int
);
CREATE TABLE dbo.Articolo (
Id_Articolo int NOT NULL,
Titolo varchar(10),
Testata varchar(10),
N_Colonne int
);
CREATE TABLE dbo.Scrive (
Id_Giornalista int,
Id_Articolo int
);
CREATE TABLE dbo.FotoReporter (
Id_Reporter int,
Nome varchar(10),
Cognome varchar(10),
AnnoNascita int
);
CREATE TABLE dbo.FotoArticolo (
Id_Articolo int,
Id_Reporter int
);
GO
INSERT INTO dbo.Giornalista VALUES ( 1, 'Lucio', 'Bianchi', 1967 );
INSERT INTO dbo.Giornalista VALUES ( 2, 'B', 'BB', 1970 );
INSERT INTO dbo.Giornalista VALUES ( 3, 'C', 'CC', 1970 );
INSERT INTO dbo.Giornalista VALUES ( 4, 'D', 'DD', 1970 );

INSERT INTO dbo.Articolo VALUES ( 1, 'A', 'Corriere', 1 );
INSERT INTO dbo.Articolo VALUES ( 2, 'B', 'Corriere', 1 );
INSERT INTO dbo.Articolo VALUES ( 3, 'C', 'BB', 2 );
INSERT INTO dbo.Articolo VALUES ( 4, 'D', 'BB', 2 );
INSERT INTO dbo.Articolo VALUES ( 5, 'E', 'BB', 2 );
INSERT INTO dbo.Articolo VALUES ( 6, 'F', 'CC', 1 );

INSERT INTO dbo.FotoReporter VALUES ( 1, 'Z', 'ZZ', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 2, 'V', 'VV', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 3, 'U', 'UU', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 4, 'T', 'TT', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 5, 'R', 'RR', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 6, 'S', 'SS', 1970 );
INSERT INTO dbo.FotoReporter VALUES ( 7, 'Q', 'QQ', 1970 );

INSERT INTO dbo.Scrive VALUES ( 1, 1 );
INSERT INTO dbo.Scrive VALUES ( 1, 2 );
INSERT INTO dbo.Scrive VALUES ( 1, 3 );
INSERT INTO dbo.Scrive VALUES ( 2, 4 );
INSERT INTO dbo.Scrive VALUES ( 3, 5 );
INSERT INTO dbo.Scrive VALUES ( 3, 6 );
INSERT INTO dbo.Scrive VALUES ( 4, 6 );

INSERT INTO dbo.FotoArticolo VALUES ( 1, 1 );
INSERT INTO dbo.FotoArticolo VALUES ( 2, 1 );
INSERT INTO dbo.FotoArticolo VALUES ( 3, 2 );
INSERT INTO dbo.FotoArticolo VALUES ( 3, 3 );
INSERT INTO dbo.FotoArticolo VALUES ( 4, 4 );
INSERT INTO dbo.FotoArticolo VALUES ( 5, 5 );
INSERT INTO dbo.FotoArticolo VALUES ( 6, 2 );
GO
PRINT 'tutti gli articoli del Corriere';
DECLARE @Testata varchar(10);
SELECT @Testata = 'Corriere';
SELECT *
FROM dbo.Articolo a
WHERE a.Testata = @Testata;
GO
PRINT 'testate per Lucio Bianchi';
DECLARE @Nome varchar(10), @Cognome varchar(10);
SELECT @Nome = 'Lucio', @Cognome = 'Bianchi';

PRINT 'filtro di where imposto a livello di join, quindi il working set
risultante avra'' una cardinalita'' inferiore';
SELECT DISTINCT(a.Testata)
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
AND g.Cognome = @Cognome AND g.Nome = @Nome;
PRINT 'oppure:';
PRINT 'Il filtro avviene dopo la produzione del working set risultante dalle
join coinvolte';
SELECT DISTINCT(a.Testata)
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
WHERE g.Cognome = @Cognome AND g.Nome = @Nome;
GO
PRINT 'numero di colonne per ogni giornalista';
SELECT g.Id_Giornalista, g.Cognome, g.Nome,
SUM(a.N_Colonne) AS [Tot Colonne]
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
GROUP BY g.Id_Giornalista, g.Cognome, g.Nome;

GO
PRINT 'Trovare i fotoreporter che hanno lavorato con il Lucio Bianchi E con
B BB';
DECLARE @Nome1 varchar(10), @Cognome1 varchar(10), @Nome2 varchar(10),
@Cognome2 varchar(10);
SELECT @Nome1 = 'Lucio', @Cognome1 = 'Bianchi', @Nome2 = 'B', @Cognome2 =
'BB';
SELECT DISTINCT f.Cognome, f.Nome
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.FotoArticolo fa ON fa.Id_Articolo = a.Id_Articolo
JOIN dbo.FotoReporter f ON f.Id_Reporter = fa.Id_Reporter
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
WHERE (g.Cognome = @Cognome1 AND g.Nome = @Nome1)
OR (g.Cognome = @Cognome2 and g.Nome = @Nome2);
GO
PRINT 'Trovare tutti i giornalisti che non hanno mai lavorato per BB';
DECLARE @Testata varchar(10);
SELECT @Testata = 'BB';
SELECT *
FROM dbo.Giornalista g
WHERE g.Id_Giornalista NOT IN (
SELECT g.Id_Giornalista
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
WHERE a.Testata = @Testata
);
GO
PRINT 'Trovare i giornalisti che in media scrivono articoli su almeno 2
colonne';
PRINT 'utilizzo di una common table expression per ottenere l''aggregazione
iniziale';
PRINT 'che viene poi utilizzata per ottenere la media di colonne divisa per
gli articoli';
PRINT 'che deve essere superiore o uguale a 2';
WITH cte AS (
SELECT g.Id_Giornalista, g.Cognome, g.Nome,
SUM(a.N_Colonne) AS [Tot Colonne], COUNT(a.Id_Articolo) AS [NumArticoli]
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
GROUP BY g.Id_Giornalista, g.Cognome, g.Nome
)
SELECT cte.Cognome, cte.Nome
FROM cte
WHERE [Tot Colonne] / [NumArticoli] >= 2;
GO
PRINT 'Trovare il numero di articoli scritti da ciascun giornalista';
SELECT g.Cognome, g.Nome,
COUNT(a.Id_Articolo) AS [Articoli]
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
GROUP BY g.Cognome, g.Nome;
GO
PRINT 'Trovare i fotoreporter che hanno sempre lavorato con giornalisti nati
prima del 1970';
PRINT 'domanda indefinita: specificare se "hanno lavorato SOLO con nati <
1970"';
PRINT 'o "ANCHE con nati < 1970"';

PRINT '"SOLO con nati < 1970"';
SELECT DISTINCT f.Cognome, f.Nome
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Articolo
AND g.AnnoNascita < 1970
JOIN dbo.FotoArticolo fa ON fa.Id_Articolo = a.Id_Articolo
JOIN dbo.FotoReporter f ON f.Id_Reporter = fa.Id_Reporter;


GO
PRINT 'Trovare i fotoreporter che hanno collaborato con B BB';
DECLARE @Nome varchar(10), @Cognome varchar(10);
SELECT @Nome = 'B', @Cognome = 'BB';

SELECT DISTINCT f.Cognome, f.Nome
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
JOIN dbo.Giornalista g ON g.Id_Giornalista = s.Id_Giornalista
AND g.Cognome = @Cognome AND g.Nome = @Nome
JOIN dbo.FotoArticolo fa ON fa.Id_Articolo = fa.Id_Reporter
JOIN dbo.FotoReporter f ON f.Id_Reporter = fa.Id_Reporter;
GO
PRINT 'Elencare le testate in cui hanno sempre scritto più di 4
giornalisti';
DECLARE @num int;
SELECT @num = 2;
SELECT a.Testata
FROM dbo.Articolo a
JOIN dbo.Scrive s ON s.Id_Articolo = a.Id_Articolo
GROUP BY a.Testata
HAVING COUNT(s.Id_Giornalista) > @num;
GO
DROP TABLE dbo.FotoArticolo, dbo.FotoReporter, dbo.Scrive, dbo.Articolo,
dbo.Giornalista;
--<----------
tutti gli articoli del Corriere
Id_Articolo Titolo Testata N_Colonne
----------- ---------- ---------- -----------
1 A Corriere 1
2 B Corriere 1

testate per Lucio Bianchi
filtro di where imposto a livello di join, quindi il working set risultante
avra' una cardinalita' inferiore
Testata
----------
BB
Corriere

oppure:
Il filtro avviene dopo la produzione del working set risultante dalle join
coinvolte
Testata
----------
BB
Corriere

numero di colonne per ogni giornalista
Id_Giornalista Cognome Nome Tot Colonne
-------------- ---------- ---------- -----------
1 Bianchi Lucio 4
2 BB B 2
3 CC C 3
4 DD D 1

Trovare i fotoreporter che hanno lavorato con il Lucio Bianchi E con B BB
Cognome Nome
---------- ----------
TT T
UU U
VV V
ZZ Z

Trovare tutti i giornalisti che non hanno mai lavorato per BB
Id_Giornalista Nome Cognome AnnoNascita
-------------- ---------- ---------- -----------
4 D DD 1970

Trovare i giornalisti che in media scrivono articoli su almeno 2 colonne
utilizzo di una common table expression per ottenere l'aggregazione iniziale
che viene poi utilizzata per ottenere la media di colonne divisa per gli
articoli
che deve essere superiore o uguale a 2
Cognome Nome
---------- ----------
BB B

Trovare il numero di articoli scritti da ciascun giornalista
Cognome Nome Articoli
---------- ---------- -----------
BB B 1
Bianchi Lucio 3
CC C 2
DD D 1

Trovare i fotoreporter che hanno sempre lavorato con giornalisti nati prima
del 1970
domanda indefinita: specificare se "hanno lavorato SOLO con nati < 1970"
o "ANCHE con nati < 1970"
"SOLO con nati < 1970"
Cognome Nome
---------- ----------
ZZ Z

Trovare i fotoreporter che hanno collaborato con B BB
Cognome Nome
---------- ----------
RR R
TT T
UU U
ZZ Z

Elencare le testate in cui hanno sempre scritto più di 4 giornalisti
Testata
----------
BB

saluti

Andrea Montanari (Microsoft MVP - SQL Server)
http://www.asql.biz - http://italy.mvps.org
http://www.hotelsole.com - http://www.hotelsolericcione.de

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.
In primo piano

I più letti di oggi

Media
In evidenza
MISC