Source: Abe Hofman
Introduction
This short SQL assignment allows you to practice your SQL skills. You
will learn how to run SQL directly on the SQL server and by using R. SQL
server:
https://data-visualization.oefenweb.nl/adminer.php?server=127.0.2.1%3A3307
(queries can be executed via the SQL command page)
Online Rstudio environment:
https://data-visualization.oefenweb.nl/rstudio/ For both
environments, login with your username and
password (see comment in the canvas assignment).
Submit your code in a plain .txt file, in a commented .R file or in
RMarkdown (use SQL block for SQL code).
We will post the correct answers after the deadline.
Q1
Write a SQL query that counts how many domains we have for
all applications (see SQL Handout)
SELECT applications.id, applications.name, COUNT(domains.id) AS n_domains
FROM applications
LEFT JOIN domains ON domains.application_id = applications.id
GROUP BY applications.id, applications.name
Q2
To which domain does the item belong that is played most
frequently? (Look in the items table, and you can also
first inspect the SQL server environment)
SELECT items.modified_count, domains.id, domains.name
FROM items
LEFT JOIN domains ON domains.id = items.domain_id
ORDER BY items.modified_count DESC
LIMIT 1
Q3
I try to make the following table using a SQL
statement.
## id name name
## 1 41 getallen Rekentuin
## 2 44 1-2-3'tje Rekentuin
## 3 48 kangoeroe Rekentuin
## 4 50 knowledgequiz Rekentuin
## 5 59 tafels Rekentuin
## 6 60 verhaaltjes Rekentuin
## 7 61 meten Rekentuin
## 8 64 vorm en kleur Rekentuin
## 9 65 figuur en plaats Rekentuin
## 10 67 splitsen Rekentuin
Can you fix the three errors in my code:
SELECT domains.id, domains.name, applications.name
FROM domains
LIMIT 10
LEFT JOIN applications ON applications.id = domains.application_id
WHERE applications.name == 'rekentuin'
AND id > 40
ORDER BY id
Errors:
- double
== in selecting application names
- ambiguous
id in the last 2 lines
- limiting too early
SELECT domains.id, domains.name, applications.name
FROM domains
LEFT JOIN applications ON applications.id = domains.application_id
WHERE applications.name = 'rekentuin'
AND domains.id > 40
ORDER BY domains.id
LIMIT 10
Q4
Use the user_domain_ratings. Investigate how many items users
made on average in domains 1, 2 and 3. Your outcome should be as
follows:
## domain_id AVG(num_played)
## 1 1 383.2100
## 2 2 294.4264
## 3 3 201.0501
SELECT domain_id, AVG(num_played)
FROM user_domain_ratings
WHERE domain_id IN (1, 2, 3)
GROUP BY domain_id
ORDER BY domain_id
Q5
Now extend your result of Q4 (join the user_domain_ratings
and users tables). What are these averages for both males and
females?
SELECT user_domain_ratings.domain_id, users.gender, AVG(user_domain_ratings.num_played)
FROM users
INNER JOIN user_domain_ratings ON user_domain_ratings.new_user_id = users.id
WHERE user_domain_ratings.domain_id IN (1, 2, 3)
AND users.gender IS NOT NULL
GROUP BY user_domain_ratings.domain_id, users.gender
ORDER BY user_domain_ratings.domain_id, users.gender
Q6
on_server <- file.exists(path.expand("~/.my.cnf"))
on_server
#> [1] TRUE
if (!requireNamespace("devtools", quietly = TRUE)) {
install.packages("devtools")
}
if (!requireNamespace("oefenwebDatabase", quietly = TRUE)) {
devtools::install_git("https://github.com/Oefenweb/r-database.git")
}
con <- oefenwebDatabase::connect()
It is also possible to run SQL queries using the Rstudio server.
To do that, log in to the Online Rstudio environment and make
connection with the server. Therefore you need to install devtools so
that you can install the oefenwebDatabase package.
Now we can make a connection:
From this point on, you can use the database connection to retrieve
data from the SQL server.
Reproduce your answer from Q4 an Q5 using R.
queries <- list(
"Q1" = q1,
"Q2" = q2,
"Q3" = q3,
"Q4" = q4,
"Q5" = q5
)
for (name in names(queries)) {
cat("**Running query", name, "**\n\n")
result <- DBI::dbGetQuery(con, queries[[name]])
print(knitr::kable(result))
}
Running query Q1
| 1 |
Rekentuin |
32 |
| 2 |
Taalzee |
25 |
| 3 |
Words & Birds |
13 |
Running query Q2
Running query Q3
| 41 |
getallen |
Rekentuin |
| 44 |
1-2-3’tje |
Rekentuin |
| 48 |
kangoeroe |
Rekentuin |
| 50 |
knowledgequiz |
Rekentuin |
| 59 |
tafels |
Rekentuin |
| 60 |
verhaaltjes |
Rekentuin |
| 61 |
meten |
Rekentuin |
| 64 |
vorm en kleur |
Rekentuin |
| 65 |
figuur en plaats |
Rekentuin |
| 67 |
splitsen |
Rekentuin |
Running query Q4
| 1 |
383.2100 |
| 2 |
294.4264 |
| 3 |
201.0501 |
Running query Q5
| 1 |
f |
507.4065 |
| 1 |
m |
528.4807 |
| 2 |
f |
381.0789 |
| 2 |
m |
394.3550 |
| 3 |
f |
258.0786 |
| 3 |
m |
284.1035 |
oefenwebDatabase::close_connections()
#> [[1]]
#> [1] TRUE
LS0tCnRpdGxlOiAiU1FMIEFzc2lnbm1lbnQiCnN1YnRpdGxlOiAiQkRTIFRvb2xib3giCmF1dGhvcjogIk1hcmlpYSBTdGVlZ2hzLVR1cmNoaW5hIgpkYXRlOiAiMjAyNi0wOS0xMyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogY29zbW8KICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIGRmX3ByaW50OiBwYWdlZAogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgICAgICAgICAgIyB0aGUgaGFuZC1pbiBoYXMgdG8gc2hvdyB0aGUgY29kZQogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgZXJyb3IgPSBUUlVFLAogIGNvbW1lbnQgPSAiIz4iLAogIGNvbGxhcHNlID0gVFJVRSwKICBmaWcuc2hvdyA9ICJob2xkIiwKICBmaWcuYWxpZ24gPSAiZGVmYXVsdCIsCiAgZmlnLndpZHRoID0gNCwKICBmaWcuaGVpZ2h0ID0gNCwKICBkcGkgPSAxNTAKKQoKb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpCnNldC5zZWVkKDQyKQpgYGAKCj4gU291cmNlOiBBYmUgSG9mbWFuCgojIyBJbnRyb2R1Y3Rpb24KClRoaXMgc2hvcnQgU1FMIGFzc2lnbm1lbnQgYWxsb3dzIHlvdSB0byBwcmFjdGljZSB5b3VyIFNRTCBza2lsbHMuIFlvdSB3aWxsIGxlYXJuIGhvdyB0byBydW4gU1FMIGRpcmVjdGx5IG9uIHRoZSBTUUwgc2VydmVyIGFuZCBieSB1c2luZyBSLiBTUUwgc2VydmVyOgoKaHR0cHM6Ly9kYXRhLXZpc3VhbGl6YXRpb24ub2VmZW53ZWIubmwvYWRtaW5lci5waHA/c2VydmVyPTEyNy4wLjIuMSUzQTMzMDcgKHF1ZXJpZXMgY2FuIGJlIGV4ZWN1dGVkIHZpYSB0aGUgYFNRTCBjb21tYW5kYCBwYWdlKQoKT25saW5lIFJzdHVkaW8gZW52aXJvbm1lbnQ6CgpodHRwczovL2RhdGEtdmlzdWFsaXphdGlvbi5vZWZlbndlYi5ubC9yc3R1ZGlvLyBGb3IgYm90aCBlbnZpcm9ubWVudHMsIGxvZ2luIHdpdGggeW91ciBgdXNlcm5hbWVgIGFuZCBgcGFzc3dvcmRgIChzZWUgY29tbWVudCBpbiB0aGUgY2FudmFzIGFzc2lnbm1lbnQpLgoKU3VibWl0IHlvdXIgY29kZSBpbiBhIHBsYWluIC50eHQgZmlsZSwgaW4gYSBjb21tZW50ZWQgLlIgZmlsZSBvciBpbiBSTWFya2Rvd24gKHVzZSBTUUwgYmxvY2sgZm9yIFNRTCBjb2RlKS4KCldlIHdpbGwgcG9zdCB0aGUgY29ycmVjdCBhbnN3ZXJzIGFmdGVyIHRoZSBkZWFkbGluZS4KCiMjIFExCgoqKldyaXRlIGEgU1FMIHF1ZXJ5IHRoYXQgY291bnRzIGhvdyBtYW55IGRvbWFpbnMgd2UgaGF2ZSBmb3IgYWxsIGFwcGxpY2F0aW9ucyAoc2VlIFNRTCBIYW5kb3V0KSoqCgpgYGB7ciBxdWVyeS0xLCBpbmNsdWRlPUZBTFNFfQpxMSA8LSB0cmltd3MoIgpTRUxFQ1QgYXBwbGljYXRpb25zLmlkLCBhcHBsaWNhdGlvbnMubmFtZSwgQ09VTlQoZG9tYWlucy5pZCkgQVMgbl9kb21haW5zCkZST00gYXBwbGljYXRpb25zCkxFRlQgSk9JTiBkb21haW5zIE9OIGRvbWFpbnMuYXBwbGljYXRpb25faWQgPSBhcHBsaWNhdGlvbnMuaWQKR1JPVVAgQlkgYXBwbGljYXRpb25zLmlkLCBhcHBsaWNhdGlvbnMubmFtZQoiKQpgYGAKCmBgYHtzcWwgZXgtcTEsIGV2YWw9RkFMU0UsIGNvZGU9cTF9CmBgYAoKIyMgUTIKCioqVG8gd2hpY2ggZG9tYWluIGRvZXMgdGhlIGl0ZW0gYmVsb25nIHRoYXQgaXMgcGxheWVkIG1vc3QgZnJlcXVlbnRseT8gKExvb2sgaW4gdGhlIGBpdGVtc2AgdGFibGUsIGFuZCB5b3UgY2FuIGFsc28gZmlyc3QgaW5zcGVjdCB0aGUgU1FMIHNlcnZlciBlbnZpcm9ubWVudCkqKgoKYGBge3IgcXVlcnktMiwgaW5jbHVkZT1GQUxTRX0KcTIgPC0gdHJpbXdzKCIKU0VMRUNUIGl0ZW1zLm1vZGlmaWVkX2NvdW50LCBkb21haW5zLmlkLCBkb21haW5zLm5hbWUKRlJPTSBpdGVtcwpMRUZUIEpPSU4gZG9tYWlucyBPTiBkb21haW5zLmlkID0gaXRlbXMuZG9tYWluX2lkCk9SREVSIEJZIGl0ZW1zLm1vZGlmaWVkX2NvdW50IERFU0MgCkxJTUlUIDEKIikKYGBgCgpgYGB7c3FsIGV4LXEyLCBldmFsPUZBTFNFLCBjb2RlPXEyfQpgYGAKCiMjIFEzCgoqKkkgdHJ5IHRvIG1ha2UgdGhlIGZvbGxvd2luZyB0YWJsZSB1c2luZyBhIFNRTCBzdGF0ZW1lbnQuKioKCmBgYAojIyAgICBpZCAgICAgICAgICAgICBuYW1lICAgICAgbmFtZQojIyAxICA0MSAgICAgICAgIGdldGFsbGVuIFJla2VudHVpbgojIyAyICA0NCAgICAgICAgMS0yLTMndGplIFJla2VudHVpbgojIyAzICA0OCAgICAgICAga2FuZ29lcm9lIFJla2VudHVpbgojIyA0ICA1MCAgICBrbm93bGVkZ2VxdWl6IFJla2VudHVpbgojIyA1ICA1OSAgICAgICAgICAgdGFmZWxzIFJla2VudHVpbgojIyA2ICA2MCAgICAgIHZlcmhhYWx0amVzIFJla2VudHVpbgojIyA3ICA2MSAgICAgICAgICAgIG1ldGVuIFJla2VudHVpbgojIyA4ICA2NCAgICB2b3JtIGVuIGtsZXVyIFJla2VudHVpbgojIyA5ICA2NSBmaWd1dXIgZW4gcGxhYXRzIFJla2VudHVpbgojIyAxMCA2NyAgICAgICAgIHNwbGl0c2VuIFJla2VudHVpbgpgYGAKCioqQ2FuIHlvdSBmaXggdGhlIHRocmVlIGVycm9ycyBpbiBteSBjb2RlOioqCgpgYGB7c3FsIGV4LXEzLWdpdmVuLCBldmFsPUZBTFNFfQpTRUxFQ1QgZG9tYWlucy5pZCwgZG9tYWlucy5uYW1lLCBhcHBsaWNhdGlvbnMubmFtZQpGUk9NIGRvbWFpbnMKTElNSVQgMTAKTEVGVCBKT0lOIGFwcGxpY2F0aW9ucyBPTiBhcHBsaWNhdGlvbnMuaWQgPSBkb21haW5zLmFwcGxpY2F0aW9uX2lkCldIRVJFIGFwcGxpY2F0aW9ucy5uYW1lID09ICdyZWtlbnR1aW4nCkFORCBpZCA+IDQwCk9SREVSIEJZIGlkCmBgYAoKRXJyb3JzOgoKMS4gZG91YmxlIGA9PWAgaW4gc2VsZWN0aW5nIGFwcGxpY2F0aW9uIG5hbWVzCjIuIGFtYmlndW91cyBgaWRgIGluIHRoZSBsYXN0IDIgbGluZXMKMy4gbGltaXRpbmcgdG9vIGVhcmx5CgpgYGB7ciBxdWVyeS0zLCBpbmNsdWRlPUZBTFNFfQpxMyA8LSB0cmltd3MoIgpTRUxFQ1QgZG9tYWlucy5pZCwgZG9tYWlucy5uYW1lLCBhcHBsaWNhdGlvbnMubmFtZQpGUk9NIGRvbWFpbnMKTEVGVCBKT0lOIGFwcGxpY2F0aW9ucyBPTiBhcHBsaWNhdGlvbnMuaWQgPSBkb21haW5zLmFwcGxpY2F0aW9uX2lkCldIRVJFIGFwcGxpY2F0aW9ucy5uYW1lID0gJ3Jla2VudHVpbicKQU5EIGRvbWFpbnMuaWQgPiA0MApPUkRFUiBCWSBkb21haW5zLmlkCkxJTUlUIDEwCiIpCmBgYAoKYGBge3NxbCBleC1xMywgZXZhbD1GQUxTRSwgY29kZT1xM30KYGBgCgojIyBRNAoKKipVc2UgdGhlIHVzZXJfZG9tYWluX3JhdGluZ3MuIEludmVzdGlnYXRlIGhvdyBtYW55IGl0ZW1zIHVzZXJzIG1hZGUgb24gYXZlcmFnZSBpbiBkb21haW5zIDEsIDIgYW5kIDMuIFlvdXIgb3V0Y29tZSBzaG91bGQgYmUgYXMgZm9sbG93czoqKgoKYGBgCiMjICAgZG9tYWluX2lkIEFWRyhudW1fcGxheWVkKQojIyAxICAgICAgICAgMSAgICAgICAgMzgzLjIxMDAKIyMgMiAgICAgICAgIDIgICAgICAgIDI5NC40MjY0CiMjIDMgICAgICAgICAzICAgICAgICAyMDEuMDUwMQpgYGAKCmBgYHtyIHF1ZXJ5LTQsIGluY2x1ZGU9RkFMU0V9CnE0IDwtIHRyaW13cygiClNFTEVDVCBkb21haW5faWQsIEFWRyhudW1fcGxheWVkKQpGUk9NIHVzZXJfZG9tYWluX3JhdGluZ3MKV0hFUkUgZG9tYWluX2lkIElOICgxLCAyLCAzKQpHUk9VUCBCWSBkb21haW5faWQKT1JERVIgQlkgZG9tYWluX2lkCiIpCmBgYAoKYGBge3NxbCBleC1xNCwgZXZhbD1GQUxTRSwgY29kZT1xNH0KYGBgCgojIyBRNQoKKipOb3cgZXh0ZW5kIHlvdXIgcmVzdWx0IG9mIFE0IChqb2luIHRoZSB1c2VyX2RvbWFpbl9yYXRpbmdzIGFuZCB1c2VycyB0YWJsZXMpLiBXaGF0IGFyZSB0aGVzZSBhdmVyYWdlcyBmb3IgYm90aCBtYWxlcyBhbmQgZmVtYWxlcz8qKgoKYGBge3IgcXVlcnktNSwgaW5jbHVkZT1GQUxTRX0KcTUgPC0gdHJpbXdzKCIKU0VMRUNUIHVzZXJfZG9tYWluX3JhdGluZ3MuZG9tYWluX2lkLCB1c2Vycy5nZW5kZXIsIEFWRyh1c2VyX2RvbWFpbl9yYXRpbmdzLm51bV9wbGF5ZWQpCkZST00gdXNlcnMKSU5ORVIgSk9JTiB1c2VyX2RvbWFpbl9yYXRpbmdzIE9OIHVzZXJfZG9tYWluX3JhdGluZ3MubmV3X3VzZXJfaWQgPSB1c2Vycy5pZApXSEVSRSB1c2VyX2RvbWFpbl9yYXRpbmdzLmRvbWFpbl9pZCBJTiAoMSwgMiwgMykKQU5EIHVzZXJzLmdlbmRlciBJUyBOT1QgTlVMTApHUk9VUCBCWSB1c2VyX2RvbWFpbl9yYXRpbmdzLmRvbWFpbl9pZCwgdXNlcnMuZ2VuZGVyCk9SREVSIEJZIHVzZXJfZG9tYWluX3JhdGluZ3MuZG9tYWluX2lkLCB1c2Vycy5nZW5kZXIKIikKYGBgCgpgYGB7c3FsIGV4LXE1LCBldmFsPUZBTFNFLCBjb2RlPXE1fQpgYGAKCiMjIFE2CgpgYGB7ciBkZXRlY3QtZW52fQpvbl9zZXJ2ZXIgPC0gZmlsZS5leGlzdHMocGF0aC5leHBhbmQoIn4vLm15LmNuZiIpKQpvbl9zZXJ2ZXIKYGBgCgpgYGB7ciBleC1xNi1naXZlbiwgZXZhbCA9IG9uX3NlcnZlcn0KaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJkZXZ0b29scyIsIHF1aWV0bHkgPSBUUlVFKSkgewogIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoIm9lZmVud2ViRGF0YWJhc2UiLCBxdWlldGx5ID0gVFJVRSkpIHsKICBkZXZ0b29sczo6aW5zdGFsbF9naXQoImh0dHBzOi8vZ2l0aHViLmNvbS9PZWZlbndlYi9yLWRhdGFiYXNlLmdpdCIpCn0KYGBgCgpgYGB7ciBleC1xNi1jb25uZWN0LCBldmFsID0gb25fc2VydmVyfQpjb24gPC0gb2VmZW53ZWJEYXRhYmFzZTo6Y29ubmVjdCgpCmBgYAoKSXQgaXMgYWxzbyBwb3NzaWJsZSB0byBydW4gU1FMIHF1ZXJpZXMgdXNpbmcgdGhlIFJzdHVkaW8gc2VydmVyLgoKVG8gZG8gdGhhdCwgbG9nIGluIHRvIHRoZSBPbmxpbmUgUnN0dWRpbyBlbnZpcm9ubWVudCBhbmQgbWFrZSBjb25uZWN0aW9uIHdpdGggdGhlIHNlcnZlci4gVGhlcmVmb3JlIHlvdSBuZWVkIHRvIGluc3RhbGwgZGV2dG9vbHMgc28gdGhhdCB5b3UgY2FuIGluc3RhbGwgdGhlIG9lZmVud2ViRGF0YWJhc2UgcGFja2FnZS4KCk5vdyB3ZSBjYW4gbWFrZSBhIGNvbm5lY3Rpb246CgpGcm9tIHRoaXMgcG9pbnQgb24sIHlvdSBjYW4gdXNlIHRoZSBkYXRhYmFzZSBjb25uZWN0aW9uIHRvIHJldHJpZXZlIGRhdGEgZnJvbSB0aGUgU1FMIHNlcnZlci4KCioqUmVwcm9kdWNlIHlvdXIgYW5zd2VyIGZyb20gUTQgYW4gUTUgdXNpbmcgUi4qKgoKYGBge3IgZXgtcTYsIGV2YWwgPSBvbl9zZXJ2ZXIsIHJlc3VsdHMgPSAiYXNpcyJ9CnF1ZXJpZXMgPC0gbGlzdCgKICAiUTEiID0gcTEsCiAgIlEyIiA9IHEyLAogICJRMyIgPSBxMywKICAiUTQiID0gcTQsIAogICJRNSIgPSBxNQopCgpmb3IgKG5hbWUgaW4gbmFtZXMocXVlcmllcykpIHsKICBjYXQoIioqUnVubmluZyBxdWVyeSIsIG5hbWUsICIqKlxuXG4iKQogIHJlc3VsdCA8LSBEQkk6OmRiR2V0UXVlcnkoY29uLCBxdWVyaWVzW1tuYW1lXV0pCiAgcHJpbnQoa25pdHI6OmthYmxlKHJlc3VsdCkpCn0KYGBgCgpgYGB7ciBleC1xNi1kaXNjb25uZWN0LCBldmFsID0gb25fc2VydmVyfQpvZWZlbndlYkRhdGFiYXNlOjpjbG9zZV9jb25uZWN0aW9ucygpCmBgYAo=