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:

  1. double == in selecting application names
  2. ambiguous id in the last 2 lines
  3. 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

id name n_domains
1 Rekentuin 32
2 Taalzee 25
3 Words & Birds 13

Running query Q2

modified_count id name
1297954 59 tafels

Running query Q3

id name name
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

domain_id AVG(num_played)
1 383.2100
2 294.4264
3 201.0501

Running query Q5

domain_id gender AVG(user_domain_ratings.num_played)
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=