salve
select notizie.titolo, notizie.testo, articoli.titolo, articolo.testo, allievi.curriculum from
notizie, articoli, allievi
where notizie.[campo1] = articoli.[campo2] and articoli.[campo3] = ...
Non conoscendo le relazioni tra le tabelle non posso concludere la selezione.
al posto di [campo1], [campo2],... dovresti mettere le chiavi esterne e primarie che legano le tabelle.
Saluti
personalmente avrei preferito non fosse stata indicata la vecchia sintassi come riportato, bensi' la nuova sintassi ANSI SQL 92, tipicamente
select notizie.titolo, notizie.testo, articoli.titolo, articolo.testo, allievi.curriculum
FROM
notizie
JOIN articoli ON x=y
JOIN allievi ON z=k
ma resta valido il discorso relativo all'indicazione di ubicazione delle chiavi referenziali...
la "vecchia" sintassi, malgrado nel caso del join naturale produca in effetti lo stesso risultato, diventa molto poco leggibile in quanto vengono "mischiati" i predicati di relazione tra le tabelle coinvolte con i veri vincoli di restrizione della proiezione (la clausola WHERE di definizione del filtro)..
in altri tipi di join, la discussione non e' piu' solo di sintassi linguistica, ma prettamente di semantica..
la sintassi 92, al contrario della vecchia sintassi 89, esclude a priori ogni ambiguita' in quanto la clausola di WHERE non viene mai frammista di elementi estranei facenti parte delle relazioni coinvolte..
dobbiamo anche ricordare che le condizioni di WHERE devono per loro natura essere di tipo associativo, risultando che la variazione dell'ordine di espressione non deve modificare il risultato finale, cosa che ovviamente non avviene nel caso di natural (inner) join, ma che puo' diventare un vero e proprio incubo nel caso di outer join..
consideriamo ad esempio
SET NOCOUNT ON;
USE master;
GO
CREATE DATABASE testJoin;
GO
EXEC sp_dbcmptlevel testJoin, 80;
GO
USE testJoin;
GO
CREATE TABLE dbo.Customers (
Id int NOT NULL,
Name varchar(5) NOT NULL
);
CREATE TABLE dbo.Products (
Id int NOT NULL,
Name varchar(5) NOT NULL
);
CREATE TABLE dbo.Orders (
Id int NOT NULL,
CustomerId int NULL,
ProductId int NULL,
Amount decimal (18,4)
);
GO
PRINT 'not allowed';
SELECT c.Id, c.Name AS [Customer],
o.Amount,
p.Name AS [ProductName]
FROM dbo.Customers c, dbo.Orders o, dbo.Products p
WHERE c.Id *= o.CustomerId
AND o.ProductId *= p.Id;
GO
PRINT 'allowed';
SELECT c.Id, c.Name AS [Customer],
o.Amount,
p.Name AS [ProductName]
FROM dbo.Customers c
LEFT OUTER JOIN dbo.Orders o ON c.Id = o.CustomerId
LEFT OUTER JOIN dbo.Products p ON o.ProductId = p.Id;
GO
DROP TABLE dbo.Orders, dbo.Products, dbo.Customers;
GO
USE master;
GO
DROP DATABASE testJoin;
dove, nella vecchia sintassi, la proprieta' associativa non e' affatto rispettata, in quanto qualora customers e orders vengano messi per primi in relazione, non sarebbe possibile relazionare ulteriormente il risultato (la work table derivata) relativo a un customer esistene che non abbia piazzato ordini con la tabella products in quanto ProductID sarebbe ovviamente NULL; al contrario, relazionando inizialmente Orders con Products, alcune righe di Products sarebbero incluse.. quindi la proprieta' associativa del predicato di WHERE non viene soddisfatto..
nell'uso della nuova sintassi, invece, l'ambiguita' viene risolta a priori ottenendo precedentemente il working set derivante dalla esplosione delle join, per poi essere opportunamente filtrato come desiderato nella condizione di WHERE..
tra l'altro, ad esempio utilizzando SQL Server, la vecchia sintassi con outer join non viene piu' supportata a partire da SQL Server 2005, ed ho infatti impostato il compatibility level del database alla versione 2000...
detto cio', relativamente alla parte teorico/semantica, restano pero' valide le osservazioni circa la necessita' di rilevare le relazioni..
saluti
Modificato da Andrea Montanari il 05 gennaio 2009 01.42 -