C#: atestat și pregătire ONTI

C#: JOIN și rapoarte care păstrează valorile zero

Construiește un raport SQL pentru aplicația C# folosind LEFT JOIN și COUNT. Include cărțile fără împrumuturi și evită numărarea rândului artificial de legătură.

Un raport cu numărul împrumuturilor trebuie să includă și cărțile care nu au fost împrumutate. INNER JOIN ar elimina aceste cărți. LEFT JOIN păstrează fiecare rând din Books și adaugă valorile copil disponibile. Pentru o carte fără copil, coloanele din Loans sunt NULL.

Cum lucrezi cu exemplul

Schema și interogarea sunt disponibile în arhiva lecției. Verificarea semantică folosește SQLite în memorie; integrarea Access/OleDb se face separat pe Windows, după pregătirea formatului și providerului potrivit.

Descarcă sursele și instrucțiunile.

Ideea și pașii de implementare

Grupăm după BookId și Title, iar COUNT(Loans.LoanId) numără numai ID-urile copil nenule. COUNT(*) ar număra și rândul păstrat pentru o carte fără împrumuturi, producând unu în loc de zero. Aceasta este o diferență semantică importantă, nu doar o variantă de scriere.

Legătura se face prin ID, nu prin titlu. Dacă legi două tabele după un câmp neunic, poți multiplica rândurile și umfla totalurile. Pentru rapoarte cu mai multe relații unu-la-mulți, verifică separat cardinalitatea fiecărei legături înainte de agregare.

Exemplu și rezultat așteptat

Cartea Algoritmi are două împrumuturi, Grafuri are unul, iar Povesti are zero. Rezultatul conține trei rânduri, cu totalurile 2, 1 și 0. Suma este trei, egală cu numărul împrumuturilor din setul de test. Această egalitate este o verificare utilă pentru raportul simplu.

Schemă pentru lecția 34: Books 1, 2, 3; LEFT JOIN Loans; COUNT(LoanId); Rezultat: 2, 1, 0.Books 1, 2, 3 → LEFT JOIN Loans → COUNT(LoanId) → Rezultat: 2, 1, 0.Mărește schema ↗

Interogarea verificată

SELECT Books.BookId, Books.Title, COUNT(Loans.LoanId) AS LoanCount
FROM Books LEFT JOIN Loans ON Books.BookId = Loans.BookId
GROUP BY Books.BookId, Books.Title
ORDER BY Books.BookId;

Rezultatul, în ordinea rândurilor:

1 | Algoritmi | 2
2 | Grafuri | 1
3 | Povesti | 0

Greșeli și limite

O condiție pe tabelul copil pusă în WHERE poate elimina rândurile fără copil și transforma efectiv rezultatul într-unul asemănător INNER JOIN. Dacă vrei să numeri numai un anumit tip de împrumut, gândește atent locul condiției. Nu folosi DISTINCT pentru a ascunde o legătură greșită fără să înțelegi cauza duplicării.

Exersează

Înlocuiește temporar COUNT(Loans.LoanId) cu COUNT(*) și observă eroarea pentru Povesti. Revino la varianta corectă, adaugă încă un împrumut pentru Grafuri și verifică totalurile 2, 2, 0. Scrie un test care verifică explicit rândul cu zero, nu doar suma generală.

Continuă parcursul

Parcursul complet de 50 de lecții

Bazele C#

Lecția precedentă: C#: interogări SQL cu filtrare și ordine stabilă

Lecția următoare: C#: citește Access prin OleDb și parametri tipizați.

Referință: documentația Microsoft.

Întrebări frecvente

De ce folosesc LEFT JOIN?

Pentru a păstra și cărțile fără împrumuturi.

De ce COUNT(*) nu dă zero?

Numără rândul păstrat de LEFT JOIN, chiar dacă toate coloanele copil sunt NULL.

Pot lega după titlu?

Este nesigur dacă titlul nu este unic. Folosește cheia stabilă.

Un pas mai departe

Autentifică-te pentru a păstra progresul în cont.

Exersează cu o problemă →