4. Mer om SQL-språket
Datatyper och uttryck
I SQL-språket används datatyper och uttryck på samma sätt som i programmering. I tidigare kapitel har vi redan gått igenom en hel del exempel på olika SQL-kommandon. Låt oss nu studera SQL-språket ännu mer ingående.
Varje databashanterare implementerar datatyper och uttryck på sitt eget sätt, och det finns en hel del små skillnader i hur olika databashanterare fungerar. Det är därför klokt att kontrollera detaljerna i dokumentationen för den databashanterare som används.
Datatyper
När man definierar en tabell anges en datatyp för varje kolumn:
CREATE TABLE Movies (
id INTEGER PRIMARY KEY,
name TEXT,
release_year INTEGER
);
Här är kolumnen name av typen TEXT (sträng) och kolumnen release_year av typen INTEGER (heltal). Dessa är de vanligaste datatyperna som finns tillgängliga under dessa namn i många databaser. Andra vanliga datatyper är till exempel TIMESTAMP (tidpunkt), REAL (flyttal) och BLOB (rådata).
TEXT vs. VARCHAR
Ett vanligt sätt att lagra en sträng i SQL är att använda typen VARCHAR där man anger den maximala längden på strängen inom parentes. Exempelvis betyder typen VARCHAR(10) att strängen kan innehålla högst 10 tecken.
Det här påminner om programmering från förr i tiden, då en sträng kunde representeras som en teckenarray med fast längd. Datatypen TEXT är smidigare att använda eftersom man inte behöver ange någon maximal längd på strängen.
Datatyper i SQLite
En ovanlig egenskap hos SQLite är att datatypen som anges vid tabellens definition bara är en riktlinje för vilken datatyp kolumnen bör ha. Vi kan dock bortse från denna riktlinje och till exempel lagra en sträng i en kolumn som egentligen är avsedd för heltal:
INSERT INTO Movies (name, release_year) VALUES ('Snövit', 'abc');
Dessutom kan datatypens namn vara vilken som helst sträng, även om SQLite inte har en sådan datatyp. Vi kan således till exempel definiera en kolumn där vi avser att lagra en tidpunkt:
CREATE TABLE Bookings (
id INTEGER PRIMARY KEY,
start_time TIMESTAMP,
end_time TIMESTAMP,
description TEXT
);
I SQLite finns inte TIMESTAMP som datatyp utan tidpunkter hanteras som strängar. Här anger dock kolumnens datatyp vilken typ av värde som är avsedd att lagras i kolumnen.
Uttryck
Ett uttryck är en del av ett SQL-kommando som har ett visst värde. Exempelvis i frågan
SELECT price FROM Products WHERE name = 'rädisa';
finns det fyra uttryck: price, name, 'rädisa' och name = 'rädisa'. Uttrycken price och name får sina värden från kolumnen i raden, uttrycket 'rädisa' är en strängkonstant och uttrycket name = 'rädisa' är booleskt.
Vi kan göra uttrycken mer komplexa på samma sätt som i programmering. Till exempel frågan
SELECT price * 5 FROM Products;
ger som svar varje produkts pris multiplicerat med fem. Frågan
SELECT name FROM Products WHERE price % 2 = 0;
hämtar de produkter vars pris är jämnt.
Ett bra sätt att testa SQL-uttryck är att interagera med databasen genom att ställa frågor som inte hämtar data från någon tabell utan enbart beräknar värdet av ett visst uttryck. Nedan följer ett exempel:
sqlite> SELECT 2 * (1 + 3);
8
sqlite> SELECT 'te' || 'st';
test
sqlite> SELECT 3 < 5;
1
Den första frågan beräknar värdet på uttrycket 2 * (1 + 3). Den andra frågan kombinerar strängarna 'te' och 'st' med hjälp av ||. Den tredje frågan bestämmer värdet av villkorsuttrycket 3 < 5. Här ser man att i SQLite representerar ett heltal ett booleskt (logiskt) värde där 1 är sant och 0 är falskt.
Mycket som rör SQL-uttryck är bekant från programmering:
- räkneoperationer:
+,-,*,/,% - jämförelser:
=,<>,<,<=,>,>= - kombinering av villkor:
AND,OR,NOT
Utöver dessa finns det i SQL även några mer speciella funktioner som kan vara nyttiga att känna till. Några av dessa är bland annat:
BETWEEN
Uttrycket x BETWEEN a AND b är sant om x är minst a och högst b. Exempelvis frågan
SELECT * FROM Products WHERE price BETWEEN 4 AND 6;
hämtar de produkter vars pris är minst 4 och högst 6. Samma fråga kan också skrivas på följande sätt:
SELECT * FROM Products WHERE price >= 4 AND price <= 6;
CASE
Strukturen CASE möjliggör skapandet av villkorsuttryck. CASE kan innehålla en eller flera WHEN-delar och en valfri ELSE-del. Exempelvis frågan
SELECT
name,
CASE WHEN price > 5 THEN 'dyr' ELSE 'billig' END
FROM
Products;
hämtar varje produktnamn och information om produkten är dyr eller billig. Här räknas en produkt som dyr om priset är över 5. Om priset är 5 eller under 5 så räknas produkten som billig.
IN
Uttrycket x IN (...) är sant om x motsvarar något av de angivna värdena. Till exempel frågan
SELECT
SUM(price)
FROM
Products
WHERE
name IN ('kålrot', 'rova', 'selleri');
hämtar det totala priset för kålroten, rovan och sellerin.
LIKE
Uttrycket s LIKE p är sant om strängen s överensstämmer med beskrivningen p. I beskrivningen kan man använda specialtecken. Tecknet _ betyder vilket enstaka tecken som helst och tecknet % betyder ett godtyckligt antal tecken. Till exempel frågan
SELECT * FROM Products WHERE name LIKE '%rot%';
hämtar de produkter i vilkas namn strängen “rot” förekommer (morot och kålrot)
Funktioner
Uttrycken kan innehålla funktioner på samma sätt som i programmering. Nedan är några exempel på funktioner i SQLite:
ABS(x): absolutbeloppet avxLENGTH(s): längden på strängensLOWER(s): strängensskriven med små bokstäverMAX(x, y): det större av talenxochyMIN(x, y): det mindre av talenxochyRANDOM(): ett slumpmässigt talROUND(x, d): taletxavrundat medddesimalers noggrannhetSUBSTR(s, a, b):bantal tecken från strängensmed start från positionaUPPER(s): strängensskriven med stora bokstäver
Följande fråga hämtar de produkter vars namn innehåller sex bokstäver (rädisa och kålrot)
SELECT * FROM Products WHERE LENGTH(name) = 6;
Följande fråga grupperar produkterna efter första bokstaven och visar antalet produkter som börjar med respektive bokstav.
SELECT
SUBSTR(name, 1, 1), COUNT(*)
FROM
Products
GROUP BY
SUBSTR(name, 1, 1);
Följande fråga returnerar raderna i slumpmässig ordning eftersom ordningen inte baseras på innehållet i någon kolumn utan på ett slumpmässigt värde.
SELECT * FROM Products ORDER BY RANDOM();
ORDER BY och uttryck
Man kunde anta att i frågan
SELECT * FROM Products ORDER BY 1;
sorteras raderna enligt uttrycket 1, och eftersom uttryckets värde är 1 på varje rad så innebär detta ingen särskild ordning. Detta är dock inte fallet. 1 sorterar nämligen raderna efter den första kolumnen, 2 efter den andra kolumnen och så vidare. Detta är alltså ett alternativt sätt att ange vilken kolumn sorteringen ska baseras på.
Om uttrycket i ORDER BY-delen däremot är något annat än ett enstaka tal (till exempel RANDOM()), ordnas raderna enligt uttrycket i fråga.
NULL-värden
NULL är ett speciellt värde som anger att en kolumn i tabellen saknar information eller att en del av en fråga inte returnerade något värde. NULL kan vara praktiskt i vissa situationer, men kan också orsaka utmaningar.
Som standard visar SQLite-tolken värdet NULL som tomt:
sqlite> SELECT NULL;
NULL-värdet kan visas med tolken genom kommandot .nullvalue:
sqlite> .nullvalue NULL
sqlite> SELECT NULL;
NULL
Observera att NULL inte är talet 0. Om NULL ingår i en beräkning blir hela resultatet NULL.
sqlite> SELECT 5 + NULL;
NULL
sqlite> SELECT 2 * NULL + 1;
NULL
En vanlig jämförelse ger inte något svar om NULL ingår i jämförelsen:
sqlite> SELECT 5 = NULL;
NULL
sqlite> SELECT 5 <> NULL;
NULL
Svaret kan vara en aning oväntat. För uttrycken a och b gäller vanligtvis antingen a = b eller a <> b. Vi kan kontrollera om ett uttryck har värdet NULL med syntaxen IS NULL:
sqlite> SELECT 5 IS NULL;
0
sqlite> SELECT NULL IS NULL;
1
Information saknas i kolumnen
Ett av syftena med värdet NULL är att ange att en kolumn saknar information. Till exempel i följande tabell Movies saknas utgivningsåret för filmen Dumbo:
id name release_year
-- --------- ------------
1 Snövit 1937
2 Fantasia 1940
3 Pinocchio 1940
4 Dumbo NULL
5 Bambi 1942
Om vi först hämtar filmer från år 1940 och sedan alla filmer från andra år, får vi följande resultat:
SELECT * FROM Movies WHERE release_year = 1940;
id name release_year
-- --------- ------------
2 Fantasia 1940
3 Pinocchio 1940
SELECT * FROM Movies WHERE release_year <> 1940;
id name release_year
-- ------- ------------
1 Snövit 1937
5 Bambi 1942
Observera att eftersom filmen Dumbo saknar utgivningsår så finns den inte med i något av svaren. Vi kan hämta de filmer som saknar utgivningsår med följande fråga:
SELECT * FROM Movies WHERE release_year IS NULL;
id name release_year
-- ----- ------------
4 Dumbo NULL
Ett NULL-värde i en aggregeringsfunktion
När en aggregeringsfunktion innehåller ett uttryck (till exempel ett kolumnvärde) räknas raden inte med om uttryckets värde är NULL. Som exempel kan vi titta på följande tabell Employees:
id name company salary
-- -------- ------- ------
1 Anna Google 8000
2 Liisa Google 7500
3 Kaaleppi Amazon NULL
4 Uolevi Amazon NULL
5 Maija Google 9500
I tabellen har Googles anställda ett angivet lönebelopp medan Amazons anställda inte har det. Aggregeringsfunktionen COUNT(salary) räknar endast med de rader där lönen är angiven:
SELECT COUNT(salary) FROM Employees WHERE company = 'Google';
COUNT(salary)
-------------
3
SELECT COUNT(salary) FROM Employees WHERE company = 'Amazon';
COUNT(salary)
-------------
0
När vi beräknar summan av lönerna med aggregeringsfunktionen SUM(salary) får vi följande resultat:
SELECT SUM(salary) FROM Employees WHERE company = 'Google';
SUM(salary)
-----------
25000
SELECT SUM(salary) FROM Employees WHERE company = 'Amazon';
SUM(salary)
-----------
NULL
Svaret kan vara en aning oväntat eftersom man skulle kunna förvänta sig att en tom summa blir 0 istället för NULL.
Ändra NULL-värdet
Funktionen IFNULL(a, b) returnerar värdet a om a inte är NULL. Om a är NULL så returneras istället värdet b:
sqlite> SELECT IFNULL(5, 0);
IFNULL(5, 0)
------------
5
sqlite> SELECT IFNULL(NULL, 0);
IFNULL(NULL, 0)
---------------
0
Ovanstående exempel är ett vanligt sätt att använda IFNULL(a, b) på. Funktionen omvandlar ett eventuellt NULL-värde till noll när den andra parametern (b) i IFNULL(a, b) är 0. Detta är användbart till exempel i LEFT JOIN-frågor tillsammans med SUM-funktionen.
Funktionen IFNULL är inte en standardfunktion i SQL och fungerar därmed inte i alla databashanterare. En standardfunktion i SQL är COALESCE(...), till vilken man ger en lista med värden. Funktionen returnerar det första värdet i listan som inte är NULL, eller NULL om alla värden i listan är NULL. Om funktionen endast har två parametrar fungerar den på samma sätt som IFNULL.
sqlite> SELECT COALESCE(1, 2, 3);
COALESCE(1, 2, 3)
-----------------
1
sqlite> SELECT COALESCE(NULL, 2, 3);
COALESCE(NULL, 2, 3)
--------------------
2
sqlite> SELECT COALESCE(NULL, NULL, 3);
COALESCE(NULL, NULL, 3)
-----------------------
3
sqlite> SELECT COALESCE(NULL, NULL, NULL);
COALESCE(NULL, NULL, NULL)
--------------------------
NULL
Underfrågor
En underfråga är ett uttryck som ingår som en del av ett SQL-kommando och vars värde bestäms av en viss fråga. Vi kan formulera underfrågor på samma sätt som vanliga frågor och använda dem för att göra sökningar som annars vore svåra att genomföra.
Exempel
Låt oss betrakta en situation där databasen innehåller spelares resultat i tabellen Results. Vi antar att tabellen ser ut på följande sätt:
id name score
-- -------- -----
1 Uolevi 120
2 Maija 80
3 Liisa 120
4 Aapeli 45
5 Kaaleppi 115
Vi vill nu ta reda på vilka spelare som har uppnått högsta poäng. Från tabellen ovan ser vi att det är Uolevi och Liisa som upnått högsta poäng. Vi kan utföra följande underfråga:
SELECT
name, score
FROM
Results
WHERE
score = (SELECT MAX(score) FROM Results);
Frågan ger som svar:
name score
------ -----
Uolevi 120
Liisa 120
I frågan ovan är underfrågan SELECT MAX(score) FROM Results. Underfrågan ger det bästa resultatet i tabellen som i det här fallet är 120. Observera att underfrågan måste skrivas inom parenteser för att den inte ska blandas ihop med huvudfrågan.
Skapa en underfråga
En underfråga kan förekomma nästan var som helst i frågan. En underfråga kan, beroende på situation, returnera ett enstaka värde, en lista med värden eller en hel tabell.
En underfråga i en kolumn
I följande fråga skapas med hjälp av en underfråga en tredje kolumn som visar spelarens poängskillnad från rekordresultatet:
SELECT
name, score, (SELECT MAX(score) FROM Results) - score
FROM
Results;
name score (SELECT MAX(score) FROM Results) - score
-------- ----- ----------------------------------------
Uolevi 120 0
Maija 80 40
Liisa 120 0
Aapeli 45 75
Kaaleppi 115 5
Uttrycket som skapar kolumnen i resultattabellen är rätt invecklat. Resultattabellen kan göras tydligare genom att ge kolumnen ett nytt namn.
SELECT
name,
score,
(SELECT MAX(score) FROM Results) - score AS difference
FROM
Results;
name score difference
-------- ----- ----------
Uolevi 120 0
Maija 80 40
Liisa 120 0
Aapeli 45 75
Kaaleppi 115 5
Underfråga som en tabell
I följande fråga skapar underfrågan en tabell med de tre bästa resultaten. Summan av dessa resultat (120 + 120 + 115) beräknas i huvudfrågan.
SELECT
SUM(score)
FROM
(SELECT * FROM Results ORDER BY score DESC LIMIT 3);
SUM(score)
----------
355
Här begränsar LIMIT resultattabellen så att den endast innehåller de tre första raderna.
Observera att vi skulle erhålla fel svar utan underfrågan:
SELECT SUM(score) FROM Results ORDER BY score DESC LIMIT 3;
SUM(score)
----------
480
I denna resultattabell finns endast en rad med summan av alla resultat (480). LIMIT 3 i slutet av frågan påverkar därför inte alls resultatet.
Underfråga som en lista
Följande fråga hämtar spelare vars resultat hör till de tre bästa. Underfrågan returnerar resultatet som en lista för att användas i IN-uttrycket.
SELECT
name
FROM
Results
WHERE
score IN (SELECT score FROM Results ORDER BY score DESC LIMIT 3);
name
----------
Uolevi
Liisa
Kaaleppi
En underfråga som beror på huvudfrågan
Det är också möjligt att skapa en underfråga så att den beror på den rad som behandlas i huvudfrågan. Detta är fallet i följande fråga:
SELECT
name,
score,
(SELECT COUNT(*) FROM Results WHERE score > R.score) AS better_count
FROM
Results R;
Denna fråga räknar för varje spelare hur många spelares resultat som är bättre än spelarens eget resultat. Till exempel är svaret 3 för Maija, eftersom resultaten för Uolevi, Liisa och Kaaleppi är bättre. Frågan ger som svar följande:
name score better_count
-------- ----- ------------
Uolevi 120 0
Maija 80 3
Liisa 120 0
Aapeli 45 4
Kaaleppi 115 2
Eftersom tabellen Results förekommer i två roller i underfrågan har tabellen i huvudfrågan getts aliaset R. Detta gör det tydligt i underfrågan att man vill räkna de rader vars resultat är bättre än resultatet på den rad som för tillfället behandlas i huvudfrågan.
Nedan är ett till exempel på en underfråga som beror på huvudfrågan:
SELECT
name
FROM
Results R
WHERE
(SELECT COUNT(*) FROM Results WHERE score < R.score) >= 1;
Frågan söker de spelare som har ett bättre resultat än någon annan spelare. Underfrågan räknar hur många spelare som har ett sämre resultat och villkoret i huvudfrågan är att underfrågans resultat är minst ett. Det slutgiltiga svaret på frågan blir:
name
----------
Uolevi
Maija
Liisa
Kaaleppi
Frågan ger som svar alla spelare förutom Aapeli som har det sämsta resultatet.
I SQL finns också nyckelordet EXISTS som anger huruvida en underfråga returnerar åtminstone en rad. Med hjälp av detta nyckelord kan den föregående frågan skrivas tydligare:
SELECT
name
FROM
Results R
WHERE
EXISTS (SELECT * FROM Results WHERE score < R.score);
När ska man använda underfrågor?
Rätt ofta är en underfråga ett alternativt sätt att ställa en fråga som också kunde ställas på något annat sätt. Till exempel hämtar båda frågorna nedan namnen på de produkter som finns i köpkorgen för kund 1:
SELECT
Products.name
FROM
Products, Purchases
WHERE
Products.id = Purchases.product_id AND Purchases.customer_id = 1;
SELECT
name
FROM
Products
WHERE
id IN (SELECT product_id FROM Purchases WHERE customer_id = 1);
Den första frågan är en typisk fråga som använder två tabeller medan den andra frågan väljer ut produkterna med hjälp av en underfråga. Vilken av dessa två frågor är bättre?
Den första frågan är bättre eftersom detta är det avsedda sättet att hämta information ur tabeller i SQL med hjälp av referenser. Den andra frågan fungerar visserligen, men följer inte standardpraxis och databashanteraren kan nödvändigtvis inte heller utföra den lika effektivt som den första frågan.
En underfråga bör endast användas när det verkligen behövs. Om frågan enkelt kan göras med en fråga som involverar flera tabeller är det vanligtvis en bättre lösning.
Fler tekniker
Detta avsnitt innehåller fler exempel på möjligheter i SQL. Dessa tekniker är användbara för att lösa vissa av de mer avancerade uppgifterna i SQL Trainer.
Kumulativ summa
En användbar färdighet i SQL är att kunna beräkna en kumulativ summa, det vill säga summan av kolumnvärden fram till varje rad. Låt oss titta på följande exempel med tabellen Items:
id value
-- -----
1 200
2 100
3 400
4 100
Vi kan beräkna den kumulativa summan med en fråga som involverar två tabeller på följande sätt:
SELECT
A.id, SUM(B.value)
FROM
Items A, Items B
WHERE
B.id <= A.id
GROUP BY
A.id;
id SUM(B.value)
-- ------------
1 200
2 300
3 700
4 800
Idén är här att summan beräknas för en rad i tabellen A och från tabell B hämtas alla rader vars id är mindre än eller lika med radens id i tabell A. De önskade summorna kan sedan beräknas med SUM-funktionen efter grupperingen.
En liknande teknik kan användas i andra situationer när vi vill beräkna ett resultat som på något sätt beror på alla “mindre” rader i tabellen.
Nästlade frågor
Låt oss betrakta en situation där vi vill ta reda på det största antalet filmer som har släppts under samma år. Till exempel i följande tabell Movies är det önskade resultatet 2 eftersom två filmer släpptes år 1940.
id name release_year
-- --------- ------------
1 Snövit 1937
2 Fantasia 1940
3 Pinocchio 1940
4 Dumbo 1941
5 Bambi 1942
Detta kan verka lite knepigt eftersom vi skulle behöva göra nästlade frågor med COUNT som räknar hur många filmer som släppts under samma år och MAX som hämtar det största värdet. SQL tillåter dock inte en fråga i stil med SELECT MAX(COUNT(release_year)).
Vi kan här utgå från en fråga som grupperar filmerna efter år och hämtar antalet filmer i varje grupp:
SELECT COUNT(*) FROM Movies GROUP BY release_year;
COUNT(*)
--------
1
2
1
1
Nu ska vi ännu hämta det största värdet, vilket kan göras med en underfråga. Det är här praktiskt att forma frågan så att underfrågans resultat är i FROM-delen i huvudfrågan. Underfrågan skapar då en tabell som huvudfrågan sedan hämtar information ifrån:
SELECT MAX(year_count) FROM (
SELECT COUNT(*) year_count FROM Movies GROUP BY release_year
);
MAX(year_count)
---------------
2
Kan uppgiften lösas utan en underfråga? Ja. Vi kan nämligen sortera resultaten från störst till minst och välja den första raden i resultattabellen:
SELECT COUNT(*) AS year_count FROM Movies GROUP BY release_year
ORDER BY year_count DESC LIMIT 1;
year_count
----------
2
Placeringar
Låt oss titta på tabellen Results som innehåller spelare och deras resultat:
id name score
-- -------- -----
1 Aapeli 45
2 Kaaleppi 115
3 Liisa 120
4 Maija 80
5 Uolevi 120
Målet är att hämta raderna i resultatordning från störst till minst och dessutom ange varje rads placering. Ett sätt att göra detta är att skapa en underfråga som räknar hur många rader som har ett bättre resultat, varpå placeringen blir ett högre än underfrågans resultat:
SELECT
(SELECT COUNT(*) FROM Results WHERE score > R.score) + 1 AS place,
name, score
FROM
Results R
ORDER BY
score DESC, name;
place name score
----- -------- -----
1 Liisa 120
1 Uolevi 120
3 Kaaleppi 115
4 Maija 80
5 Aapeli 45
Enligt samma princip kan placeringar beräknas så att varje spelare får en unik plats och vid lika resultat avgör alfabetisk ordning placeringen:
SELECT
(SELECT COUNT(*) FROM Results WHERE score > R.score OR
(score = R.score AND name < R.name)) + 1 AS place,
name, score
FROM
Results R
ORDER BY
score DESC, name;
place name score
----- -------- -----
1 Liisa 120
2 Uolevi 120
3 Kaaleppi 115
4 Maija 80
5 Aapeli 45
Ett alternativt sätt att beräkna placeringar är med en fönsterfunktion, förutsatt att databashanteraren som används tillåter det. Till exempel kan man i nyare versioner av SQLite använda fönsterfunktionen RANK för att beräkna motsvarande placeringar som i de tidigare exemplen.
SELECT
RANK() OVER (ORDER BY score DESC) place, name, score
FROM
Results
ORDER BY
place, name;
place name score
----- -------- -----
1 Liisa 120
1 Uolevi 120
3 Kaaleppi 115
4 Maija 80
5 Aapeli 45
SELECT
RANK() OVER (ORDER BY score DESC, name) place, name, score
FROM
Results
ORDER BY
place, name;
place name score
----- -------- -----
1 Liisa 120
2 Uolevi 120
3 Kaaleppi 115
4 Maija 80
5 Aapeli 45
Jämförelse av listor
Låt oss betrakta tabellen Lists som består av innehållet i olika listor. Till exempel innehåller lista 1 talen [2, 4, 5], lista 2 talen [3, 5] och lista 3 talen [2, 4, 5]:
id list_id value
-- ------- -----
1 1 2
2 1 4
3 1 5
4 2 3
5 2 5
6 3 2
7 3 4
8 3 5
Följande fråga räknar för varje par av listor hur många gemensamma tal de har:
SELECT
A.list_id, B.list_id, COUNT(*)
FROM
Lists A, Lists B
WHERE
A.value = B.value
GROUP BY
A.list_id, B.list_id;
list_id list_id COUNT(*)
------- ------- --------
1 1 3
1 2 1
1 3 3
2 1 1
2 2 2
2 3 1
3 1 3
3 2 1
3 3 3
Här framgår det att till exempel listorna 1 och 2 har ett gemensamt tal (5) och listorna 1 och 3 har tre gemensamma tal (2, 4, 5). En sådan här fråga kan man bygga vidare på och till exempel jämföra om två listor har exakt samma innehåll. Detta är fallet när listorna har lika många tal och antalet gemensamma tal är lika stort som antalet tal i varje enskild lista.