Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.
15.4. Lektion: Frågor
När du skriver ett SELECT ...-kommando kallas det vanligen en query - du frågar databasen efter information.
Målet med den här lektionen: Att lära dig hur du skapar frågor som ger användbar information.
Observera
Om du inte gjorde det i den föregående lektionen, lägg till följande people-objekt i tabellen people. Om du får några fel relaterade till begränsningar för främmande nycklar måste du först lägga till objektet ”Main Road” i tabellen streets
insert into people (name,house_no, street_id, phone_no)
values ('Joe Bloggs',3,2,'072 887 23 45');
insert into people (name,house_no, street_id, phone_no)
values ('Jane Smith',55,3,'072 837 33 35');
insert into people (name,house_no, street_id, phone_no)
values ('Roger Jones',33,1,'072 832 31 38');
insert into people (name,house_no, street_id, phone_no)
values ('Sally Norman',83,1,'072 932 31 32');
15.4.1. Beställning av resultat
Låt oss hämta en lista över personer ordnade efter deras husnummer:
select name, house_no from people order by house_no;
Resultat:
name | house_no
--------------+----------
Joe Bloggs | 3
Roger Jones | 33
Jane Smith | 55
Sally Norman | 83
(4 rows)
Du kan sortera resultaten efter värdena i mer än en kolumn:
select name, house_no from people order by name, house_no;
Resultat:
name | house_no
--------------+----------
Jane Smith | 55
Joe Bloggs | 3
Roger Jones | 33
Sally Norman | 83
(4 rows)
15.4.2. FIltrering
Ofta vill du inte se varenda post i databasen - särskilt inte om det finns tusentals poster och du bara är intresserad av att se en eller två.
Här är ett exempel på ett numeriskt filter som bara returnerar objekt vars house_no
är mindre än 50:
select name, house_no from people where house_no < 50;
name | house_no
-------------+----------
Joe Bloggs | 3
Roger Jones | 33
(2 rows)
Du kan kombinera filter (som definieras med hjälp av klausulen WHERE
) med sortering (som definieras med hjälp av klausulen ORDER BY
):
select name, house_no from people where house_no < 50 order by house_no;
name | house_no
-------------+----------
Joe Bloggs | 3
Roger Jones | 33
(2 rows)
Du kan också filtrera baserat på textdata:
select name, house_no from people where name like '%s%';
name | house_no
-------------+----------
Joe Bloggs | 3
Roger Jones | 33
(2 rows)
Här använde vi klausulen LIKE för att hitta alla namn med en s i sig. Du kommer att märka att den här frågan är skiftlägeskänslig, så Sally Norman har inte returnerats.
Om du vill söka efter en sträng med bokstäver oberoende av skiftlägesskillnad kan du göra en skiftlägeskänslig sökning med hjälp av klausulen ILIKE:
select name, house_no from people where name ilike '%r%';
name | house_no
--------------+----------
Roger Jones | 33
Sally Norman | 83
(2 rows)
Den frågan returnerade alla people-objekt med en r eller R i sitt namn.
15.4.3. Anslutningar
Vad händer om du vill se personens detaljer och gatunamnet istället för ID? För att göra det måste du koppla ihop de två tabellerna i en enda fråga. Låt oss titta på ett exempel:
select people.name, house_no, streets.name
from people,streets
where people.street_id=streets.id;
Observera
Med joins anger du alltid de två tabeller som informationen kommer från, i det här fallet personer och gator. Du måste också ange vilka två nycklar som måste matcha (främmande nyckel och primärnyckel). Om du inte anger det får du en lista med alla möjliga kombinationer av personer och gator, men inget sätt att veta vem som faktiskt bor på vilken gata!
Så här ser den korrekta utmatningen ut:
name | house_no | name
--------------+----------+-------------
Joe Bloggs | 3 | Low Street
Roger Jones | 33 | High street
Sally Norman | 83 | High street
Jane Smith | 55 | Main Road
(4 rows)
Vi kommer att återkomma till joins när vi skapar mer komplexa frågor senare. Kom bara ihåg att de är ett enkelt sätt att kombinera information från två eller flera tabeller.
15.4.4. Välj under
Med hjälp av underval kan du välja objekt från en tabell baserat på data från en annan tabell som är länkad via en främmande nyckelrelation. I vårt fall vill vi hitta personer som bor på en viss gata.
Låt oss först göra några små justeringar av våra data:
insert into streets (name) values('QGIS Road');
insert into streets (name) values('OGR Corner');
insert into streets (name) values('Goodle Square');
update people set street_id = 2 where id=2;
update people set street_id = 3 where id=3;
Låt oss ta en snabb titt på våra data efter dessa ändringar: vi kan återanvända vår fråga från föregående avsnitt:
select people.name, house_no, streets.name
from people,streets
where people.street_id=streets.id;
Resultat:
name | house_no | name
--------------+----------+-------------
Roger Jones | 33 | High street
Sally Norman | 83 | High street
Jane Smith | 55 | Main Road
Joe Bloggs | 3 | Low Street
(4 rows)
Låt oss nu visa dig ett underval på dessa data. Vi vill bara visa personer som bor i street_id
nummer 1:
select people.name
from people, (
select *
from streets
where id=1
) as streets_subset
where people.street_id = streets_subset.id;
Resultat:
name
--------------
Roger Jones
Sally Norman
(2 rows)
Även om detta är ett mycket enkelt exempel och onödigt med våra små datamängder, illustrerar det hur användbara och viktiga underval kan vara när man söker efter stora och komplexa datamängder.
15.4.5. Aggregerade frågor
En av de kraftfulla egenskaperna hos en databas är dess förmåga att sammanfatta data i dess tabeller. Dessa sammanfattningar kallas aggregerade frågor. Här är ett typiskt exempel som talar om för oss hur många personobjekt som finns i vår tabell People:
select count(*) from people;
Resultat:
count
-------
4
(1 row)
Om vi vill att räkningarna ska sammanfattas efter gatunamn kan vi göra detta:
select count(name), street_id
from people
group by street_id;
Resultat:
count | street_id
-------+-----------
2 | 1
1 | 3
1 | 2
(3 rows)
Observera
Eftersom vi inte har använt en ORDER BY-klausul, kanske ordningen på dina resultat inte stämmer överens med vad som visas här.
Prova själv: ★★☆
Sammanfatta personerna efter gatunamn och visa de faktiska gatunamnen i stället för street_ids.
Svar
Här är den korrekta SQL-satsen som du ska använda:
select count(people.name), streets.name
from people, streets
where people.street_id=streets.id
group by streets.name;
Resultat:
count | name
------+-------------
1 | Low Street
2 | High street
1 | Main Road
(3 rows)
Du kommer att märka att vi har prefixerat fältnamn med tabellnamn (t.ex. people.name och streets.name). Detta måste göras när fältnamnet är tvetydigt (dvs. inte unikt för alla tabeller i databasen).
15.4.6. Sammanfattningsvis
Du har sett hur du kan använda frågor för att returnera data i din databas på ett sätt som gör att du kan extrahera användbar information från den.
15.4.7. Vad händer härnäst?
Därefter får du se hur du skapar vyer från de frågor som du har skrivit.