Nell'ultima lezione si è appreso come creare insiemi di risultati che contengono i dati di una singola tabella. In questa lezione verrà illustrato come creare insiemi di risultati di dati provenienti da due o più tabelle. A tale scopo, è possibile utilizzare un join o una unione.
Un join consente di combinare le colonne di due o più tabelle in un unico set di risultati. Negli argomenti che seguono, si apprenderà come utilizzare il tipo più comune di join, un join interno. Più avanti nella lezione si apprenderà come utilizzare altri tipi di join.
L'esempio qui sotto presenta la sintassi esplicita per la codifica di un join interno. Come si vedrà più avanti in questa lezione, SQL Server fornisce anche una sintassi implicita che si può usare per codificare le giunzioni interne. Tuttavia, la sintassi mostrata è quella più frequente. Per unire i dati di due tabelle, si codificano i nomi delle due tabelle nella clausola FROM e nella clausola JOIN. FROM insieme alla parola chiave JOIN e a una frase ON specifica la condizione di unione. La condizione di unione indica il modo in cui le due tabelle devono essere confrontate. Nella maggior parte dei casi, vengono confrontate in base alla relazione tra la chiave primaria della prima tabella e una chiave esterna della seconda tabella. L'istruzione SELECT di questo esempio si uniscono i dati delle tabelle Venditori e Fatture in base alla chiave primaria della tabella Venditori e la colonna VendorID della tabella Fatture. Si noti che, poiché l'operatore equal viene utilizzato in questa condizione, il valore della colonna VendorID della colonna VendorID di una riga della tabella Vendors deve corrispondere al VendorID di una riga della tabella Invoices perché la riga sia inclusa nel set di risultati. In altre parole, solo i fornitori con una o più fatture saranno inclusi. Anche se la maggior parte dei join utilizzano l'operatore di uguaglianza, è bene sapere che è possibile confrontare due tabelle in base ad altre condizioni. In questo esempio, la tabella Venditori viene unita alla tabella Fatture utilizzando una colonna che ha lo stesso nome in entrambe le tabelle: VendorID. Per questo motivo, le colonne devono essere qualificate per indicare da quale tabella provengono. Come si può può vedere, si codifica il nome di una colonna qualificata inserendo il nome della tabella e un punto davanti al nome della colonna. Sebbene questo esempio utilizzi nomi di colonne qualificati solo nella condizione di unione, è necessario qualificare il nome di una colonna ovunque appaia nell'istruzione se nella dichiarazione lo stesso nome è presente in entrambe le tabelle. In caso contrario, SQL Server restituirà un errore indicando che il nome della colonna è ambiguo. Naturalmente, è possibile qualificare anche i nomi di colonna che non sono ambigui. Tuttavia, vi consiglio di farlo solo se serve a rendere più chiaro il vostro codice.
SELECT select_list
FROM table_l
[INNER] JOIN table_2
ON join_condition_l
[[INNER] JOIN table_3
ON join_condition_2] ...
USE AP
GO
SELECT InvoiceNumber, VendorName
FROM Vendors JOIN Invoices
ON Vendors.VendorID = Invoices.VendorID;
USE AP
GO
SELECT InvoiceNumber, VendorName
FROM Invoices JOIN Vendors
ON Invoices.VendorID = Vendors.VendorID;
Quando si nominano le tabelle da unire nella clausola FROM, è possibile assegnare nomi temporanei alle tabelle, chiamati nomi di correlazione o alias di tabella. Per farlo, si usa la frase AS proprio come quando si assegna un alias a una colonna. È necessario utilizzare tale nome al posto del nome originale della tabella originale in tutta la query. La prima istruzione SELECT di questa figura unisce i dati della tabella Venditori e Fatture. In questo caso, a entrambe le tabelle sono stati assegnati nomi di correlazione che consistono in una sola lettera. Sebbene nomi di correlazione così brevi possano ridurre la di digitazione, possono anche rendere più difficile la lettura e la manutenzione di una query. Di conseguenza, si dovrebbero usare i nomi delle correlazioni solo quando semplificano o chiariscono la query. Il nome della correlazione usato nella seconda istruzione SELECT degli esempi qui sotto, semplifica il nome della tabella InvoiceLineltems in Lineltems. In questo modo, il nome più breve può essere usato per fare riferimento alla colonna lnvoiceID della tabella nella condizione di join. Anche se questo non migliora di molto la query in questo esempio, può avere un effetto notevole su una query che fa riferimento alla colonna lnvoiceLineltems più volte.
SELECT select_list
FROM table_l [AS] nl
[INNER] JOIN table_2 [AS] n2
ON nl.column_name operator n2.column_name
[[INNER] JOIN table_3 [AS] n3
ON n2.column_name operator n3.column_name] ...
USE AP
GO
SELECT InvoiceNumber, VendorName, InvoiceDueDate,
InvoiceTotal - PaymentTotal - CreditTotal AS BalanceDue
FROM Vendors AS v JOIN Invoices AS i
ON v.VendorID = i.VendorID
WHERE InvoiceTotal - PaymentTotal - CreditTotal > 0
ORDER BY InvoiceDueDate DESC
USE AP
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE InvoiceLineItems(
InvoiceID int NOT NULL,
InvoiceSequence smallint NOT NULL,
AccountNo int NOT NULL,
InvoiceLineItemAmount money NOT NULL,
InvoiceLineItemDescription varchar(100) NOT NULL,
CONSTRAINT PK_InvoiceLineItems PRIMARY KEY CLUSTERED
(
InvoiceID ASC,
InvoiceSequence ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (1, 1, 553, 3813.3300, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (2, 1, 553, 40.2000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (3, 1, 553, 138.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (4, 1, 553, 144.7000, N'Int''l shipment')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (5, 1, 553, 15.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (6, 1, 553, 42.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (7, 1, 553, 172.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (8, 1, 522, 95.0000, N'Telephone service')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (9, 1, 403, 601.9500, N'Cover design')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (10, 1, 553, 42.6700, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (11, 1, 553, 42.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (12, 1, 580, 50.0000, N'DiCicco''s')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (12, 2, 570, 75.6000, N'Kinko''s')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (12, 3, 570, 58.4000, N'Office Max')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (12, 4, 540, 478.0000, N'Publishers Marketing')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (13, 1, 522, 16.3300, N'Telephone (line 5)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (14, 1, 553, 6.0000, N'Freight out')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (15, 1, 574, 856.9200, N'Property Taxes')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (16, 1, 572, 9.9500, N'Monthly access fee')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (17, 1, 553, 10.0000, N'Address correction')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (18, 1, 553, 104.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (19, 1, 160, 116.5400, N'MVS Online Library')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (20, 1, 553, 6.0000, N'Freight out')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (21, 1, 589, 4901.2600, N'Office lease')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (22, 1, 553, 108.2500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (23, 1, 572, 9.9500, N'Monthly access fee')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (24, 1, 520, 1750.0000, N'Warehouse lease')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (25, 1, 553, 129.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (26, 1, 553, 10.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (27, 1, 540, 207.7800, N'Prospect list')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (28, 1, 553, 109.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (29, 1, 523, 450.0000, N'Back office additions')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (30, 1, 553, 63.4000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (31, 1, 589, 7125.3400, N'Web site design')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (32, 1, 403, 953.1000, N'Crash Course revision')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (33, 1, 591, 220.0000, N'Form 571-L')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (34, 1, 553, 127.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (35, 1, 507, 1600.0000, N'Income Tax')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (36, 1, 403, 565.1500, N'Crash Course Ad')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (37, 1, 553, 36.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (38, 1, 553, 61.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (39, 1, 400, 37966.1900, N'CICS Desk Reference')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (40, 1, 403, 639.7700, N'Card deck')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (41, 1, 553, 53.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (42, 1, 553, 400.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (43, 1, 400, 21842.0000, N'Book repro')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (44, 1, 522, 19.6700, N'Telephone (Line 3)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (45, 1, 553, 2765.3600, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (46, 1, 510, 224.0000, N'Health Insurance')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (47, 1, 572, 1575.0000, N'Catalog ad')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (48, 1, 553, 33.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (49, 1, 522, 16.3300, N'Telephone (line 6)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (50, 1, 510, 116.0000, N'Health Insurance')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (51, 1, 553, 2184.1100, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (52, 1, 160, 1083.5800, N'MSDN')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (53, 1, 522, 46.2100, N'Telephone (Line 1)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (54, 1, 403, 313.5500, N'Card revision')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (55, 1, 553, 40.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (56, 1, 572, 2433.0000, N'Card deck')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (57, 1, 589, 1367.5000, N'401K Contributions')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (58, 1, 553, 53.2500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (59, 1, 553, 13.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (60, 1, 553, 2312.2000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (61, 1, 553, 25.6700, N'Freight out')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (62, 1, 553, 26.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (63, 1, 553, 2115.8100, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (64, 1, 553, 23.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (65, 1, 400, 6940.2500, N'OS Utilities')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (66, 1, 553, 31.9500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (67, 1, 553, 1927.5400, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (68, 1, 160, 936.9300, N'Quarterly Maintenance')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (69, 1, 540, 175.0000, N'Card deck advertising')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (70, 1, 553, 6.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (71, 1, 553, 108.5000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (72, 1, 553, 10.0000, N'Address correction')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (73, 1, 552, 290.0000, N'International pkg.')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (74, 1, 570, 41.8000, N'Coffee')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (75, 1, 553, 27.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (76, 1, 553, 241.0000, N'Int''l shipment')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (77, 1, 403, 904.1400, N'Cover design')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (78, 1, 403, 1197.0000, N'Cover design')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (78, 2, 540, 765.1300, N'Catalog design')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (79, 1, 540, 2184.5000, N'PC card deck')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (80, 1, 553, 2318.0300, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (81, 1, 553, 26.2500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (82, 1, 150, 17.5000, N'Supplies')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (83, 1, 522, 39.7700, N'Telephone (Line 2)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (84, 1, 553, 111.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (85, 1, 553, 158.0000, N'Int''l shipment')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (86, 1, 553, 739.2000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (87, 1, 553, 60.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (88, 1, 553, 147.2500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (89, 1, 400, 85.3100, N'Book copy')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (90, 1, 553, 38.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (91, 1, 522, 32.7000, N'Telephone (line 4)')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (92, 1, 521, 16.6200, N'Propane-forklift')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (93, 1, 553, 162.7500, N'International shipment')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (94, 1, 553, 52.2500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (95, 1, 572, 600.0000, N'Books for research')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (96, 1, 400, 26881.4000, N'MVS JCL')
GO
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (97, 1, 170, 356.4800, N'Network wiring')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (98, 1, 572, 579.4200, N'Catalog ad')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (99, 1, 553, 59.9700, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (100, 1, 553, 67.9200, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (101, 1, 553, 30.7500, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (102, 1, 400, 20551.1800, N'CICS book printing')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (103, 1, 553, 2051.5900, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (104, 1, 553, 44.4400, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (105, 1, 582, 503.2000, N'Bronco lease')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (106, 1, 400, 23517.5800, N'DB2 book printing')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (107, 1, 553, 3689.9900, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (108, 1, 553, 67.0000, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (109, 1, 403, 1000.4600, N'Crash Course covers')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (110, 1, 540, 90.3600, N'Card deck advertising')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (111, 1, 553, 22.5700, N'Freight')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (112, 1, 400, 10976.0600, N'VSAM book printing')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (113, 1, 510, 224.0000, N'Health Insurance')
INSERT InvoiceLineItems (InvoiceID, InvoiceSequence, AccountNo, InvoiceLineItemAmount, InvoiceLineItemDescription) VALUES (114, 1, 553, 127.7500, N'Freight')
USE AP
GO
SELECT InvoiceNumber, InvoiceLineitemAmount, InvoiceLineitemDescription
FROM Invoices JOIN InvoiceLineitems AS Lineitems
ON Invoices.InvoiceID = Lineitems.InvoiceID
WHERE AccountNo = 540
ORDER BY InvoiceDate;
Anche se non è frequente, può capitare di dover unire dati provenienti da tabelle che risiedono in database diversi. Per farlo, è necessario qualificare uno o più nomi di tabelle. L'esempio qui sotto mostra come fare. Per cominciare, la figura presenta la sintassi di un nome di oggetto qualificato. Come si può vedere, un nome completamente qualificato è composto da quattro parti: un nome di server, un nome di database, un nome di schema e un nome di tabella. In questa lezione si apprenderà come qualificare i nomi delle tabelle. Tuttavia, è bene sapere che è possibile questa sintassi anche con altri oggetti. La prima istruzione SELECT di questa figura illustra l'uso di nomi di oggetti completamente qualificati. Questa istruzione unisce i dati di due tabelle (Venditori e Clienti) in due database diversi (AP e ProductOrders). Entrambi i database si trovano sullo stesso server (SERVER2025) e sono memorizzati nello stesso schema (dbo ). In questo caso, a entrambe le tabelle sono stati assegnati dei nomi di correlazione per facilitarne il riferimento nella condizione di join. Anche se è possibile qualificare tutti i nomi delle tabelle in questo modo, di solito si specificano solo le parti che sono diverse dalle impostazioni correnti. Quando si avvia Management Studio, ad esempio, ci si connette a un server specifico. Finché si lavora con i database di quel server, non è necessario includere il nome del server. Allo stesso modo, prima di eseguire un'istruzione, si seleziona di solito il database che utilizza. Quindi, finché si lavora con le tabelle di quel database, non è necessario includere il nome del database. Si può anche omettere il nome dello schema, purché si lavori con le tabelle dello schema predefinito dell'utente (vedere lezione 17) o dello schema dbo. Ecco perché tutte le istruzioni viste fino a questo punto hanno incluso solo il nome della tabella. Quando si omettono una o più parti di un nome di oggetto completamente qualificato, si crea un nome di oggetto parzialmente qualificato. Si noti che, poiché il nome dello schema si colloca tra il nome del database e il nome della tabella, sono stati codificati due caratteri punto per indicare che questa parte del nome è stata omessa.
linked_server.database.schema.object
USE AP
GO
SELECT VendorName, CustLastName, CustFirstName,
VendorState AS State, VendorCity AS City
FROM Vendors
JOIN ProductOrders..Customers AS Customers
ON Vendors.VendorZipCode = Customers.CustZip
ORDER BY State, City
Sebbene una condizione di unione sia tipicamente costituita da un singolo confronto, è possibile includere due o più confronti in una condizione di unione utilizzando gli operatori AND e OR. L'esempio qui sotto ne illustra il funzionamento. Nella prima istruzione SELECT di questa figura, si può notare che le fatture e le linee di fattura sono unite in base a due confronti. In primo luogo, lnvoiceID della tabella fatture, viene confrontata con la chiave esterna della tabella lnvoiceLineltems anch'essa denominata lnvoiceID. Come negli esempi precedenti questo confronto utilizza una condizione di uguaglianza. Quindi, la colonna lnvoiceTotal della tabella Fatture viene testata per verificare se il valore è maggiore di quello della tabella lnvoiceLineltemAmount della tabella InvoiceLineltems. Ciò significa che solo le fatture che hanno due o più voci saranno incluse nell'insieme dei risultati. L'esempio mostra una parte dell'insieme dei risultati. Un altro modo per codificare queste condizioni è quello di codificare la condizione di join primario nella clausola FROM e l'altra condizione nella clausola WHERE. Questo è illustrato dalla seconda istruzione SELECT. Quando si codificano condizioni di unione composte separate come questa, la condizione di unione nell'espressione ON viene eseguita prima che le tabelle vengano unite, mentre la condizione di ricerca nella clausola WHERE viene eseguita dopo l'unione delle tabelle. Per questo motivo, ci si potrebbe aspettare che un'istruzione SELECT venga eseguita in modo più efficiente se si codifica la condizione di ricerca nell'espressione ON. Tuttavia, SQL Server esamina le condizioni di unione e di ricerca durante l'ottimizzazione della query. Quindi non è necessario preoccuparsi di quale sia la tecnica più efficiente. È invece necessario codificare le condizioni in modo che siano facilmente comprensibili.
USE AP
GO
SELECT InvoiceNumber, InvoiceDate,
InvoiceTotal, InvoiceLineitemAmount
FROM Invoices JOIN InvoiceLineitems AS Lineitems
ON (Invoices.InvoiceID = Lineitems.InvoiceID) AND
(Invoices.InvoiceTotal > Lineitems.InvoiceLineitemAmount )
ORDER BY InvoiceNumber
USE AP
GO
SELECT InvoiceNumber, InvoiceDate,
InvoiceTotal, InvoiceLineitemAmount
FROM Invoices JOIN InvoiceLineitems AS Lineitems
ON Invoices.InvoiceID = Lineitems.InvoiceID
WHERE Invoices.InvoiceTotal > Lineitems.InvoiceLineitemAmount
ORDER BY InvoiceNumber
Una self-join è una join in cui una tabella è unita a se stessa. Sebbene i self join siano rari, ci sono alcune query uniche che si risolvono meglio utilizzando i self-join. L'esempio qui sotto presenta un esempio di self-join che utilizza la tabella Vendors. Si noti che, poiché la stessa tabella viene utilizzata due volte, vengono utilizzati nomi di correlazione per distinguere le due occorrenze della tabella. Inoltre, ogni nome di colonna utilizzato nella query è qualificato dal nome della correlazione, poiché le colonne sono presenti in entrambe le tabelle. La condizione di join in questo esempio utilizza tre confronti. I primi due corrispondono alle colonne VendorCity e VendorState delle due tabelle. Di conseguenza, la query restituirà le righe dei fornitori che risiedono nella stessa città e nello stesso stato di un altro fornitore. Poiché un fornitore risiede nella stessa città e nello stesso stato di se stesso, tuttavia, viene incluso un terzo confronto per escludere le righe che corrispondono a un fornitore con se stesso. A tale scopo, questa condizione utilizza l'operatore not equal per confrontare le colonne VendorID delle due tabelle. Si noti che anche la parola chiave DISTINCT è inclusa in questa istruzione SELECT. In questo modo, un fornitore compare solo una volta nell'insieme dei risultati. Altrimenti comparirebbe una volta per ogni riga con città e stato corrispondenti. Questo esempio mostra anche come sia possibile utilizzare colonne diverse dalle colonne chiave in una condizione di unione. Si tenga presente, tuttavia, che si tratta di una situazione insolita e che non è probabile che si codifichino spesso join di questo tipo.
USE AP
GO
SELECT DISTINCT Vendorsl.VendorName, Vendorsl.VendorCity,
Vendorsl.VendorState
FROM Vendors AS Vendorsl JOIN Vendors AS Vendors2
ON (Vendorsl.VendorCity = Vendors2.VendorCity) AND
(Vendorsl.VendorState = Vendors2.VendorState) AND
(Vendorsl.VendorID <> Vendors2.VendorID)
ORDER BY Vendorsl.VendorState, Vendorsl.VendorCity
In questa lezione abbiamo visto come unire i dati di due tabelle. Tuttavia, SQL Server consente di unire dati provenienti da un massimo di 256 tabelle. Naturalmente, è probabile che sia mai necessario unire i dati di più di qualche tabella. Inoltre, ogni join richiede risorse di sistema aggiuntive, per cui è consigliabile limitare il numero di tabelle unite quando possibile. L'istruzione SELECT dell'esempio qui sotto unisce i dati di quattro tabelle: Venditori, Fatture, FattureLineltems e GLAccounts. Ogni unione si basa sulla relazione tra la chiave primaria di una tabella e una chiave esterna dell'altra tabella. Ad esempio, la colonna AccountNo è la chiave primaria della tabella GLAccounts e una chiave esterna dell'altra tabella. Sotto l'istruzione SELECT, si possono vedere tre tabelle. La prima presenta il risultato del join tra le tabelle Vendors e Invoices. Questa tabella può essere definita una tabella intermedia perché contiene risultati intermedi. Analogamente, la seconda tabella mostra il risultato dell'unione tra la prima tabella intermedia e la tabella lnvoiceLineltems. La terza tabella mostra il risultato dell'unione tra la seconda tabella intermedia e la tabella GLAccounts dopo l'applicazione della sequenza ORDER BY. Nell'esaminare le tre tabelle in questo esempio, si tenga presente che SQL Server potrebbe non elaborare le unioni come illustrato qui. Tuttavia, l'idea delle tabelle intermedie dovrebbe aiutare a capire come funzionano le giunzioni tra più tabelle.
USE AP
GO
-- create the GLAccounts table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE GLAccounts (
AccountNo int NOT NULL,
AccountDescription varchar(50) NOT NULL,
CONSTRAINT PK_GLAccounts PRIMARY KEY CLUSTERED
(
AccountNo ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
-- insert the records into GLAccounts table
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (100, N'Cash')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (110, N'Accounts Receivable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (120, N'Book Inventory')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (150, N'Furniture')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (160, N'Computer Equipment')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (162, N'Capitalized Lease')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (167, N'Software')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (170, N'Other Equipment')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (181, N'Book Development')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (200, N'Accounts Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (205, N'Royalties Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (221, N'401K Employee Contributions')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (230, N'Sales Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (234, N'Medicare Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (235, N'Income Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (237, N'State Payroll Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (238, N'Employee FICA Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (239, N'Employer FICA Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (241, N'Employer FUTA Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (242, N'Employee SDI Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (243, N'Employer UCI Taxes Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (251, N'IBM Credit Corporation Payable')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (280, N'Capital Stock')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (290, N'Retained Earnings')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (300, N'Retail Sales')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (301, N'College Sales')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (302, N'Trade Sales')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (306, N'Consignment Sales')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (310, N'Compositing Revenue')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (394, N'Book Club Royalties')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (400, N'Book Printing Costs')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (403, N'Book Production Costs')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (500, N'Salaries and Wages')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (505, N'FICA')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (506, N'FUTA')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (507, N'UCI')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (508, N'Medicare')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (510, N'Group Insurance')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (520, N'Building Lease')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (521, N'Utilities')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (522, N'Telephone')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (523, N'Building Maintenance')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (527, N'Computer Equipment Maintenance')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (528, N'IBM Lease')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (532, N'Equipment Rental')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (536, N'Card Deck Advertising')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (540, N'Direct Mail Advertising')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (541, N'Space Advertising')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (546, N'Exhibits and Shows')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (548, N'Web Site Production and Fees')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (550, N'Packaging Materials')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (551, N'Business Forms')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (552, N'Postage')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (553, N'Freight')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (555, N'Collection Agency Fees')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (556, N'Credit Card Handling')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (565, N'Bank Fees')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (568, N'Auto License Fee')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (569, N'Auto Expense')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (570, N'Office Supplies')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (572, N'Books, Dues, and Subscriptions')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (574, N'Business Licenses and Taxes')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (576, N'PC Software')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (580, N'Meals')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (582, N'Travel and Accomodations')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (589, N'Outside Services')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (590, N'Business Insurance')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (591, N'Accounting')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (610, N'Charitable Contributions')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (611, N'Profit Sharing Contributions')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (620, N'Interest Paid to Banks')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (621, N'Other Interest')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (630, N'Federal Corporation Income Taxes')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (631, N'State Corporation Income Taxes')
INSERT GLAccounts (AccountNo, AccountDescription) VALUES (632, N'Sales Tax')
GO
USE AP
GO
SELECT VendorName, InvoiceNumber, InvoiceDate,
InvoiceLineitemAmount AS LineitemAmount, AccountDescription,
InvoiceLineitems.AccountNo, GLAccounts.AccountNo
FROM Vendors
JOIN Invoices ON Vendors.VendorID = Invoices.VendorID
JOIN InvoiceLineitems
ON Invoices.InvoiceID = InvoiceLineitems.InvoiceID
JOIN GLAccounts ON InvoiceLineitems.AccountNo = GLAccounts.AccountNo
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0
ORDER BY VendorName, LineitemAmount DESC
All'inizio di questa lezione, ho menzionato che SQL Server fornisce una sintassi implicita per l'unione delle tabelle. Questa sintassi era utilizzata prima degli standard SQL-92. Anche se vi consiglio di utilizzare la sintassi esplicita, dovreste conoscere la sintassi implicita nel caso in cui doveste gestire delle istruzioni SQL che la utilizzano. L'esempio qui sotto presenta la sintassi implicita di un join interno e due istruzioni che la utilizzano. Come si può vedere, le tabelle da unire sono semplicemente elencate nella clausola FROM. Quindi, le condizioni di unione sono incluse nella clausola WHERE. La prima istruzione SELECT, ad esempio, unisce i dati delle tabelle Venditori e Fatture. Come l'istruzione SELECT vista in precedenza, queste tabelle sono unite in base al confronto tra le colonne VendorID delle due tabelle. In questo caso, però, il confronto è codificato come condizione di ricerca della clausola WHERE. Se si confronta il set di risultati mostrato in questo esempio con quello precedente, si noterà che sono identici. La seconda istruzione SELECT utilizza la sintassi implicita per unire i dati di quattro tabelle. Si tratta della stessa unione vista nell'esempio precedente. Si noti in questo esempio che le tre condizioni di unione sono combinate nella clausola WHERE con l'operatore AND. Inoltre, viene utilizzato l'operatore AND per combinare le condizioni di join con la condizione di ricerca. Poiché la sintassi esplicita per le unioni consente di separare le condizioni di unione da quelle di ricerca, le istruzioni che utilizzano la sintassi esplicita sono in genere più facili da leggere rispetto a quelle che utilizzano la sintassi implicita. Inoltre, la sintassi esplicita consente di evitare un errore di codifica comune con la sintassi implicita: l'omissione della condizione di unione. Come si apprenderà più avanti in questo capitolo, un join implicito senza una condizione di join dà luogo a un join incrociato, che può restituire un gran numero di righe. Per questi motivi, vi consiglio di utilizzare la sintassi esplicita in tutto il vostro nuovo codice SQL.
SELECT select_list
FROM table_l, table_2 [, table_3] ...
WHERE table_l.column_name operator table_2.column_name
[AND table_2.column_name operator table_3.column_name] ...
USE AP
GO
SELECT InvoiceNumber, VendorName
FROM Vendors, Invoices
WHERE Vendors.VendorID = Invoices.VendorID
USE AP
GO
SELECT VendorName, InvoiceNumber, InvoiceDate,
InvoiceLineitemAmount AS LineitemAmount, AccountDescription
FROM Vendors, Invoices, InvoiceLineitems, GLAccounts
WHERE vendors.vendorID = Invoices.vendorID
AND Invoices.InvoiceID = InvoiceLineitems.InvoiceID
AND InvoiceLineitems.AccountNo = GLAccounts.AccountNo
AND (InvoiceTotal - PaymentTotal - CreditTotal) > 0
ORDER BY VendorName, LineitemAmount DESC
Sebbene le join interne siano il tipo di join che si usa più spesso, SQL Server supporta anche le join esterne. A differenza di una join interna, una outer join restituisce tutte le righe di una o di entrambe le tabelle coinvolte nel join, indipendentemente dal fatto che la condizione di join sia vera. Il funzionamento di questa funzione è illustrato negli argomenti che seguono.
L'esempio qui sotto presenta la sintassi esplicita per la codifica di una join esterna. Poiché questa sintassi è simile alla sintassi esplicita per le giunzioni interne, non dovrebbero esserci problemi a capire come funziona. La differenza principale è che si includono la parola chiave LEFT, RIGHT o FULL per specificare il tipo di join esterno che si desidera eseguire. Come si può vedere nella sintassi, è possibile includere anche la parola chiave OUTER ma è opzionale e di solito viene omessa. La tabella in questo esempio riassume le differenze tra join esterno sinistro, destro e completo. Quando si utilizza una join esterna sinistra, l'insieme dei risultati comprende tutte le righe della prima tabella, o sinistra. Allo stesso modo, quando si utilizza una join esterna destra, l'insieme dei risultati include tutte le righe della seconda tabella, o destra. E quando si utilizza una join esterna completa, l'insieme dei risultati include tutte le righe di entrambe le tabelle. L'esempio illustra una join esterna sinistra. In questo caso, la tabella Venditori è unita alla tabella Fatture. Si noti che l'insieme dei risultati include le righe dei fornitori anche se non vengono trovate fatture corrispondenti. In questo caso, vengono restituiti valori nulli per le colonne della tabella Fatture. Quando si codificano le join esterne, è prassi comune evitare di usare le join destre. A tale scopo, è possibile sostituire una join esterna sinistra con una join esterna destra, invertendo l'ordine delle tabelle nella clausola FROM e utilizzando la parola chiave LEFT al posto di RIGHT. Questo spesso facilita la lettura delle istruzioni che uniscono più di due tabelle. Oltre alla sintassi esplicita per la codifica delle join esterne, le versioni precedenti di SQL Server prevedevano una sintassi implicita. Questa funziona più o meno come la sintassi implicita per la codifica di join interni. Per i join esterni, tuttavia, si utilizzava l'operatore *= nella clausola WHERE per identificare un join esterno sinistro e l'operatore =* per identificare un join esterno destro. Sebbene non sia possibile utilizzare questi operatori da SQL Server 2005 e successivi, è bene conoscerli almeno nel caso in cui si incontrino in query più vecchie.
SELECT select_list
FROM table_l
{LEFT | RIGHT IFULL} [OUTER] JOIN table_2
ON join_condition_l
[{LEFT | RIGHT IFULL} [OUTER] JOIN table_3
ON join_condition_2] ...
Tipo di join | Mantenere le righe non corrispondenti da |
---|---|
Left outer join | La prima tabella (a sinistra) |
Right outer join | la seconda tabella (a destra) |
Full outer join | Entrambe le tabelle |
USE AP
GO
SELECT VendorName, InvoiceNumber, InvoiceTotal
FROM Vendors LEFT JOIN Invoices
ON Vendors.VendorID = Invoices.VendorID
ORDER BY VendorName
Per comprendere meglio il funzionamento dei join esterni, l'esempio qui sotto presenta altri tre esempi. Questi esempi utilizzano le tabelle Reparti e Dipendenti mostrate nella parte superiore dell'esempio. In ogni caso, la condizione di join unisce le tabelle in base ai valori delle colonne DeptNo. La prima istruzione SELECT esegue una join esterna sinistra su queste due tabelle. Nel risultato prodotto da questa istruzione, si può notare che il dipartimento numero 3 è incluso nel set di risultati anche se nessuno dei dipendenti della tabella Employees lavora in quel reparto. Per questo motivo, viene assegnato un valore nullo alla colonna LastName di quella tabella. La seconda istruzione SELECT utilizza un join esterno destro. In questo caso, tutte le righe della tabella Employees sono incluse nell'insieme dei risultati. Si noti, tuttavia, che due dei dipendenti, Watson e Locario, sono assegnati a un reparto che non esiste nella tabella Departments. Naturalmente, se la colonna DeptNo della tabella fosse stata definita come chiave esterna alla tabella Reparti, ciò non sarebbe stato possibile. In questo caso, però, non è stata definita una chiave esterna, quindi vengono restituiti valori nulli per la colonna DeptName in queste due righe. La terza istruzione SELECT di questa figura illustra una join esterna completa. Se si confrontano i risultati di questa query con quelli delle query che utilizzano un join esterno sinistro e destro, si noterà che si tratta di una combinazione dei due join. In altre parole, ogni riga della tabella Reparti è inclusa nel set di risultati, insieme a ogni riga della tabella Dipendenti. Poiché la colonna DeptNo è in entrambe le tabelle, è possibile identificare chiaramente la riga della tabella Departments che non ha una riga corrispondente nella tabella Dipendenti e le due righe della tabella Dipendenti che non hanno una riga corrispondente nella tabella Reparti.
USE AP
GO
-- create the Departments table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE Departments (
DeptNo int IDENTITY(1,1) NOT NULL,
DeptName varchar(50) NOT NULL,
CONSTRAINT PK_Departments PRIMARY KEY CLUSTERED
(
DeptNo ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
-- create the Employees table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE Employees (
EmployeeID int IDENTITY(1,1) NOT NULL,
LastName varchar(35) NOT NULL,
FirstName varchar(35) NOT NULL,
DeptNo int NOT NULL,
ManagerID int NULL,
CONSTRAINT PK_Employees PRIMARY KEY CLUSTERED
(
EmployeeID ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
SET IDENTITY_INSERT Departments ON
INSERT Departments (DeptNo, DeptName) VALUES (1, N'Accounting')
INSERT Departments (DeptNo, DeptName) VALUES (2, N'Payroll')
INSERT Departments (DeptNo, DeptName) VALUES (3, N'Operations')
INSERT Departments (DeptNo, DeptName) VALUES (4, N'Personnel')
INSERT Departments (DeptNo, DeptName) VALUES (5, N'Maintenance')
SET IDENTITY_INSERT Departments OFF
USE AP
GO
SET IDENTITY_INSERT Employees ON
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (1, N'Smith', N'Cindy', 2, NULL)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (2, N'Jones', N'Elmer', 4, 1)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (3, N'Simonian', N'Ralph', 2, 2)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (4, N'Hernandez', N'Olivia', 1, 2)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (5, N'Aaronsen', N'Robert', 2, 3)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (6, N'Watson', N'Denise', 6, 3)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (7, N'Hardy', N'Thomas', 5, 2)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (8, N'O''Leary', N'Rhea', 4, 2)
INSERT Employees (EmployeeID, LastName, FirstName, DeptNo, ManagerID) VALUES (9, N'Locario', N'Paulo', 6, 1)
SET IDENTITY_INSERT Employees OFF
USE AP
GO
SELECT Departments.DeptName, Departments.DeptNo, Employees.LastName
FROM Departments LEFT JOIN Employees
ON Departments.DeptNo = Employees.DeptNo
USE AP
GO
SELECT Departments.DeptName, Departments.DeptNo, Employees.LastName
FROM Departments RIGHT JOIN Employees
ON Departments.DeptNo = Employees.DeptNo
USE AP
GO
SELECT Departments.DeptName, Departments.DeptNo, Employees.LastName
FROM Departments FULL JOIN Employees
ON Departments.DeptNo = Employees.DeptNo
Come con i Join interni, è possibile utilizzare i Join esterni per unire i dati di più di due tabelle. I due esempi qui sotto ne illustrano il funzionamento. Questi esempi utilizzano le tabelle Reparti e Dipendenti viste nell'esempio precedente, oltre a una tabella Progetti. Il primo esempio utilizza Join esterni a sinistra per unire i dati delle tre tabelle. Anche in questo caso si può notare che nessuno dei dipendenti della tabella Employees è assegnato al reparto Operations. Per questo motivo, vengono restituiti valori per le colonne delle tabelle Dipendenti e Progetti. Inoltre, si può notare che due dipendenti, Hardy e Jones, non sono assegnati a un progetto. Il secondo esempio in questa figura utilizza Join esterni completi per unire le tre tabelle. Questo set di risultati include le righe non abbinate delle tabelle Reparti e Dipendenti, proprio come il set di risultati visto in precedenza. Proprio come l'insieme di risultati visto in precedenza è stato creato con un join esterno completo. Inoltre, l'insieme di risultati di questo esempio include una riga dalla tabella Progetti: quella relativa al progetto numero P1014. In altre parole, nessuno dei dipendenti è assegnato a questo progetto.
USE AP
GO
-- create the Projects table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE Projects (
ProjectID int IDENTITY(1,1) NOT NULL,
ProjectNo char(5) NOT NULL,
EmployeeID int NOT NULL,
CONSTRAINT PK_Projects PRIMARY KEY CLUSTERED
(
ProjectID ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
SET IDENTITY_INSERT Projects ON
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (1, N'P1011', 8)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (2, N'P1011', 4)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (3, N'P1012', 3)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (4, N'P1012', 1)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (5, N'P1012', 5)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (6, N'P1013', 6)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (7, N'P1013', 9)
INSERT Projects (ProjectID, ProjectNo, EmployeeID) VALUES (8, N'P1014', 10)
SET IDENTITY_INSERT Projects OFF
USE AP
GO
SELECT DeptName, LastName, ProjectNo
FROM Departments
LEFT JOIN Employees
ON Departments.DeptNo = Employees.DeptNo
LEFT JOIN Projects
ON Employees.EmployeeID = Projects.EmployeeID
ORDER BY DeptName, LastName, ProjectNo
USE AP
GO
SELECT DeptName, LastName, ProjectNo
FROM Departments
FULL JOIN Employees
ON Departments.DeptNo - Employees.DeptNo
FULL JOIN Projects
ON Employees.EmployeeID = Projects.EmployeeID
ORDER BY DeptName
I due argomenti che seguono presentano due abilità aggiuntive per lavorare con i join. Nel primo argomento, imparerete a utilizzare i join interni ed esterni nella stessa istruzione. Poi, nel secondo argomento, imparerete a usare un altro tipo di join, chiamato join incrociato.
L'esempio che segue mostra come è possibile combinare join interni ed esterni. In questo esempio, la tabella Reparti viene unita alla tabella Dipendenti utilizzando un join interno. Il risultato è una tabella intermedia che include i reparti con uno o più dipendenti. Si noti che la colonna EmployeeID è mostrata in questa tabella, anche se non è inclusa nell'insieme dei risultati finali. Questo perché viene utilizzata dalla join che segue. Dopo aver unito le tabelle Reparti e Dipendenti, la tabella provvisoria viene unita alla tabella Progetti con un join esterno sinistro. Il risultato è una tabella che include tutti i dipartimenti a cui sono assegnati dipendenti, tutti i dipendenti assegnati a tali dipartimenti e tutti i progetti. Qui si vede chiaramente che a due dipendenti, Hardy e Jones, non sono stati assegnati progetti.
USE AP
GO
SELECT DeptName, LastName, ProjectNo
FROM Departments
JOIN Employees
ON Departments.DeptNo = Employees.DeptNo
LEFT JOIN Projects
ON Employees.EmployeeID = Projects.EmployeeID
ORDER BY DeptName
Un join incrociato produce un set di risultati che include ogni riga della prima tabella unita a ogni riga della seconda tabella. L'insieme dei risultati è noto come prodotto cartesiano delle tabelle. L'esempio qui sotto mostra come codificare un join incrociato utilizzando la sintassi esplicita o implicita. Per utilizzare la sintassi esplicita, si includono le parole chiave CROSS JOIN tra le due tabelle nella clausola FROM. Si noti che, per il modo in cui funziona un join, non è necessario includere una condizione di unione. Lo stesso vale quando si usa la sintassi implicita. In questo caso, si elencano semplicemente le tabelle nella clausola FROM e si omette la condizione di join dalla clausola WHERE. Le due istruzioni SELECT di questo esempio illustrano il funzionamento dei cross join. Entrambe le istruzioni combinano i dati delle tabelle Reparti e Dipendenti. Come si può vedere, il risultato è una tabella che include 45 righe. Ognuna delle cinque righe della tabella Reparti combinate con le nove righe della tabella Dipendenti. Anche se questo insieme di risultati è relativamente piccolo, si può immaginare quanto sarebbe grande se le tabelle includessero centinaia o migliaia di righe. Studiando questi esempi, ci si rende conto che i cross join hanno pochi usi pratici. Di conseguenza, raramente, se non mai, sarà necessario utilizzarne uno.
SELECT select_list
FROM table_l CROSS JOIN table_2
USE AP
GO
SELECT Departments.DeptNo, DeptName, EmployeeID, LastName
FROM Departments CROSS JOIN Employees
ORDER BY Departments.DeptNo
SELECT select_list
FROM table_l, table_2
USE AP
GO
SELECT Departments.DeptNo, DeptName, EmployeeID, LastName
FROM Departments, Employees
ORDER BY Departments.DeptNo
Come un join, una union combina i dati di due o più tabelle. Tuttavia, invece di combinare le colonne delle tabelle di base, un'unione combina le righe di due o più insiemi di risultati. Vedrete come funziona negli argomenti che seguono.
L'esempio qui sotto mostra come codificare un'unione. Come mostra la sintassi, si crea un'unione collegando due o più istruzioni SELECT con la parola chiave UNION. Perché funzioni, il risultato di ogni istruzione SELECT deve avere lo stesso numero di colonne e i tipi di dati delle colonne corrispondenti in ogni tabella devono essere compatibili. In questa sintassi, ho indentato tutte le istruzioni SELECT collegate dall'operatore UNION, in modo da rendere più semplice l'operazione. Tuttavia, in un ambiente di produzione, è comune vedere le istruzioni SELECT e l'operatore UNION codificati allo stesso livello di indentazione. Se si vuole ordinare il risultato di un'operazione di unione, si può codificare una clausola ORDER BY dopo l'ultima istruzione SELECT. Si noti che i nomi delle colonne in questa clausola devono essere gli stessi utilizzati nella prima istruzione SELECT. Questo perché i nomi delle colonne usati nella prima istruzione SELECT sono quelli usati nell'insieme dei risultati. Per impostazione predefinita, un'operazione di unione rimuove le righe duplicate dall'insieme dei risultati. Se non si vuole questo, si può includere la parola chiave ALL. Nella maggior parte dei casi, tuttavia, si omette questa parola chiave.
L'esempio seguente mostra come utilizzare un'unione per combinare i dati di due tabelle diverse. In questo caso, la tabella Activelnvoices (Fatture attive) contiene le fatture con fatture con saldi in sospeso, mentre la tabella Fatture pagate contiene le fatture che sono state pagate completamente. Entrambe le tabelle hanno la stessa struttura della tabella Fatture, come si è visto nelle figure precedenti. Questa operazione di unione combina le righe di entrambe le tabelle che hanno una data fattura uguale o successiva al 2/1/2016. Si noti che la prima istruzione SELECT include una colonna denominata Sorgente che contiene il valore letterale “Attivo”. La seconda SELECT include una colonna con lo stesso nome, ma che contiene il valore letterale “Pagato”. Questa colonna viene utilizzata per indicare da quale tabella proviene ogni riga del set di risultati. Sebbene a questa colonna sia stato assegnato lo stesso nome in entrambe le istruzioni SELECT è bene sapere che non è detto che sia così. Infatti, nessuna delle colonne deve avere lo stesso nome. Le colonne corrispondenti devono avere tipi di dati compatibili. Ma le relazioni corrispondenti sono determinate dall'ordine in cui le colonne sono codificate nelle clausole SELECT, non dai loro nomi. Quando si usano gli alias di colonna, però, di solito si assegna lo stesso nome alle colonne corrispondenti, in modo che l'istruzione sia più facile da capire.
SELECT_statement_l
UNION [ALL]
SELECT_statement_2
[UNION [ALL]
SELECT_statement_3] ...
[ORDER BY order_by_list]
USE AP
GO
-- create the ActiveInvoices table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE ActiveInvoices(
InvoiceID int IDENTITY(1,1) NOT NULL,
VendorID int NOT NULL,
InvoiceNumber varchar(50) NOT NULL,
InvoiceDate date NOT NULL,
InvoiceTotal money NOT NULL,
PaymentTotal money NOT NULL,
CreditTotal money NOT NULL,
TermsID int NOT NULL,
InvoiceDueDate date NOT NULL,
PaymentDate date NULL,
CONSTRAINT PK_ActiveInvoices PRIMARY KEY CLUSTERED
(
InvoiceID ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
SET IDENTITY_INSERT ActiveInvoices ON
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (89, 72, N'39104', CAST(N'2023-01-10' AS Date), 85.3100, 0.0000, 0.0000, 3, CAST(N'2023-02-09' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (94, 123, N'963253264', CAST(N'2023-01-18' AS Date), 52.2500, 0.0000, 0.0000, 3, CAST(N'2023-02-17' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (98, 83, N'31361833', CAST(N'2023-01-21' AS Date), 579.4200, 0.0000, 0.0000, 2, CAST(N'2023-02-10' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (99, 123, N'263253268', CAST(N'2023-01-21' AS Date), 59.9700, 0.0000, 0.0000, 3, CAST(N'2023-02-20' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (100, 123, N'263253270', CAST(N'2023-01-22' AS Date), 67.9200, 0.0000, 0.0000, 3, CAST(N'2023-02-21' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (101, 123, N'263253273', CAST(N'2023-01-22' AS Date), 30.7500, 0.0000, 0.0000, 3, CAST(N'2023-02-21' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (102, 110, N'P-0608', CAST(N'2023-01-23' AS Date), 20551.1800, 0.0000, 1200.0000, 3, CAST(N'2023-02-22' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (105, 106, N'9982771', CAST(N'2023-01-24' AS Date), 503.2000, 0.0000, 0.0000, 3, CAST(N'2023-02-23' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (110, 80, N'134116', CAST(N'2023-01-28' AS Date), 90.3600, 0.0000, 0.0000, 2, CAST(N'2023-02-17' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (112, 110, N'0-2436', CAST(N'2023-01-31' AS Date), 10976.0600, 0.0000, 0.0000, 3, CAST(N'2023-03-01' AS Date), NULL)
INSERT ActiveInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (113, 37, N'547480102', CAST(N'2023-02-01' AS Date), 224.0000, 0.0000, 0.0000, 3, CAST(N'2023-03-01' AS Date), NULL)
SET IDENTITY_INSERT ActiveInvoices OFF
USE AP
GO
-- create the PaidInvoices table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE PaidInvoices (
InvoiceID int IDENTITY(1,1) NOT NULL,
VendorID int NOT NULL,
InvoiceNumber varchar(50) NOT NULL,
InvoiceDate date NOT NULL,
InvoiceTotal money NOT NULL,
PaymentTotal money NOT NULL,
CreditTotal money NOT NULL,
TermsID int NOT NULL,
InvoiceDueDate date NOT NULL,
PaymentDate date NULL
CONSTRAINT PK_PaidInvoices PRIMARY KEY CLUSTERED
(
InvoiceID ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
SET IDENTITY_INSERT PaidInvoices ON
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (1, 122, N'989319-457', CAST(N'2022-10-08' AS Date), 3813.3300, 3813.3300, 0.0000, 3, CAST(N'2022-11-08' AS Date), CAST(N'2022-11-07' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (2, 123, N'263253241', CAST(N'2022-10-10' AS Date), 40.2000, 40.2000, 0.0000, 3, CAST(N'2022-11-10' AS Date), CAST(N'2022-11-14' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (3, 123, N'963253234', CAST(N'2022-10-13' AS Date), 138.7500, 138.7500, 0.0000, 3, CAST(N'2022-11-13' AS Date), CAST(N'2022-11-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (4, 123, N'2-000-2993', CAST(N'2022-10-16' AS Date), 144.7000, 144.7000, 0.0000, 3, CAST(N'2022-11-16' AS Date), CAST(N'2022-11-12' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (5, 123, N'963253251', CAST(N'2022-10-16' AS Date), 15.5000, 15.5000, 0.0000, 3, CAST(N'2022-11-16' AS Date), CAST(N'2022-11-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (6, 123, N'963253261', CAST(N'2022-10-16' AS Date), 42.7500, 42.7500, 0.0000, 3, CAST(N'2022-11-16' AS Date), CAST(N'2022-11-21' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (7, 123, N'963253237', CAST(N'2022-10-21' AS Date), 172.5000, 172.5000, 0.0000, 3, CAST(N'2022-11-21' AS Date), CAST(N'2022-11-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (8, 89, N'125520-1', CAST(N'2022-10-24' AS Date), 95.0000, 95.0000, 0.0000, 1, CAST(N'2022-11-04' AS Date), CAST(N'2022-11-01' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (9, 121, N'97/488', CAST(N'2022-10-24' AS Date), 601.9500, 601.9500, 0.0000, 3, CAST(N'2022-11-24' AS Date), CAST(N'2022-11-21' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (10, 123, N'263253250', CAST(N'2022-10-24' AS Date), 42.6700, 42.6700, 0.0000, 3, CAST(N'2022-11-24' AS Date), CAST(N'2022-11-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (11, 123, N'963253262', CAST(N'2022-10-25' AS Date), 42.5000, 42.5000, 0.0000, 3, CAST(N'2022-11-25' AS Date), CAST(N'2022-11-20' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (12, 96, N'I77271-O01', CAST(N'2022-10-26' AS Date), 662.0000, 662.0000, 0.0000, 2, CAST(N'2022-11-16' AS Date), CAST(N'2022-11-13' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (13, 95, N'111-92R-10096', CAST(N'2022-10-30' AS Date), 16.3300, 16.3300, 0.0000, 2, CAST(N'2022-11-20' AS Date), CAST(N'2022-11-23' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (14, 115, N'25022117', CAST(N'2022-11-01' AS Date), 6.0000, 6.0000, 0.0000, 4, CAST(N'2022-12-10' AS Date), CAST(N'2022-12-10' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (15, 48, N'P02-88D77S7', CAST(N'2022-11-03' AS Date), 856.9200, 856.9200, 0.0000, 3, CAST(N'2022-12-02' AS Date), CAST(N'2022-11-30' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (16, 97, N'21-4748363', CAST(N'2022-11-03' AS Date), 9.9500, 9.9500, 0.0000, 2, CAST(N'2022-11-23' AS Date), CAST(N'2022-11-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (17, 123, N'4-321-2596', CAST(N'2022-11-05' AS Date), 10.0000, 10.0000, 0.0000, 3, CAST(N'2022-12-04' AS Date), CAST(N'2022-12-05' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (18, 123, N'963253242', CAST(N'2022-11-06' AS Date), 104.0000, 104.0000, 0.0000, 3, CAST(N'2022-12-05' AS Date), CAST(N'2022-12-05' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (19, 34, N'QP58872', CAST(N'2022-11-07' AS Date), 116.5400, 116.5400, 0.0000, 1, CAST(N'2022-11-17' AS Date), CAST(N'2022-11-19' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (20, 115, N'24863706', CAST(N'2022-11-10' AS Date), 6.0000, 6.0000, 0.0000, 4, CAST(N'2022-12-19' AS Date), CAST(N'2022-12-15' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (21, 119, N'10843', CAST(N'2022-11-11' AS Date), 4901.2600, 4901.2600, 0.0000, 2, CAST(N'2022-11-30' AS Date), CAST(N'2022-11-29' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (22, 123, N'963253235', CAST(N'2022-11-11' AS Date), 108.2500, 108.2500, 0.0000, 3, CAST(N'2022-12-10' AS Date), CAST(N'2022-12-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (23, 97, N'21-4923721', CAST(N'2022-11-13' AS Date), 9.9500, 9.9500, 0.0000, 2, CAST(N'2022-12-02' AS Date), CAST(N'2022-11-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (24, 113, N'77290', CAST(N'2022-11-13' AS Date), 1750.0000, 1750.0000, 0.0000, 5, CAST(N'2023-01-02' AS Date), CAST(N'2023-01-05' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (25, 123, N'963253246', CAST(N'2022-11-13' AS Date), 129.0000, 129.0000, 0.0000, 3, CAST(N'2022-12-12' AS Date), CAST(N'2022-12-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (26, 123, N'4-342-8069', CAST(N'2022-11-14' AS Date), 10.0000, 10.0000, 0.0000, 3, CAST(N'2022-12-13' AS Date), CAST(N'2022-12-13' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (27, 88, N'972110', CAST(N'2022-11-15' AS Date), 207.7800, 207.7800, 0.0000, 1, CAST(N'2022-11-25' AS Date), CAST(N'2022-11-27' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (28, 123, N'963253263', CAST(N'2022-11-16' AS Date), 109.5000, 109.5000, 0.0000, 3, CAST(N'2022-12-15' AS Date), CAST(N'2022-12-10' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (29, 108, N'121897', CAST(N'2022-11-19' AS Date), 450.0000, 450.0000, 0.0000, 4, CAST(N'2022-12-28' AS Date), CAST(N'2023-01-03' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (30, 123, N'1-200-5164', CAST(N'2022-11-20' AS Date), 63.4000, 63.4000, 0.0000, 3, CAST(N'2022-12-19' AS Date), CAST(N'2022-12-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (31, 104, N'P02-3772', CAST(N'2022-11-21' AS Date), 7125.3400, 7125.3400, 0.0000, 3, CAST(N'2022-12-20' AS Date), CAST(N'2022-12-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (32, 121, N'97/486', CAST(N'2022-11-21' AS Date), 953.1000, 953.1000, 0.0000, 3, CAST(N'2022-12-20' AS Date), CAST(N'2022-12-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (33, 105, N'94007005', CAST(N'2022-11-23' AS Date), 220.0000, 220.0000, 0.0000, 3, CAST(N'2022-12-22' AS Date), CAST(N'2022-12-26' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (34, 123, N'963253232', CAST(N'2022-11-23' AS Date), 127.7500, 127.7500, 0.0000, 3, CAST(N'2022-12-22' AS Date), CAST(N'2022-12-18' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (35, 107, N'RTR-72-3662-X', CAST(N'2022-11-25' AS Date), 1600.0000, 1600.0000, 0.0000, 4, CAST(N'2023-01-04' AS Date), CAST(N'2023-01-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (36, 121, N'97/465', CAST(N'2022-11-25' AS Date), 565.1500, 565.1500, 0.0000, 3, CAST(N'2022-12-24' AS Date), CAST(N'2022-12-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (37, 123, N'963253260', CAST(N'2022-11-25' AS Date), 36.0000, 36.0000, 0.0000, 3, CAST(N'2022-12-24' AS Date), CAST(N'2022-12-26' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (38, 123, N'963253272', CAST(N'2022-11-26' AS Date), 61.5000, 61.5000, 0.0000, 3, CAST(N'2022-12-25' AS Date), CAST(N'2022-12-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (39, 110, N'0-2058', CAST(N'2022-11-28' AS Date), 37966.1900, 37966.1900, 0.0000, 3, CAST(N'2022-12-27' AS Date), CAST(N'2022-12-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (40, 121, N'97/503', CAST(N'2022-11-30' AS Date), 639.7700, 639.7700, 0.0000, 3, CAST(N'2022-12-28' AS Date), CAST(N'2022-12-25' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (41, 123, N'963253255', CAST(N'2022-11-30' AS Date), 53.7500, 53.7500, 0.0000, 3, CAST(N'2022-12-28' AS Date), CAST(N'2022-12-27' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (42, 123, N'94007069', CAST(N'2022-11-30' AS Date), 400.0000, 400.0000, 0.0000, 3, CAST(N'2022-12-28' AS Date), CAST(N'2023-01-01' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (43, 72, N'40318', CAST(N'2022-12-01' AS Date), 21842.0000, 21842.0000, 0.0000, 3, CAST(N'2023-01-01' AS Date), CAST(N'2022-12-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (44, 95, N'111-92R-10094', CAST(N'2022-12-01' AS Date), 19.6700, 19.6700, 0.0000, 2, CAST(N'2022-12-21' AS Date), CAST(N'2022-12-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (45, 122, N'989319-437', CAST(N'2022-12-01' AS Date), 2765.3600, 2765.3600, 0.0000, 3, CAST(N'2023-01-01' AS Date), CAST(N'2022-12-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (46, 37, N'547481328', CAST(N'2022-12-03' AS Date), 224.0000, 224.0000, 0.0000, 3, CAST(N'2023-01-03' AS Date), CAST(N'2023-01-04' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (47, 83, N'31359783', CAST(N'2022-12-03' AS Date), 1575.0000, 1575.0000, 0.0000, 2, CAST(N'2022-12-23' AS Date), CAST(N'2022-12-21' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (48, 123, N'1-202-2978', CAST(N'2022-12-03' AS Date), 33.0000, 33.0000, 0.0000, 3, CAST(N'2023-01-03' AS Date), CAST(N'2023-01-05' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (49, 95, N'111-92R-10097', CAST(N'2022-12-04' AS Date), 16.3300, 16.3300, 0.0000, 2, CAST(N'2022-12-24' AS Date), CAST(N'2022-12-26' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (50, 37, N'547479217', CAST(N'2022-12-07' AS Date), 116.0000, 116.0000, 0.0000, 3, CAST(N'2023-01-07' AS Date), CAST(N'2023-01-07' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (51, 122, N'989319-477', CAST(N'2022-12-08' AS Date), 2184.1100, 2184.1100, 0.0000, 3, CAST(N'2023-01-08' AS Date), CAST(N'2023-01-08' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (52, 34, N'Q545443', CAST(N'2022-12-09' AS Date), 1083.5800, 1083.5800, 0.0000, 1, CAST(N'2022-12-19' AS Date), CAST(N'2022-12-23' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (53, 95, N'111-92R-10092', CAST(N'2022-12-09' AS Date), 46.2100, 46.2100, 0.0000, 2, CAST(N'2022-12-28' AS Date), CAST(N'2023-01-02' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (54, 121, N'97/553B', CAST(N'2022-12-10' AS Date), 313.5500, 313.5500, 0.0000, 3, CAST(N'2023-01-10' AS Date), CAST(N'2023-01-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (55, 123, N'963253245', CAST(N'2022-12-10' AS Date), 40.7500, 40.7500, 0.0000, 3, CAST(N'2023-01-10' AS Date), CAST(N'2023-01-12' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (56, 86, N'367447', CAST(N'2022-12-11' AS Date), 2433.0000, 2433.0000, 0.0000, 1, CAST(N'2022-12-21' AS Date), CAST(N'2022-12-17' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (57, 103, N'75C-90227', CAST(N'2022-12-11' AS Date), 1367.5000, 1367.5000, 0.0000, 5, CAST(N'2023-01-31' AS Date), CAST(N'2023-01-31' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (58, 123, N'963253256', CAST(N'2022-12-11' AS Date), 53.2500, 53.2500, 0.0000, 3, CAST(N'2023-01-11' AS Date), CAST(N'2023-01-07' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (59, 123, N'4-314-3057', CAST(N'2022-12-11' AS Date), 13.7500, 13.7500, 0.0000, 3, CAST(N'2023-01-11' AS Date), CAST(N'2023-01-15' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (60, 122, N'989319-497', CAST(N'2022-12-12' AS Date), 2312.2000, 2312.2000, 0.0000, 3, CAST(N'2023-01-12' AS Date), CAST(N'2023-01-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (61, 115, N'24946731', CAST(N'2022-12-15' AS Date), 25.6700, 25.6700, 0.0000, 4, CAST(N'2023-01-25' AS Date), CAST(N'2023-01-26' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (62, 123, N'963253269', CAST(N'2022-12-15' AS Date), 26.7500, 26.7500, 0.0000, 3, CAST(N'2023-01-15' AS Date), CAST(N'2023-01-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (63, 122, N'989319-427', CAST(N'2022-12-16' AS Date), 2115.8100, 2115.8100, 0.0000, 3, CAST(N'2023-01-16' AS Date), CAST(N'2023-01-19' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (64, 123, N'963253267', CAST(N'2022-12-17' AS Date), 23.5000, 23.5000, 0.0000, 3, CAST(N'2023-01-17' AS Date), CAST(N'2023-01-19' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (65, 99, N'509786', CAST(N'2022-12-18' AS Date), 6940.2500, 6940.2500, 0.0000, 3, CAST(N'2023-01-18' AS Date), CAST(N'2023-01-15' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (66, 123, N'263253253', CAST(N'2022-12-18' AS Date), 31.9500, 31.9500, 0.0000, 3, CAST(N'2023-01-18' AS Date), CAST(N'2023-01-21' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (67, 122, N'989319-487', CAST(N'2022-12-20' AS Date), 1927.5400, 1927.5400, 0.0000, 3, CAST(N'2023-01-20' AS Date), CAST(N'2023-01-18' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (68, 81, N'MABO1489', CAST(N'2022-12-21' AS Date), 936.9300, 936.9300, 0.0000, 2, CAST(N'2023-01-11' AS Date), CAST(N'2023-01-10' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (69, 80, N'133560', CAST(N'2022-12-22' AS Date), 175.0000, 175.0000, 0.0000, 2, CAST(N'2023-01-12' AS Date), CAST(N'2023-01-16' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (70, 115, N'24780512', CAST(N'2022-12-22' AS Date), 6.0000, 6.0000, 0.0000, 4, CAST(N'2023-02-01' AS Date), CAST(N'2023-01-29' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (71, 123, N'963253254', CAST(N'2022-12-22' AS Date), 108.5000, 108.5000, 0.0000, 3, CAST(N'2023-01-22' AS Date), CAST(N'2023-01-20' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (72, 123, N'43966316', CAST(N'2022-12-22' AS Date), 10.0000, 10.0000, 0.0000, 3, CAST(N'2023-01-22' AS Date), CAST(N'2023-01-17' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (73, 114, N'CBM9920-M-T77109', CAST(N'2022-12-23' AS Date), 290.0000, 290.0000, 0.0000, 1, CAST(N'2023-01-03' AS Date), CAST(N'2022-12-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (74, 102, N'109596', CAST(N'2022-12-24' AS Date), 41.8000, 41.8000, 0.0000, 4, CAST(N'2023-02-03' AS Date), CAST(N'2023-02-04' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (75, 123, N'7548906-20', CAST(N'2022-12-24' AS Date), 27.0000, 27.0000, 0.0000, 3, CAST(N'2023-01-24' AS Date), CAST(N'2023-01-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (76, 123, N'963253248', CAST(N'2022-12-24' AS Date), 241.0000, 241.0000, 0.0000, 3, CAST(N'2023-01-24' AS Date), CAST(N'2023-01-25' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (77, 121, N'97/553', CAST(N'2022-12-25' AS Date), 904.1400, 904.1400, 0.0000, 3, CAST(N'2023-01-25' AS Date), CAST(N'2023-01-25' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (78, 121, N'97/522', CAST(N'2022-12-28' AS Date), 1962.1300, 1762.1300, 200.0000, 3, CAST(N'2023-01-28' AS Date), CAST(N'2023-01-30' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (79, 100, N'587056', CAST(N'2022-12-28' AS Date), 2184.5000, 2184.5000, 0.0000, 4, CAST(N'2023-02-09' AS Date), CAST(N'2023-02-07' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (80, 122, N'989319-467', CAST(N'2023-01-01' AS Date), 2318.0300, 2318.0300, 0.0000, 3, CAST(N'2023-01-31' AS Date), CAST(N'2023-01-29' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (81, 123, N'263253265', CAST(N'2023-01-02' AS Date), 26.2500, 26.2500, 0.0000, 3, CAST(N'2023-02-01' AS Date), CAST(N'2023-01-28' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (82, 94, N'203339-13', CAST(N'2023-01-05' AS Date), 17.5000, 17.5000, 0.0000, 2, CAST(N'2023-01-25' AS Date), CAST(N'2023-01-27' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (83, 95, N'111-92R-10093', CAST(N'2023-01-06' AS Date), 39.7700, 39.7700, 0.0000, 2, CAST(N'2023-01-26' AS Date), CAST(N'2023-01-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (84, 123, N'963253258', CAST(N'2023-01-06' AS Date), 111.0000, 111.0000, 0.0000, 3, CAST(N'2023-02-05' AS Date), CAST(N'2023-02-05' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (85, 123, N'963253271', CAST(N'2023-01-07' AS Date), 158.0000, 158.0000, 0.0000, 3, CAST(N'2023-02-06' AS Date), CAST(N'2023-02-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (86, 123, N'963253230', CAST(N'2023-01-07' AS Date), 739.2000, 739.2000, 0.0000, 3, CAST(N'2023-02-06' AS Date), CAST(N'2023-02-06' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (87, 123, N'963253244', CAST(N'2023-01-08' AS Date), 60.0000, 60.0000, 0.0000, 3, CAST(N'2023-02-07' AS Date), CAST(N'2023-02-09' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (88, 123, N'963253239', CAST(N'2023-01-08' AS Date), 147.2500, 147.2500, 0.0000, 3, CAST(N'2023-02-07' AS Date), CAST(N'2023-02-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (90, 123, N'963253252', CAST(N'2023-01-12' AS Date), 38.7500, 38.7500, 0.0000, 3, CAST(N'2023-02-11' AS Date), CAST(N'2023-02-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (91, 95, N'111-92R-10095', CAST(N'2023-01-15' AS Date), 32.7000, 32.7000, 0.0000, 2, CAST(N'2023-02-04' AS Date), CAST(N'2023-02-06' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (92, 117, N'111897', CAST(N'2023-01-15' AS Date), 16.6200, 16.6200, 0.0000, 3, CAST(N'2023-02-14' AS Date), CAST(N'2023-02-14' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (93, 123, N'4-327-7357', CAST(N'2023-01-16' AS Date), 162.7500, 162.7500, 0.0000, 3, CAST(N'2023-02-15' AS Date), CAST(N'2023-02-11' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (95, 82, N'C73-24', CAST(N'2023-01-19' AS Date), 600.0000, 600.0000, 0.0000, 2, CAST(N'2023-02-08' AS Date), CAST(N'2023-02-13' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (96, 110, N'P-0259', CAST(N'2023-01-19' AS Date), 26881.4000, 26881.4000, 0.0000, 3, CAST(N'2023-02-18' AS Date), CAST(N'2023-02-20' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (97, 90, N'97-1024A', CAST(N'2023-01-20' AS Date), 356.4800, 356.4800, 0.0000, 2, CAST(N'2023-02-09' AS Date), CAST(N'2023-02-07' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (103, 122, N'989319-417', CAST(N'2023-01-23' AS Date), 2051.5900, 2051.5900, 0.0000, 3, CAST(N'2023-02-22' AS Date), CAST(N'2023-02-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (104, 123, N'263253243', CAST(N'2023-01-23' AS Date), 44.4400, 44.4400, 0.0000, 3, CAST(N'2023-02-22' AS Date), CAST(N'2023-02-24' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (106, 110, N'0-2060', CAST(N'2023-01-24' AS Date), 23517.5800, 21221.6300, 2295.9500, 3, CAST(N'2023-02-23' AS Date), CAST(N'2023-02-27' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (107, 122, N'989319-447', CAST(N'2023-01-24' AS Date), 3689.9900, 3689.9900, 0.0000, 3, CAST(N'2023-02-23' AS Date), CAST(N'2023-02-19' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (108, 123, N'963253240', CAST(N'2023-01-24' AS Date), 67.0000, 67.0000, 0.0000, 3, CAST(N'2023-02-23' AS Date), CAST(N'2023-02-23' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (109, 121, N'97/222', CAST(N'2023-01-25' AS Date), 1000.4600, 1000.4600, 0.0000, 3, CAST(N'2023-02-24' AS Date), CAST(N'2023-02-22' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (111, 123, N'263253257', CAST(N'2023-01-30' AS Date), 22.5700, 22.5700, 0.0000, 3, CAST(N'2023-03-01' AS Date), CAST(N'2023-03-03' AS Date))
INSERT PaidInvoices (InvoiceID, VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate) VALUES (114, 123, N'963253249', CAST(N'2023-02-02' AS Date), 127.7500, 127.7500, 0.0000, 3, CAST(N'2023-03-01' AS Date), CAST(N'2023-03-04' AS Date))
SET IDENTITY_INSERT PaidInvoices OFF
USE AP
GO
SELECT 'Active' AS Source, InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Activeinvoices
WHERE InvoiceDate >= '2022-12-15'
UNION
SELECT 'Paid' AS Source, InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Paidinvoices
WHERE InvoiceDate >= '2022-12-15'
ORDER BY InvoiceTotal DESC
L'esempio qui sotto mostra come utilizzare le unioni per combinare i dati di una singola tabella. Nel primo esempio, le righe della tabella Fatture che hanno un saldo da pagare vengono combinate con le righe della stessa tabella che sono state pagate per intero. Come nell'esempio precedente, all'inizio di ogni tabella intermedia viene aggiunta una colonna denominata Source. In questo modo, il risultato finale indica se ogni fattura è attiva o pagata. Il secondo esempio di questa figura mostra come si può utilizzare un'unione con i dati uniti da due tabelle. In questo caso, ogni istruzione SELECT unisce i dati delle tabelle Fatture e Venditori. La prima istruzione SELECT recupera le fatture con totali superiori a 10.000 dollari. Quindi calcola un pagamento pari al 33% del totale della fattura. Le altre due istruzioni SELECT sono simili. La seconda recupera le fatture con un totale compreso tra 500 e 10.000 dollari e calcola un pagamento del 50%. La terza recupera le fatture con un totale inferiore a 500 dollari e imposta il pagamento al 100% del totale. Anche se questo è un po' irrealistico, aiuta a illustrare la flessibilità delle operazioni con le unioni. Si noti che in questo esempio vengono assegnati gli stessi alias di colonna in ogni istruzione SELECT. Anche se gli alias della seconda e terza istruzione SELECT non hanno alcun effetto sulla query, credo che rendano la query più facile da leggere. In particolare, rende facile vedere che le tre istruzioni SELECT hanno lo stesso numero e lo stesso tipo di colonne.
USE AP
GO
SELECT 'Active' AS Source, InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Invoices
-- fatture con un saldo da pagare
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0
UNION
SELECT 'Paid' AS Source, InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Invoices
-- fatture pagate per intero
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) <= 0
ORDER BY InvoiceTotal DESC
USE AP
GO
SELECT InvoiceNumber, VendorName, '33% Payment' AS PaymentType,
InvoiceTotal AS Total, (InvoiceTotal * 0.333) AS Payment
FROM Invoices JOIN Vendors
ON Invoices.VendorID = Vendors.VendorID
WHERE InvoiceTotal > 10000
UNION
SELECT InvoiceNumber, VendorName, '50% Payment' AS PaymentType,
InvoiceTotal AS Total, (InvoiceTotal * 0.5) AS Payment
FROM Invoices JOIN Vendors
ON Invoices.VendorID = Vendors.VendorID
WHERE InvoiceTotal BETWEEN 500 AND 10000
UNION
SELECT InvoiceNumber, VendorName, 'Full amount' AS PaymentType,
InvoiceTotal AS Total, InvoiceTotal AS Payment
FROM Invoices JOIN Vendors
ON Invoices.VendorID = Vendors.vendorID
WHERE InvoiceTotal < 500
ORDER BY PaymentType, VendorName, InvoiceNumber
Gli operatori EXCEPT e INTERSECT sono stati introdotti con SQL Server 2005. Come l'operatore UNION, gli operatori EXCEPT e INTERSECT funzionano con due o più insiemi di risultati, come mostrato nell'esempio seguente. Per questo motivo, tutti e tre questi operatori possono essere definiti operatori di insiemi. Inoltre, gli operatori EXCEPT seguono molte delle stesse regole dell'operatore UNION. La prima query mostrata in questo esempio utilizza l'operatore EXCEPT per restituire i nomi e i cognomi di tutti i clienti di un'azienda, ad eccezione dei clienti il cui nome e cognome sono presenti anche nella tabella Dipendenti. Poiché Thomas Hardy è l'unico nome uguale in entrambe le tabelle, questa è l'unica riga che viene esclusa dall'insieme dei risultati della query che precede l'operatore EXCEPT. La seconda query utilizza l'operatore INTERSECT per restituire il nome e il cognome di tutti i clienti della tabella Clienti il cui nome e cognome sono presenti anche nella tabella Dipendenti. Poiché Thomas Hardy è l'unico nome presente in entrambe le tabelle, questa è l'unica riga restituita nel set di risultati di questa query. Quando si utilizzano gli operatori EXCEPT e INTERSECT, bisogna seguire molte delle stesse regole che si devono seguire quando si lavora con l'operatore UNION. Tanto per cominciare, entrambe le istruzioni collegate da questi operatori devono restituire lo stesso numero di colonne. Inoltre, i tipi di dati per colonne devono essere compatibili. Infine, quando due query sono unite da un operatore EXCEPT o INTERSECT, i nomi delle colonne nell'insieme dei risultati finale sono presi dalla prima query. Ecco perché la clausola ORDER BY utilizza la colonna CustomerLast specificata dalla prima query invece della colonna LastName specificata dalla seconda query. Se si comprende il funzionamento dell'operatore UNION non dovrebbe essere difficile capire queste regole. Anche se spesso è possibile ottenere lo stesso insieme di risultati utilizzando una join interna o una subquery al posto dell'operatore UNION. o una sottoquery al posto degli operatori EXCEPT e INTERSECT, questi operatori sono un'utile funzione di SQL Server che può facilitare il confronto tra due insiemi di risultati.
SELECT_statement_l
{EXCEPT I INTERSECT}
SELECT_statement_2
[ORDER BY order_by_list]
USE AP
GO
-- create the Customers table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE Customers (
CustID int IDENTITY(1,1) NOT NULL,
CustomerLast nvarchar(30) NULL,
CustomerFirst nvarchar(30) NULL,
CustAddr nvarchar(60) NULL,
CustCity nvarchar(15) NULL,
CustState nvarchar(15) NULL,
CustZip nvarchar(10) NULL,
CustPhone nvarchar(24) NULL,
CONSTRAINT PK_Customers PRIMARY KEY CLUSTERED
(
CustID ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
USE AP
GO
SET IDENTITY_INSERT Customers ON
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (1, N'Anders', N'Maria', N'345 Winchell Pl', N'Anderson', N'IN', N'46014', N'(765) 555-7878')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (2, N'Trujillo', N'Ana', N'1298 E Smathers St', N'Benton', N'AR', N'72018', N'(501) 555-7733')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (3, N'Moreno', N'Antonio', N'6925 N Parkland Ave', N'Puyallup', N'WA', N'98373', N'(253) 555-8332')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (4, N'Hardy', N'Thomas', N'83 d''Urberville Ln', N'Casterbridge', N'GA', N'31209', N'(478) 555-1139')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (5, N'Berglund', N'Christina', N'22717 E 73rd Ave', N'Dubuque', N'IA', N'52004', N'(319) 555-1139')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (6, N'Moos', N'Hanna', N'1778 N Bovine Ave', N'Peoria', N'IL', N'61638', N'(309) 555-8755')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (7, N'Citeaux', N'Fred', N'1234 Main St', N'Normal', N'IL', N'61761', N'(309) 555-1914')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (8, N'Summer', N'Martin', N'1877 Ete Ct', N'Frogtown', N'LA', N'70563', N'(337) 555-9441')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (9, N'Lebihan', N'Laurence', N'717 E Michigan Ave', N'Chicago', N'IL', N'60611', N'(312) 555-9441')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (10, N'Lincoln', N'Elizabeth', N'4562 Rt 78 E', N'Vancouver', N'WA', N'98684', N'(360) 555-2680')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (32, N'Snyder', N'Howard', N'2732 Baker Blvd.', N'Eugene', N'OR', N'97403', N'(503) 555-7555')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (36, N'Latimer', N'Yoshi', N'City Center Plaza 516 Main St.', N'Elgin', N'OR', N'97827', N'(503) 555-6874')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (43, N'Steel', N'John', N'12 Orchestra Terrace', N'Walla Walla', N'WA', N'99362', N'(509) 555-7969')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (45, N'Yorres', N'Jaime', N'87 Polk St. Suite 5', N'San Francisco', N'CA', N'94117', N'(415) 555-5938')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (48, N'Wilson', N'Fran', N'89 Chiaroscuro Rd.', N'Portland', N'OR', N'97219', N'(503) 555-9573')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (55, N'Phillips', N'Rene', N'2743 Bering St.', N'Anchorage', N'AK', N'99508', N'(907) 555-7584')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (65, N'Wilson', N'Paula', N'2817 Milton Dr.', N'Albuquerque', N'NM', N'87110', N'(505) 555-5939')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (71, N'Pavarotti', N'Jose', N'187 Suffolk Ln.', N'Boise', N'ID', N'83720', N'(208) 555-8097')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (75, N'Braunschweiger', N'Art', N'P.O. Box 555', N'Lander', N'WY', N'82520', N'(307) 555-4680')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (77, N'Nixon', N'Liz', N'89 Jefferson Way Suite 2', N'Providence', N'RI', N'02909', N'(401) 555-3612')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (78, N'Wong', N'Liu', N'55 Grizzly Peak Rd.', N'Butte', N'MT', N'59801', N'(406) 555-5834')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (82, N'Nagy', N'Helvetius', N'722 DaVinci Blvd.', N'Concord', N'MA', N'01742', N'(351) 555-1219')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (89, N'Jablonski', N'Karl', N'305 - 14th Ave. S. Suite 3B', N'Seattle', N'WA', N'98128', N'(206) 555-4112')
INSERT Customers (CustID, CustomerLast, CustomerFirst, CustAddr, CustCity, CustState, CustZip, CustPhone) VALUES (92, N'Chelan', N'Donna', N'2299 E Baylor Dr', N'Dallas', N'TX', N'75224', N'(469) 555-8828')
SET IDENTITY_INSERT Customers OFF
USE AP
GO
SELECT CustomerFirst, CustomerLast
FROM Customers
EXCEPT
SELECT FirstName, LastName
FROM Employees
ORDER BY CustomerLast
USE AP
GO
SELECT CustomerFirst, CustomerLast
FROM Customers
INTERSECT
SELECT FirstName, LastName
FROM Employees
In questa lezione si sono apprese diverse tecniche per combinare i dati di due o più tabelle in un unico insieme di risultati. In particolare, si è appreso come utilizzare la sintassi di SQL-92 per combinare i dati utilizzando i join interni. Di tutte le tecniche presentate in questo capitolo, questa è quella che utilizzerete più spesso. Per questo motivo, prima di continuare, è bene essere sicuri di averla compresa a fondo.