Në SQL, ju përshkruani «çfarë» dëshironi të merrni, dhe jo «si» duhet të zbatohet. Prandaj, problemi i zhvillimit të pyetjeve SQL në stilin «si dëgjohet, ashtu shkruhet» mban vendin e tij të nderuar, së bashku me .
Sot do të shohim disa shembuj të thjeshtë se ku mund të çojë kjo në kontekstin e përdorimit të GROUP/DISTINCT dhe KUFIZO së bashku me ta.
Ja, nĂ«se shkruani nĂ« pyetje «sĂ« pari bashkoni kĂ«to tabela, pastaj heqni tĂ« gjithĂ« dublikatĂ«, duhet tĂ« mbetet vetĂ«m njĂ« exemplar pĂ«r çdo çelĂ«s» â pikĂ«risht kĂ«shtu do tĂ« funksionojĂ«, edhe nĂ«se bashkimi nuk ishte i nevojshĂ«m fare.
Dhe ndonjĂ«herĂ« ndihmohet dhe kjo «thjesht funksionon», ndonjĂ«herĂ«âka njĂ« efekt negativ nĂ« performancĂ«, e ndonjĂ«herĂ« jep rezultate krejtĂ«sisht tĂ« papritura pĂ«r zhvilluesin.

Epo, ndoshta jo aq spektakolar, porâŠ
«Ăifti i Ă«mbĂ«l»: JOIN + DISTINCT
SELECT DISTINCT
X.*
FROM
X
JOIN
Y
ON Y.fk = X.pk
WHERE
Y.bool_condition; Duket e qartĂ« se çfarĂ« dĂ«shironin tĂ« merrni ato regjistrime X, pĂ«r tĂ« cilat nĂ« Y ka lidhje me kushtin e ekzekutuar. e kishim shkruar pyetjen pĂ«rmes JOIN â morĂ«m disa vlera pk disa herĂ« (aq sa ishin regjistrimet pĂ«rkatĂ«se nĂ« Y). Si ta heqim? Sigurisht DISTINCT!
VeçanĂ«risht «gĂ«zon» kur pĂ«r çdo regjistrim X ndodhen disa qindra regjistrime tĂ« lidhura Y, dhe pastaj heroikisht hiqen dublikatĂ«âŠ

