Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 85.11%.
15.4. Lektion: Frågor
When you write a SELECT ... command it is commonly known as a query -
you are interrogating the database for information.
Målet med den här lektionen: Att lära dig hur du skapar frågor som ger användbar information.
Observera
If you did not do so in the previous lesson, add the following people
objects to your people table. If you receive any errors related to
foreign key constraints, you will need to add the ’Main Road’ object to your
streets table first
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)
Here we used the LIKE clause to find all names with an s in them.
You’ll notice that this query is case-sensitive, so the Sally Norman entry
has not been returned.
If you want to search for a string of letters regardless of case, you can do a
case in-sensitive search using the ILIKE clause:
select name, house_no from people where name ilike '%r%';
name | house_no
--------------+----------
Roger Jones | 33
Sally Norman | 83
(2 rows)
That query returned every people object with an r or R in their
name.
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)
Now let’s show you a sub-selection on this data. We want to show only people who
live in street_id number 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
Because we have not used an ORDER BY clause, the order of your
results may not match what is shown here.
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.