Si ta rregullojmĂ«? SĂ« pari, duhet tĂ« kuptojmĂ« se detyra mund tĂ« modifikohet nĂ« «tĂ« marrĂ« regjistrimet X, pĂ«r tĂ« cilat nĂ« Y ka TĂ PAKTĂ NĂNJĂ lidhje me kushtin e ekzekutuar» â sepse nga regjistrimi Y nuk na nevojitet asgjĂ«.
EXISTS e vendosur
SELECT
*
FROM
X
WHERE
EXISTS(
SELECT
NULL
FROM
Y
WHERE
fk = X.pk AND
bool_condition
LIMIT 1
); Disa versione tĂ« PostgreSQL kuptojnĂ« se nĂ« EXISTS Ă«shtĂ« mjaft tĂ« gjejnĂ« regjistrimin e parĂ« qĂ« del, versionet mĂ« tĂ« vjetra â jo. Prandaj, unĂ« preferoj gjithmonĂ« tĂ« specifikoj LIMIT 1 brenda EKZISTON.
LATERAL JOIN
SELECT
X.*
FROM
X
, LATERAL (
SELECT
Y.*
FROM
Y
WHERE
fk = X.pk AND
bool_condition
LIMIT 1
) Y
WHERE
Y IS DISTINCT FROM NULL;Ky opsion gjithashtu lejon, nëse është e nevojshme, të kthehet menjëherë ndonjë të dhënë nga regjistrimi i lidhur Y që u gjet. Një variant i ngjashëm është shqyrtuar në artikullin .
«Pse të paguajmë më shumë»: DISTINCT [ON] + LIMIT 1
Një avantazh tjetër i tillë të transformimeve të pyetjes është mundësia për të kufizuar lehtësisht shfrytëzimin e regjistrave, nëse nevojiten vetëm një/s disa prej tyre, si në rastin e mëposhtëm:
SELECT DISTINCT ON(X.pk)
*
FROM
X
JOIN
Y
ON Y.fk = X.pk
LIMIT 1;Tani lexojmë pyetjen dhe përpiqemi të kuptojmë se çfarë propozohet të bëjë DBMS:
- bashkojmë tabelat
- e unikizojmë sipas X.pk
- nga regjistrat e mbetur zgjedhim një të vetëm
Pra, çfarĂ« morĂ«m? âNjĂ« regjistĂ«r tĂ« caktuarâ nga tĂ« unikizuarit â dhe sikur ta marrim kĂ«tĂ« njĂ« nga ata qĂ« nuk janĂ« unikĂ«, rezultatet do tĂ« ndryshonin ndonjĂ«herĂ«?.. âE nĂ«se nuk ka dallime, pĂ«rse tĂ« paguajmĂ« mĂ« shumĂ«?â
SELECT
*
FROM
(
SELECT
*
FROM
X
-- këtu mund të fusim kushte të përshtatshme
LIMIT 1 -- +1 Limit
) X
JOIN
Y
ON Y.fk = X.pk
LIMIT 1;
Dhe një temë e ngjashme me GROUP BY + LIMIT 1.
âMĂ« duhet vetĂ«m tĂ« pyesâ: GROUP implicit + LIMIT
Këto gjëra ndodhin në kontrollin e ndryshueshmërisë tabelës ose CTE gjatë ekzekutimit të pyetjeve: ... CASE WHEN ( SELECT count(*) FROM X LIMIT 1 ) = 0 THEN ...
Funksionet agreguese ( count/min/max/sum/...) përfundojnë me sukses në të gjithë grupin, edhe pa një tregues të dukshëm. Por me GRUPIM NGAnuk janë shumë të lidhura. KUFIZO Programuesi mund të mendojë
âpo nĂ«se ka regjistra, atĂ«herĂ« mĂ« duhet jo mĂ« shumĂ« se LIMITâ . Por nuk Ă«shtĂ« ashtu! Sepse pĂ«r bazĂ«n e tĂ« dhĂ«nave, kjo Ă«shtĂ«:numĂ«ro se çfarĂ« duan
- për të gjitha regjistrat kthe sa rreshta kërkohen
- Në varësi të kushteve të synuara, këtu është e përshtatshme të bëhet një nga zëvendësimet:
(count + LIMIT 1) = 0
NOT EXISTS(LIMIT 1)nĂ«(count + LIMIT 1) > 0EXISTS(LIMIT 1)nĂ«count >= N(SELECT count(*) FROM (... LIMIT N))nĂ«âSa tĂ« varfĂ«r nĂ« gramĂ«â: DISTINCT + LIMIT
SELECT DISTINCT pk FROM X LIMIT $1
Programuesi naiv mund të mendojë sinqerisht se ekzekutimi i pyetjes do të ndalet,sa herë që të gjejmë $1 vlerat e para të rastësishme të ndryshme Në të ardhmen, mund të funksionojë në këtë mënyrë falë nyjës së re.
Index Skip Scan , implementimi i së cilës tani po zhvillohet, por për momentin - jo.Për momentin, fillimisht
do tĂ« nxirren tĂ« gjitha regjistrat , do tĂ« unikizohen, dhe vetĂ«m nga ato do tĂ« kthehet aq sa Ă«shtĂ« kĂ«rkuar. Sidomos Ă«shtĂ« e trishtueshme nĂ«se dĂ«shironim diçka si, dhe regjistrat nĂ« tabelĂ« â qindra mijĂ«ra⊠$1 = 4QĂ« tĂ« mos trishtohemi kot, le tĂ« pĂ«rdorim pyetjen rikursive
âDISTINCT pĂ«r tĂ« varfritâ nga PostgreSQL Wiki :

Burimi: habr.com
