Vous êtes sur la page 1sur 78

Ecole doctorale 227

Sciences de la Nature et de l’Homme

Module
R : APPLICATIONS

Utiliser une base de données relationnelle sous R


Initiation au langage SQL

Raymond Baudoin
Conservatoire botanique national du Bassin parisien
Département EGB
baudoin@mnhn.fr

23 avril 2012
24/04/2012
Utiliser SQL pour manipuler des données sous

 Pour un utilisateur de R
Quand on veut filtrer les données à traiter car :
 Elles sont trop nombreuses
 Qu’une partie seulement nous intéresse
Elles sont éclatées dans plusieurs entités (fichiers)

C’est-à-dire chaque fois qu’un read.table() n’est pas totalement satisfaisant *


(*) permet cependant la restriction du nombre de lignes lues

 Pour un utilisateur SQL :


Quand on souhaite y appliquer des fonctions de R

Librairies utilisées :
 pour la connexion aux bases de données : RODBC, RSQLite, RMySQL, RPostgreSQL, ROracle, DBI
 pour accéder aux données des :
 fichiers txt, .csv : sqldf
 fichiers Excel : RODBC, xlsReadWrite, xlsx
 bases de données : RODBC, RSQLite, RMySQL, RPostgreSQL, ROracle, DBI
 pour manipuler des data frames : sqldf
24/04/2012
Fonctions de base pour lire un fichier texte
 Si le fichier est sous la forme d'un tableau statistique :
read.table (file = fich , # Nom complet du fichier ou "clipboard" pour le presse papier (copier/coller)
sep = ";" , # Séparateur des valeurs, \t pour tabulation, \n : pas de séparateur
dec = "," , # Symbole décimal
header = FALSE ,
stringsAsFactors = TRUE , # Conversion des chaines en facteur
row.names = 1, # colonne utilisée comme identifiant des lignes
skip = 1, nrow = 3 ) # Restriction de lecture, ici saut de la première ligne et 3 lignes lues

> read.table (file = "Habitants.csv", sep=";", header=FALSE, nrow=2)


V1 V2 V3 V4 V5 V6 V7 V8 V9
1 pk Nom Prénom numéro voie Code Ville Téléphone Depuis
2 1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 19/10/1920
> read.csv2 (file = "Habitants.csv", row.names=1, nrow=2)
Nom Prénom numéro voie Code Ville Téléphone Depuis
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 19/10/1920
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 01/01/1999
> read.delim2 ("clipboard", row.names=1, nrow=2) Copier/Coller
Nom Prénom numéro voie Code Ville Téléphone Depuis
d'une feuille Excel
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 19/10/1920
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 01/01/1999

 Si le fichier est sous une autre forme :


scan (file = fich , sep=";", what = "character", skip = 1, nlines = 3)
> scan (file = "Habitants.csv", sep=";", what = "character",skip=1, nlines=2)
Read 18 item
[1] "1" "Lecesve" "André" "9" "rue Gay Lussac" "92320" "CHATILLON"
[8] "146542856" "19/10/1920" "2" "Larrouy" "Catherine" "10" "rue Gay Lussac"
[15] "92320" "CHATILLON" "140920841" "01/01/1999"

readLines (con = fich, n = 3)


> readLines (con = "Habitants.csv", n=2)
[1] "pk;Nom;Prénom;numéro;voie;Code;Ville;Téléphone;Depuis"
[2] "1;Lecesve;André;9;rue Gay Lussac;92320;CHATILLON;146542856;19/10/1920
24/04/2012
Fonctions pour lire une feuille MS-Excel R ≥ 2.12.2

au format .xls (Excel 97/2000/XP/2003) ou .xlsx (Excel 2007)


library (xlsx)
read.xlsx ( read.xlsx2 (
file, # nom du fichier file, # nom du fichier
sheetIndex=, # numéro de la feuille sheetIndex=, # numéro de la feuille
sheetName=NULL, # ou son nom sheetName=NULL, # ou son nom
as.data.frame=TRUE, as.data.frame=TRUE,
header=TRUE, header=TRUE,
colClasses=NA, # numeric, integer, logical, character, Date colClasses="character", # ou "numeric"
rowIndex=NULL, startRow=1,
colIndex=NULL, startColumn=1,
keepFormulas=FALSE, noRows=NULL, # nombre de lignes à lire
encoding="unknown", noColumns=NULL)
...)

read.xlsx ("OCCSOL_1000.xlsx", sheetIndex=1, rowIndex=c(1:4,rep(0,135-4)) )


NA. BB BH BI BM BT O TR VB VG VH VM
1 0 0.0787 25.2158 30.0836 15.3149 1.1547 0.0465 6.5254 5.4042 3.2627 5.0906 7.8229
2 1 0.2431 22.2879 27.8258 22.7205 1.1578 0.0000 5.9316 5.1204 2.8737 3.8698 7.9693
3 2 0.1411 16.7779 23.4831 8.4136 0.7781 18.2162 7.0589 6.9271 2.5255 6.9970 8.6815

read.xlsx2 ("OCCSOL_1000.xlsx", sheetIndex=1, colClasses="numeric", startRow=1, noRows=3)


c.0..1. BB BH BI BM BT O TR VB VG VH VM
1 0 0.0787 25.2158 30.0836 15.3149 1.1547 0.0465 6.5254 5.4042 3.2627 5.0906 7.8229
2 1 0.2431 22.2879 27.8258 22.7205 1.1578 0.0000 5.9316 5.1204 2.8737 3.8698 7.9693

read.xlsx ("Habitants.xls", sheetIndex=1, rowIndex=c(1:3,rep(0,14-3)), encoding="UTF-8", stringsAsFactors=FALSE)


Nom Prénom numéro Adresse Code Ville Téléphone Depuis
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 1920-10-19
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 1999-01-01
24/04/2012
Fonctions pour lire une feuille MS-Excel au format .xls

library (xlsReadWrite)
read.xls( file,
colNames = TRUE,
sheet = 1,
colClasses = NA, # numeric, integer, logical, character, isodate, isotime, isodatetime…
stringsAsFactors = TRUE… )

fich <- file.choose() # chemin complet


# [1] "C:\\Mes documents sauvegardés\\Enseignement\\Ecole doctorale mnhn\\Module R compl\\Habitants.xls"
Encoding (fich) # "UTF-8"
fich <- iconv (fich , from = Encoding (fich), to = "latin1") # changement de code page

read.xls (file = fich, sheet = 1, stringsAsFactors = FALSE)


Nom Prénom numéro Adresse Code Ville Téléphone Depuis
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 7598
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 36161
3 Larrouy Eric 10 rue Gay Lussac 92320 CHATILLON 140920841 36161

read.xls (file=fich, sheet=1, stringsAsFactors=FALSE, dateTime="isodatetime")


Nom Prénom numéro Adresse Code Ville Téléphone Depuis
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 1920-10-19
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 1999-01-01
3 Larrouy Eric 10 rue Gay Lussac 92320 CHATILLON 140920841 1999-01-01

Pour enregistrer un data.frame au format MS-Excel :


write.xls(datal, file="localisation.xls", rowNames = TRUE)
24/04/2012
SGBD : Système de gestion de base de données
Ou DBMS (Database management system)

Un ensemble de services pour :

 permettre l'accès aux données de façon simple


 autoriser un accès aux informations à de multiples utilisateurs
 manipuler les données présentes dans la base (insertion, suppression,
modification)

Se décompose en trois sous-systèmes :

 un système de gestion de fichiers pour le stockage des informations sur le


support physique
 un système pour gérer l'ordonnancement des informations
 une interface avec l'utilisateur

24/04/2012
Elément de base : la table
• Les données sont réparties en tables ou entités
• Une table est composée de lignes
• Une ligne est un ensemble fixe de champs (attributs)
Exemple :
Chaque champ a : la table Personnes
un nom id Nom Prénom numéro id_localisation Téléphone Depuis
1 Lecesve André 9 2 146542856 19/10/1920
2 Larrouy Catherine 10 2 140920841 01/01/1999
3 Larrouy Eric 10 2 140920841 01/01/1999
6 Meyer Michel 15 3 05/06/1960
8 Auquier Anne 21 3 157750048 05/09/2005
9 Auquier Anne 21 3 636699001 05/09/2005
10 Auquier Bernard 21 3 146428564 05/09/2005

• un type INTEGER CHARACTER INTEGER DECIMAL DATE

Propriétés d’une table : Avec ces propriétés,


• pas de nom de colonne dupliqué
une table :
• ordre des lignes sans signification
 un fichier
• ordre des colonnes (champs) sans signification
 une feuille xls
• chaque champ permet la sélection de lignes 24/04/2012
Les types de champs 1/2
Les types normalisés SQL 2
Type SQL octet Valeurs limites MS Access Nature Remarque
numériques
SMALLINT 2  32 768 Entier entier court
INTEGER (ou INT) 4  2 147 483 647 Entier Long entier long
NUMERIC (ou 12  (10^28) -1 Décimal nombre décimal représentation exacte (précision,
DECIMAL ou DEC) échelle), 28 décimales

REAL 4  3.402823E38 Réel simple réel à virgule flottante représentation binaire, 7 décimales

FLOAT 8  Réel double réel à virgule flottante représentation binaire, précision


1,7976931E308 obligatoire, 15 décimales

DOUBLE PRECISION 8 réel à virgule flottante représentation binaire

BIT chaîne de bit longueur fixe

alphanumériques
CHAR 255 Texte caractères (ou CHARACTER)

VARCHAR 32767 caractères (ou CHARACTER VARYING)

NCHAR (ou NATIONAL CHARACTER)

temporels
TIMESTAMP 8 Date/Heure combiné date temps
DATE date du calendrier grégorien

TIME temps sur 24 heures

24/04/2012
Les types de champs 2/2

Les types non normalisés SQL 2


Type SQL octet Valeurs limites MS Access Nature Remarque
BLOBS
TEXT 65 536 Mémo () caractères longueur indéterminé

IMAGE image stockage dans un format déterminé

OLE objet OLE Windows

autres types
BOOLEAN Oui/Non ou LOGICAL

MONEY Monétaire NUMERIC précision de deux chiffres.

BYTES 1 octet ou BINARY

AUTOINC 4 NuméroAuto entier à incrément automatique

24/04/2012
SGBDR : Le modèle relationnel
Objectif du modèle :
Entités Pas d’information redondante

La clef primaire d'une table est un


attribut ou un groupe d'attributs de
Attributs cette table dont la valeur permet
d'identifier de manière unique une
ligne de la table.
Permet la création de liaisons fixes
Relation entre les tables en mettant en
relation un ou plusieurs champs.

Cardinalité : dénombre le nombre d'éléments de Relations possibles :


l'entité départ en relation avec un 1/1, 1/n, n/1, n/m
élément de l'entité arrivée. Une relation n/m nécessite une table de jointure

24/04/2012
SGBDR : Le modèle relationnel
• 1 nom à n téléphones
• 1 téléphone est partagé
par m nom

relation n / m

table de jointure

L'attribut id de l'entité xxx


= clé primaire de la table xxx
permet la relation avec l'entité yyy via l'attribut
id_xxx = clé étrangère de la table yyy

24/04/2012
SQLite : SGBDR portable utilisable sous
• moteur de base de données relationnelles accessible par le langage SQL.
• implémente en grande partie le standard SQL-92
• la base de données (déclarations, tables, index et données) stockée dans un fichier
• utilisation sans restriction dans des projets aussi bien open source que propriétaires
• multi-plateforme
Une « interface » utilisateur : SQLite Database Browser
http://www.sqlite.org/

SQLite est le moteur de base de données le plus


distribué au monde, grâce à son utilisation dans de
nombreux logiciels grand public comme Firefox,
Skype, Google Gears, dans certains produits d'Apple,
d'Adobe et de McAfee et dans les librairies standards
de nombreux langages comme PHP ou Python. De
par son extrême légèreté (moins de 300 ko), elle est
également très populaire sur les systèmes embarqués,
notamment sur la plupart des smartphones modernes.

http://sqlitebrowser.sourceforge.net/

La librairie sqldf permet à d'utiliser SQLite


24/04/2012
Pourquoi se connecter au SGBD ?
Sans connexion

Serveur de données fichier


SGBD (DBMS)
copier Excel .txt read.table()
coller fichier texte .csv read.csv2()
sélection
export
A refaire si les données sont modifiées ou si mauvaise sélection
Introduction d’un fichier intermédiaire  l’intégrité des données n’est plus respectée

Avec connexion

Serveur de données
SGBD (DBMS) Interface de connexion odbcDriverConnect()
Excel sqlFetch()
fichier texte
sqlQuery()

Intégrité des données respectée


Sélection des données dans R
24/04/2012
Accès à l'application gérant les données

Application
Interface de connexion Serveur de données
SGBD (DBMS)
DBI Excel
database interface fichier texte

ODBC ODBC : interface spécialisée


L'application doit avoir un pilote ODBC.
Open DataBase Connectivity
Exemple : pilote ODBC SQLite
http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe

L’interface doit : rôle des objets de

 Identifier l'application DBI Driver


Dans ce cas la connexion se fait
directement sur le pilote ODBC de
 Etablir la connexion DBI Connexion
l'application

 Renvoyer les données DBI Résultats


24/04/2012
Des packages R spécifiques* R ≥ 2.9

Interface de connexion Application


Serveur de données

Package source: RMySQL_0.7-4.tar.gz


RMySQL MacOS X binary: RMySQL_0.7-4.tgz MySQL
Windows binary: RMySQL_0.7-4.zip

Package source: RPostgreSQL_0.1-6.tar.gz


RPostgreSQL MacOS X binary: Non disponible PostgreSQL
Windows binary: RPostgreSQL_0.1-6.zip

Package source: ROracle_0.5-9.tar.gz


ROracle MacOS X binary: Non disponible Oracle
Windows binary: Non disponible

Package source: RSQLite_0.8-2.tar.gz


RSQLite MacOS X binary: RSQLite_0.8-2.tgz SQLite
Windows binary: RSQLite_0.8-2.zip

Package source: RODBC_1.3-1.tar.gz Bases de données ayant


RODBC MacOS X binary: RODBC_1.3-1.tgz un pilote ODBC :
Windows binary: RODBC_1.3-1.zip
Access, Excel, SQLite...
* Contient à la fois le driver et l'interface (DBI) 24/04/2012
ODBC = Open DataBase Connectivity (format défini par Microsoft)

Couche logiciel qui permet la connexion d’une application windows à une source
de données
La source de données est identifiée par son DSN = Data Source Name

Machine utilisateur Serveur de données distant

Microsoft, UNIX, Linux

Client Microsoft

Applications
SGBD
DSN
windows ODBC

Driver ODBC
correspondant à
l'application source

Client
Oracle Oracle
24/04/2012
Connexion à une base de données via ODBC
channel <- odbcDriverConnect () Configurer un lien ODBC sous
Windows
• Démarrer
• Panneau de configuration
La base est dans un La base est sur • Outils d’administration
répertoire accessible un serveur distant • Sources de données (ODBC)

Contrôle de
l’accès si activé

Configuration du DSN
L’accès à la base est décrit dans le dsn associé dans
C:\Program Files\Fichiers communs\ODBC\Data Sources

Permet d’identifier la source


Nom de la base à connecter
24/04/2012
Connexion : la démarche
Connexion via DBI via ODBC
exemple : SGBD sqlite
1. charger la librairie
library (RSQLite) library (RODBC)
2. charger le pilote
drv <- dbDriver ("SQLite")
3. ouvrir une connexion sur les données
con <- dbConnect (drv, dbname=*...) channel <- odbcDriverConnect()
* nom de la base uniquement ou channel <- odbcConnectExcel(…)
channel <- odbcConnectAccess(…)
4. voir la structure des données (non obligatoire)
dbListTables (con) sqlTables (channel,…)
dbListFields (con, "sqtable") sqlColumns (channel, sqtable,…)
dbGetRowCount (res); dbColumnInfo (res)
5. charger les données avec tous les champs
dbReadTable (con, sqtable) sqlFetch (channel, sqtable,…)
6. charger les données avec un SELECT (sql)
res <- dbSendQuery (con, sql) sqlQuery (channel, sql,…)
fetch (res, n = -1)
dbGetQuery (channel, sql,…)
7. fermer la connexion : OBLIGATOIRE pour libérer l’accès
dbDisconnect (con) close(channel) ou odbcClose(channel)
odbcCloseAll()
8. libérer le pilote : dbUnloadDriver (drv) 24/04/2012
Exemples de connexion
à une base sqlite : "SeminR.db" à une base Access
Via DBI Via ODBC
library (RSQLite) library (RODBC) library (RODBC)
# Se mettre dans le répertoire de la base (conn <- file.choose())
setwd(choose.dir()) [1] "C:\\...\\Séminaire R\\RODBC.mdb"
db <- "SeminR.db"
drv <- dbDriver("SQLite")
con <- dbConnect(drv, dbname=db) c_sqlite <- odbcDriverConnect() channel <- odbcConnectAccess (conn)

drv c_sqlite channel


<SQLiteDriver:(2192)> RODBC Connection 10 RODBC Connection 11
con Details: Details:
<SQLiteConnection:(2192,0)> case=nochange case=nochange
DSN=SemirR3 DBQ=C:\Mes documents
dbGetInfo(drv)$num_con Database=C:\Mes documents sauvegardés\Enseignement\Séminaire
[1] 1 # nombre de connexion sauvegardés\Enseignement\Séminaire R\RODBC.mdb
dbGetInfo(con) R\Nouveau 2010\SeminR.db Driver={Microsoft Access Driver (*.mdb)}
$dbname StepAPI=0 DriverId=25
[1] "SeminR.db" SyncPragma=NORMAL FIL=MS Access
NoTXN=0
$serverVersion MaxBufferSize=2048
Timeout=
[1] "3.6.21" ShortNames=0 PageTimeout=5
$rsId LongNames=1 UID=admin
integer(0) NoCreat=0
$loadableExtensions NoWCHAR=0
[1] "off" JournalMode=
$flags LoadExt=
[1] 6
$vfs
[1] ""
dbDisconnect (con)
[1] TRUE
con
<Expired SQLiteConnection: DBI CON (2192, 0)> 24/04/2012
Accès aux structures
dbListTables(con)
DBI [1] "Habitants" "localisation" "personnes"
sqlTables (c_sqlite)
TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS
1 <NA> <NA> Habitants TABLE <NA>
2 <NA> <NA> localisation TABLE <NA>
3 <NA> <NA> personnes TABLE <NA>
sqlTables (channel)
Tables TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS
1 C:\\...\\Séminaire R\\RODBC <NA> MSysAccessObjects SYSTEM TABLE <NA>
2 C:\\...\\Séminaire R\\RODBC <NA> MSysAccessXML SYSTEM TABLE <NA>
ODBC 3 C:\\...\\Séminaire R\\RODBC <NA> MSysACEs SYSTEM TABLE <NA>
4 C:\\...\\Séminaire R\\RODBC <NA> MSysObjects SYSTEM TABLE <NA>
5 C:\\...\\Séminaire R\\RODBC <NA> MSysQueries SYSTEM TABLE <NA>
6 C:\\...\\Séminaire R\\RODBC <NA> MSysRelationships SYSTEM TABLE <NA>
7 C:\\...\\Séminaire R\\RODBC <NA> Habitants TABLE <NA>
8 C:\\...\\Séminaire R\\RODBC <NA> Localisation TABLE <NA>
9 C:\\...\\Séminaire R\\RODBC <NA> Personnes TABLE <NA>

sqtable = "localisation"
dbExistsTable (con, sqtable)
[1] TRUE
DBI dbListFields( con, sqtable)
[1] "id" "Adresse" "Code" "Ville"
sqlColumns (c_sqlite, sqtable)[,3:6]
TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME
1 localisation id 4 INTEGER
Champs 2
3
localisation
localisation
Adresse
Code
-9
8
VARCHAR
NUMERIC
4 localisation Ville -10 TEXT
ODBC sqlColumns (channel, sqtable)[,3:6]
TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME
1 localisation id 4 COUNTER
2 localisation Adresse 12 VARCHAR
3 localisation Code 4 INTEGER
4 localisation Ville 12 VARCHAR 24/04/2012
Travailler avec les tables via ODBC
 Créer une table
 En enregistrant un data.frame : sqlSave ()
sqlSave(channel, datal[1:2,], rownames ="pk", addPK =TRUE)
Par défaut : Création d’une clef primaire nommée pk
tablename = sqlQuery(channel,"SELECT * FROM datal")
nom du data.frame pk id Adresse Code Ville
1 1 1 avenue Verdun 92170 VANVES
2 2 2 rue Gay Lussac 92320 CHATILLON

 En copiant la structure d'une table existante : sqlCopyTable ()


sqlCopyTable(channel, srctable, Nom de la table à copier (source)

desttable, destchannel = channel)


Nom de la nouvelle table et sa localisation

 En copiant le résultat d'une requête : sqlCopy ()


sqlCopy(channel, query, "SELECT ... FROM ... ;"

desttable, destchannel = channel)


Nom de la nouvelle table et sa localisation 24/04/2012
Travailler avec les tables via ODBC
 Ajouter des lignes
 à une table : sqlSave ()
sqlQuery(channel,"SELECT * FROM datal")
pk id Adresse Code Ville
# ajouter la 3ème ligne du data.frame datal 1 1 1 avenue Verdun 92170 VANVES
# à la table de même nom 2 2 2 rue Gay Lussac 92320 CHATILLON
3 3 3 rue Roissis 92140 CLAMART
sqlSave (channel, datal[3,],
rownames = "pk", addPK = TRUE, append = TRUE)

 Modifier des lignes


 d’une table : sqlUpdate ()
# modification de la 3ème ligne de datal
datal[3,3:4] = datal[1,3:4]
datal <- cbind(rownames(datal),datal) sqlQuery(channel,"SELECT * FROM datal")
colnames(datal)[1] <- "pk" pk id Adresse Code Ville
1 1 1 avenue Verdun 92170 VANVES
2 2 2 rue Gay Lussac 92320 CHATILLON
sqlUpdate (channel, datal[3,], 3 3 3 rue Roissis 92170 VANVES

tablename = "datal", index = "pk")


24/04/2012
Travailler avec les tables via ODBC
 Supprimer toutes les lignes
 d’une table : sqlClear ()
sqlClear (channel, "datal")
sqlQuery(channel,"SELECT count(*) FROM datal")
Expr1000
1 0
Mais la structure de la table existe toujours
sqlSave(channel,datal,rownames = FALSE, append = TRUE)
sqlQuery(channel,"SELECT count(*) FROM datal")
Expr1000
1 3

 Supprimer une table


 sqlDrop ()
sqlDrop (channel,"datal")

24/04/2012
 Pas de sélection de
Accès aux données colonnes

(dDBI <- dbReadTable(con, sqtable))


id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON
3 3 rue Roissis 92140 CLAMART
DBI str(dDBI)
'data.frame': 3 obs. of 4 variables:
$ id : int 1 2 3
$ Adresse: chr "avenue Verdun" "rue Gay Lussac" "rue Roissis"
$ Code : int 92170 92320 92140
$ Ville : chr "VANVES" "CHATILLON" "CLAMART"

(dODBC <- sqlFetch (c_sqlite, sqtable))


localisation.id localisation.Adresse localisation.Code localisation.Ville
1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON
3 3 rue Roissis 92140 CLAMART
str(dODBC)
'data.frame': 3 obs. of 4 variables:
ODBC $ localisation.id : int 1 2 3
$ localisation.Adresse: Factor w/ 3 levels "avenue Verdun",..: 1 2 3
$ localisation.Code : num 92170 92320 92140
$ localisation.Ville : Factor w/ 3 levels "CHATILLON","CLAMART",..: 3 1 2

Pour avoir des caractères, mettre le paramètre stringsAsFactors = FALSE

24/04/2012
Utilisation de sqlFetch() Commande RODBC
sqlFetchMore() Gestion
d’un
 Charger les données ligne(s) à ligne(s)
curseur
sqlFetch (channel,"personnes", max=3) lignes
Nom Prénom numéro Adresse Code Ville Téléphone Depuis
1 Lecesve André 9 rue Gay Lussac 92320 CHATILLON 146542856 1920-10-19
2 Larrouy Catherine 10 rue Gay Lussac 92320 CHATILLON 140920841 1999-01-01
3 Larrouy Eric 10 rue Gay Lussac 92320 CHATILLON 140920841 1999-01-01 1 à max

sqlFetchMore (channel, max=1)


Nom Prénom numéro Adresse Code Ville Téléphone Depuis 4
1 Malher Goerges 13 rue Gay Lussac 92320 CHATILLON 146576986 1960-06-05 curseur + max

sqlFetchMore (channel)
Nom Prénom numéro Adresse Code Ville Téléphone Depuis
1 Lipinski Ludovic 15 rue Gay Lussac 92320 CHATILLON 147352329 1952-09-23
2 Meyer Michel 15 rue Roissis 92140 CLAMART NA 1960-06-05
3 Foucher Georges 17 rue Roissis 92140 CLAMART 146449501 2000-02-03
4
5
Auquier
Auquier
Anne
Anne
21
21
rue Roissis
rue Roissis
92140
92140
CLAMART 157750048 2005-09-05
CLAMART 636699001 2005-09-05
5 à 13
6 Auquier Bernard 21 rue Roissis 92140 CLAMART 146428564 2005-09-05
7 Mahier Ludovic 3 avenue Verdun 92170 VANVES 147361266 1983-05-07
8 Berrue Christiane 4 avenue Verdun 92170 VANVES 146381434 1985-10-21
9 Berrue Christiane 4 avenue Verdun 92170 VANVES 954912355 1985-10-21

sqlFetchMore (channel, max=1)


[1] -1 code de fin
24/04/2012
Connexion ODBC à un classeur Excel

 Par sélection dans un menu  Par son nom


( conn <- file.choose() )
channel <- odbcConnectExcel() [1] "C:\\Mes documents sauvegardés\\Enseignement
\\CoursStat\\Séminaire R\\Habitants.xls"

channel <- odbcConnectExcel(conn)

channel
RODB Connection 3
Details:
case=nochange
DBQ=C:\Mes documents sauvegardés\Enseignement\Séminaire R\Habitants.xls
DefaultDir=C:\Mes documents sauvegardés\Enseignement\Séminaire R
Driver={Microsoft Excel Driver (*.xls)}
DriverId=790
MaxBufferSize=2048
PageTimeout=5

 Ouvrir la connexion avec l’option d’écriture (par défaut : readOnly = TRUE)


channel <- odbcConnectExcel (conn, readOnly = FALSE) 24/04/2012
Commandes RODBC
Accès aux données Excel
Commandes identiques à l'accès à un SGBDR sauf sqlQuery()
 Voir la structure des données : description du classeur
sqlTables(channel)
TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS
1 C:\\Mes documents sauvegardés\\Enseignement\\Séminaire R\\Habitants <NA> Feuil1$ SYSTEM TABLE <NA>
2 C:\\Mes documents sauvegardés\\Enseignement\\Séminaire R\\Habitants <NA> Feuil2$ SYSTEM TABLE <NA>
3 C:\\Mes documents sauvegardés\\Enseignement\\Séminaire R\\Habitants <NA> Feuil3$ SYSTEM TABLE <NA>

 Charger les données : sqlFetch()


data <- sqlFetch (channel, "Feuil1")

nom de la connexion nom de la « table » obligatoire

 Ecriture des données dans une nouvelle feuille


sqlSave(channel, data1, tablename = "New", rownames = FALSE) Nouveau nom de Pas d’écrire possible
dans une feuille vide
data.frame des données nom de la feuille TRUE par défaut feuille obligatoire
existante.

 Ajouter des données dans une feuille Possible que si la


sqlSave(channel,data1,tablename = "New", rownames = FALSE, append = TRUE) feuille à des données

Obligatoire : fermer la connexion pour accéder au fichier par Excel


close(channel) 24/04/2012
SQL (Structured Query Language)

Utilisation du language SQL pour sélectionner :

 des colonnes
 des lignes

d'une ou plusieurs tables

par l'utilisation d'une requête SQL

24/04/2012
SQL (Structured Query Language)

Langage normalisé pour décrire, manipuler, contrôler l'accès et interroger


les bases de données relationnelles

Caractéristiques
 Inventé en 1970
 Déclaratif c'est-à-dire indépendant du contexte d'exécution
 Régi par une norme ANSI/ISO
 Première normalisation ISO en 1987
 SQL 2 correspond à la norme SQL/92
 SQL 3 en 1999, actuellement SQL 2003
 Portable sur différentes plates-formes aussi bien matérielles que logicielles.

Une commande SQL écrite dans un environnement Windows sous MS-ACCESS


est utilisable directement dans un environnement ORACLE sous Unix.

24/04/2012
SQL (Structured Query Language)

Langage de requêtes structuré


regroupant :
 un langage de contrôle des accès (DCL, Data Control Language)

 un langage de définition de données (DDL Data Definition Language)


 Pour créer, modifier ou supprimer des tables dans la base

 un langage de manipulation de données (DML, Data Manipulation Language)


 Pour sélectionner, insérer, modifier ou supprimer des données dans une
table

24/04/2012
Les commandes SQL
DCL : Contrôle des données
GRANT Attribution de droits d'accès
REVOKE Suppression de droits d'accès
COMMIT Prise en compte des mises à jour
ROLLBACK Suppression des mises à jour

DDL : Description des données


CREATE Création de tables
ALTER Modification de tables
DROP Suppression de tables

DML : Manipulation des données


SELECT Interrogation des données
INSERT Insertion de lignes dans une table
UPDATE Mise à jour de lignes dans une table
DELETE Suppression de lignes dans une table

24/04/2012
Syntaxe de la commande SELECT
SELECT [ALL | DISTINCT] { * | col | expr [AS alias], ... }
FROM table [alias], ...
Légende :
[ WHERE { conditions de recherche | sous conditions} ] { } : Une des valeurs
séparées par '|'
[ GROUP BY col, ...] [HAVING conditions de recherche ] obligatoire.
[ ] : Valeur optionnelle.
[ ORDER BY { col | num } {ASC | DESC}, ...] ; ... : Répétition.
__ : Valeur par défaut.

SELECT Précise les colonnes qui vont apparaître dans la réponse


FROM Précise la (ou les) table intervenant dans l'interrogation
WHERE Précise les conditions à appliquer sur les lignes avec :
- Des opérateurs de comparaison : =, >, <, >=, <=,<>
- Des opérateurs logiques : AND, OR, NOT
- Des prédicats : IN, LIKE, NULL, ALL, ANY...
GROUP BY Précise la (ou les) colonne de regroupement
HAVING Précise la (ou les) conditions associées à un regroupement
ORDER BY Précise l'ordre dans lequel vont apparaître les lignes de la réponse :
- ASC : ordre ascendant (par défaut)
- DESC : ordre descendant
24/04/2012
Accès aux données via SQL
La requête : sql <- "SELECT * FROM localisation ;"
dbGetQuery(con, sql)
id Adresse Code Ville Première utilisation
1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON
3 3 rue Roissis 92140 CLAMART
res <- dbSendQuery(con, sql) # Prépare la requête Deuxième
fetch (res, n = 2) # Affiche n lignes (curseur), si n = -1 → jusqu’à la fin utilisation
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON
dbGetRowCount(res) # nb lignes lues
[1] 2
DBI dbHasCompleted(res) # test la fin de l’affichage
[1] FALSE
fetch(res, n = -1)
id Adresse Code Ville
3 3 rue Roissis 92140 CLAMART
dbHasCompleted(res)
[1] TRUE

Autres fonctions :
dbClearResult (res) # libère le lien à la table. A faire pour un nouveau dbSendQuery() si dbHasCompleted(res)→FALSE
dbColumnInfo (res) #  à sqlColumns()
dbGetStatement (res) # affiche le SELECT

sqlQuery(c_sqlite, sql)
localisation.id localisation.Adresse localisation.Code localisation.Ville
ODBC 1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON
3 3 rue Roissis 92140 CLAMART 24/04/2012
library (sqldf)
pour l'utilisation d'une base de données sqlite

sqldf () permet l'usage des requêtes SQL sur :


 les tables d'une base SQLite
 des data frames
 des fichiers textes

Utilise les librairies :


• DBI (data base interface)
• RSQLite : pilote (driver) R pour l’accès à une base SQLite

24/04/2012
Connexion à une base sqlite via sqldf ()
 Ouverture d'une connexion à la base sqlite "nom_de_la_base" *
* exclusivement le nom de la base et non le chemin complet
sqldf (dbname = "nom_de_la_base")
Si "nom_de_la_base" non trouvé : création d'une base vide à ce nom

 Si dbname non précisé : ouverture d'une base virtuelle


( sqldf () )
<SQLiteConnection:(1036,0)>
 Fermeture de la connexion au 2ème appel
sqldf ()
NULL

Utilisation des commandes DBI :


dbGetInfo(SQLite())$num_con # nombre de connexions ouvertes
con <- sqldf (dbname = "nom_de_la_base") # récupération de l’identifiant de la connexion
dbListTables(con) # liste les tables de la base "SQLite" connectée

(*) Exemple d’un script setwd(dirname(dbase <- file.choose())) # change le répertoire


de sélection de la dbase = iconv(dbase,Encoding(dbase),"latin1") # conversion code caractère
base à connecter dbase <- substring(dbase,max(unlist(gregexpr("\\",dbase,fixed=TRUE)))-1)
sqldf(dbname = dbase) # connexion 24/04/2012
Utiliser SQL pour manipuler des données dans
library (sqldf)

sqldf ("Requête SQL", dbname = ..., connection = ... )


nom* d'une base SQLite nom d'une connexion
par défaut : sur une base SQLite
SELECT ouvre une base virtuelle
OU
ouverte par :
en mémoire - dbConnect ()
- sqldf (dbname = )
* uniquement le nom de la base
par défaut

• sur des tables d'une base SQLite (ou MySQL)


• sur des fichiers textes
• sur des data.frames
Remarque sur l'ouverture / fermeture de la connexion
( sqldf() ) # ouverture d’une connexion sur une base virtuelle
<SQLiteConnection:(1036,0)>
( sqldf() ) # fermeture de la connexion au 2ème appel
NULL 24/04/2012
SELECT SQL via sqldf
S’assurer qu’une connexion
1 - Utilisation avec une base sqlite est bien ouverte

sqldf ("SELECT * FROM ma_table ;", method = "raw" )

Requête SQL "raw" Données brutes


"auto" Types ajustés au "mieux"

2 - Utilisation avec un data.frame

Exemple : iris
sqldf ("SELECT * FROM iris ;", method = "raw", row.names = FALSE)

Requête SQL "raw" Données brutes TRUE : ajoute une colonne row_names à la table
"auto" Types ajustés si method= "raw" et SELECT * : ajoute une
colonne row_names au data.frame

Attention – Dans les cas 2, 3 et 4


 si la connexion est sur une base nommée, il y aura copie de la (des) table(s) du FROM. Risque
de conflit !
 si la connexion ne pointe aucune base nommée, c’est la base virtuelle qui est utilisée.
24/04/2012
SELECT SQL via sqldf sur un fichier texte
3 – Avec la syntaxe sqldf

fich <- file(file.choose()) # ouvre une connexion sur un fichier texte au choix
attr(fich , "file.format") <- list(sep = "\t" , header = TRUE) # affectation des attributs
Séparateur des champs Si nom des colonnes en 1ère ligne

sqldf ("SELECT * FROM fich;", method = "auto")

Requête SQL • Si pas de nom de colonne : nomme des colonnes de V1 à Vncol


• Si header = TRUE :
si length(colnames) = ncol : nomme les colonnes avec les noms
si length(colnames) = ncol -1 ajoute une colonne row_names à la table
si method= "raw" et SELECT * ajoute une colonne row_names au data.frame

4 – Avec un read.csv filtré par SELECT SQL


read.csv2.sql (file.choose(), sql = "select * from file” )
«file» mot clé obligatoire

Remarque :
dbRemoveTable(con, "ma_table") # supprime la table "ma_table" de la base connectée
24/04/2012
sqldf () pour manipuler des données dans
1 - Utilisation avec une base SQLite
requête SQL

pers <- sqldf ("SELECT Nom, prenom, id_localisation FROM Personnes ;",
dbname = "SeminR.db") # nom de la base
condb <- dbConnect (drv = "SQLite", dbname = "SeminR.db")
loca <- sqldf ("SELECT * FROM localisation ;", connection = condb) # connexion

2 - Utilisation avec des data.frames


NV
sql <- "SELECT Nom, Ville FROM loca , pers # data.frame Nom Ville
1 Lecesve CHATILLON
WHERE loca.id = pers.id_localisation # jointure
2 Larrouy CHATILLON
AND Nom LIKE 'L%' ;" # troncature à droite 3 Larrouy CHATILLON
NV <- sqldf (sql) # requête exécuté dans la base virtuelle 4 Lipinski CHATILLON

3 - Utilisation avec des fichiers textes


Loc <- file ("Localisation.txt") # connexion au fichier texte
attr (Loc ,"file.format") = list (sep = "\t", header=TRUE)

sql1 ="SELECT DISTINCT Nom, code, NV.Ville FROM NV, Loc Nom Code Ville
WHERE Loc.Ville = NV.Ville ;" # jointure 1 Larrouy 92320 CHATILLON
2 Lecesve 92320 CHATILLON
sqldf (sql1) 3 Lipinski 92320 CHATILLON
data.frame
fichier texte 24/04/2012
sqlQuery vs sqldf
Commandes RODBC

Requêtes
Données Connexions
SQL

SGBD channel <- odbcDriverConnect (maBase)


sqlQuery (channel, SQL)
Access channel <- odbcConnectAccess (maBase)
channel <- odbcConnectAccess (paste(getwd(),"RODBC.MDB",sep="/"))

Excel channel <- odbcConnectExcel (monClasseur)

sqlFetch (channel, "maFeuil")

mon.data.frame
Commandes sqldf

fichier channel_file <- file (monFichier)


.txt sqldf (SQL)
.csv Habitants <- file( paste(getwd(),"Habitants.txt",sep="/") )
attr(Habitants ,"file.format") = list(sep = "\t",header=TRUE)
Personnes <- file( paste(getwd(),"Personnes.txt",sep="/") )
attr(Personnes ,"file.format") = list(sep = "\t",header=TRUE)
Localisation <- file( paste(getwd(),"Localisation.txt",sep="/") )
attr(Localisation ,"file.format") = list(sep = "\t",header=TRUE)
Comm2 <- file( paste(getwd(),"Comm2.txt",sep="/") )
attr(Comm2 ,"file.format") = list(sep = "\t",header=TRUE)

24/04/2012
Syntaxe de la commande SELECT
SELECT [ALL | DISTINCT] { * | col | expr [AS alias], ... }
FROM table [alias], ...
Légende :
[ WHERE { conditions de recherche | sous conditions} ] { } : Une des valeurs
séparées par '|'
[ GROUP BY col, ...] [HAVING conditions de recherche ] obligatoire.
[ ] : Valeur optionnelle.
[ ORDER BY { col | num } {ASC | DESC}, ...] ; ... : Répétition.
__ : Valeur par défaut.

SELECT Précise les colonnes qui vont apparaître dans la réponse


FROM Précise la (ou les) table intervenant dans l'interrogation
WHERE Précise les conditions à appliquer sur les lignes avec :
- Des opérateurs de comparaison : =, >, <, >=, <=,<>
- Des opérateurs logiques : AND, OR, NOT
- Des prédicats : IN, LIKE, NULL, ALL, ANY...
GROUP BY Précise la (ou les) colonne de regroupement
HAVING Précise la (ou les) conditions associées à un regroupement
ORDER BY Précise l'ordre dans lequel vont apparaître les lignes de la réponse :
- ASC : ordre ascendant (par défaut)
- DESC : ordre descendant
24/04/2012
Alias renommer une colonne ou une table
(cf auto jointure)

sql <- "SELECT Adresse AS Voie, Code AS [Code postal], Ville AS Commune
FROM Localisation;"

Voie Code postal Commune


1 avenue Verdun 92170 VANVES
2 rue Gay Lussac 92320 CHATILLON
3 rue Roissis 92140 CLAMART

sql <- "SELECT Ville, ' - ' AS Sep, Code AS CP FROM Localisation;"

Ville Sep CP
1 VANVES - 92170
2 CHATILLON - 92320
3 CLAMART - 92140

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
ORDER BY Trier la sélection
 croissant ou alphabétique : ASC (par défaut)
sql <- "SELECT * FROM Localisation ORDER BY Code;"
id Adresse Code Ville
1 3 rue Roissis 92140 CLAMART
2 1 avenue Verdun 92170 VANVES
3 2 rue Gay Lussac 92320 CHATILLON

sql <- "SELECT * FROM Localisation ORDER BY Ville;"


id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON
2 3 rue Roissis 92140 CLAMART
3 1 avenue Verdun 92170 VANVES

 décroissant DESC
sql <- "SELECT * FROM Localisation ORDER BY Code desc;"
id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON
2 1 avenue Verdun 92170 VANVES Exécution de la requête SQL :
3 3 rue Roissis 92140 CLAMART sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
DISTINCT Supprimer les lignes identiques

sql <- "SELECT DISTINCT Nom FROM Personnes;"


Nom
1 Auquier
2 Berrue
3 Foucher
4 Larrouy
5 Lecesve
6 Lipinski
7 Mahier
sql <- "SELECT Nom, Prénom
8 Malher
FROM Personnes
9 Meyer ORDER BY Nom, Prénom;"
Nom Prénom
1 Auquier Anne
2 Auquier Anne
Remarque : DISTINCT trie aussi 3 Auquier Bernard
4 Berrue Christiane
5 Berrue Christiane
6 Foucher Georges
7 Larrouy Catherine
8 Larrouy Eric
Exécution de la requête SQL : 9 Lecesve André
sqldf (sql) 10 Lipinski
11 Mahier
Ludovic
Ludovic
sqlQuery (channel, sql) 12 Malher Goerges
13 Meyer Michel
24/04/2012
COUNT () Compter des enregistrements

# nombre d'enregistements de la table


sql <- "SELECT count(*) FROM Personnes;"
count(*)
1 13
# nombre d'enregistements pour un champ
sql <- "SELECT count(Nom) FROM Personnes;"
count(*)
1 13
sql <- "SELECT count(Distinct Nom) FROM Personnes;"
count(Distinct Nom)
1 9
sql <- "SELECT count(Téléphone) FROM Personnes;"
count(Téléphone)
1 12
Exécution de la requête SQL :
sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
WHERE Introduire des conditions de recherche

sql <- "SELECT * FROM Localisation WHERE ville = 'VANVES' ;"


id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES

sql <- "SELECT * FROM Localisation WHERE Code < 92200 ;"
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
2 3 rue Roissis 92140 CLAMART

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
Prédicats : LIKE, BETWEEN, IN, ISNULL
LIKE rechercher à l'intérieur d'une chaîne de caractères

% symbole de troncature
_ remplace 1 caractère

sql <- "SELECT * FROM Localisation WHERE Ville LIKE 'C%' ;"
id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON
2 3 rue Roissis 92140 CLAMART

sql <- "SELECT * FROM Localisation WHERE Ville LIKE '%N%' ;"
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
2 2 rue Gay Lussac 92320 CHATILLON

sql <- "SELECT * FROM Localisation WHERE Ville LIKE '_A%' ;"
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
Exécution de la requête SQL :
sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
Prédicats : LIKE, BETWEEN, IN, ISNULL
IN rechercher dans une liste de valeurs

Exemples

sql <- "SELECT * FROM Localisation WHERE Code IN (92140, 92320) ;"

sql <- "SELECT * FROM Localisation WHERE Ville IN ('CHATILLON', 'CLAMART') ;"

Troncature impossible
id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON
2 3 rue Roissis 92140 CLAMART

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
Prédicats : LIKE, BETWEEN, IN, ISNULL
BETWEEN
rechercher entre deux bornes

sql <- "SELECT * FROM Localisation WHERE Code BETWEEN 92140 AND 92200 ;"

id Adresse Code Ville


1 1 avenue Verdun 92170 VANVES
2 3 rue Roissis 92140 CLAMART

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
Prédicats : LIKE, BETWEEN, IN, ISNULL
NOT …

Les commandes LIKE, IN et BETWEEN peuvent être utilisées avec le préfixe NOT

sql <- "SELECT * FROM Localisation WHERE Ville NOT LIKE '%N%' ;"

id Adresse Code Ville


1 3 rue Roissis 92140 CLAMART

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
Prédicats : LIKE, BETWEEN, IN, ISNULL
IS NULL
rechercher des valeurs nulles
sql <- "SELECT Nom, Prénom FROM Personnes WHERE ISNULL (Téléphone);"
# NOT ISNULL ()
sqlQuery(channel,sql)
Nom Prénom
1 Meyer Michel
sqldf(sql) # erreur

sql <- "SELECT Nom, Prénom FROM Personnes WHERE Téléphone ISNULL;"
sqldf(sql)
Nom Prénom
1 Meyer Michel
sqlQuery(channel,sql) # erreur

sql <- "SELECT Nom, Prénom FROM Personnes WHERE Téléphone IS NULL;"
# IS NOT NULL
sqldf(sql)
sqlQuery(channel,sql)
Nom Prénom
1 Meyer Michel

sql <- "SELECT Nom, Prénom FROM Personnes WHERE NOT Téléphone IS NULL;" 24/04/2012
opérateurs logiques OR, AND, NOT
OR, AND, NOT
Lier les conditions de recherche
OR sql <- "SELECT * FROM Localisation WHERE Adresse Like '%s' OR Adresse Like '%n' ;"
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES
2 3 rue Roissis 92140 CLAMART

AND sql <- "SELECT * FROM Localisation WHERE Ville LIKE 'c%' AND Code > 92200 ;"
id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON

sql <- "SELECT * FROM Localisation WHERE NOT ville = 'VANVES' ;"
NOT # avec sqldf(sql) utilisation possible de !=
id Adresse Code Ville
1 2 rue Gay Lussac 92320 CHATILLON
2 3 rue Roissis 92140 CLAMART

sql <- "SELECT * FROM Localisation WHERE NOT Code = 92320 ;"
# idem avec sql <- "SELECT * FROM Localisation WHERE Code <> 92320 ;"
id Adresse Code Ville
1 1 avenue Verdun 92170 VANVES Exécution de la requête SQL :
2 3 rue Roissis 92140 CLAMART sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
GROUP BY Aggrégation des lignes
Permet faire un dénombrement (count) ou le calcul d'une fonction d'aggrégation
pour les champs des lignes regroupées.
Critères d'aggrégation : min, max, avg, sum ou une expression

Exemples :
 Nombre d'enregistrements par commune
sql <- "SELECT Ville, count(*) AS Nb_personnes FROM Habitants
GROUP BY Ville ;"
Ville Nb_personnes
1 CHATILLON 5
2 CLAMART 5
3 VANVES 3

 Moyenne des numéros par commune


sql <- "SELECT Ville, avg(numéro) AS Moy FROM Habitants
GROUP BY Ville ;"
Ville Moy
1 CHATILLON 11.400000
2 CLAMART 19.000000 Exécution de la requête SQL :
3 VANVES 3.666667
sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
GROUP BY  Réaliser un tableau de contingence

Nombre de téléphones par famille et par communes


sql <- "SELECT Nom, sum(Ville = 'CHATILLON') AS CHATILLON,
sum(Ville = 'CLAMART') AS CLAMART, sum(Ville = 'VANVES') AS VANVES
FROM Habitants GROUP BY Nom, Ville ;"

Nom CHATILLON CLAMART VANVES


1 Auquier 0 3 0
2 Berrue 0 0 2
3 Foucher 0 1 0 tabsql <- sqldf(sql)
4 Larrouy 2 0 0 str(tabsql)
'data.frame': 9 obs. of 4 variables:
5 Lecesve 1 0 0
$ Nom : Factor w/ 9 levels "Auquier","Berrue",..:
6 Lipinski 1 0 0 $ CHATILLON: int 0 0 0 2 1 1 0 1 0
7 Mahier 0 0 1 $ CLAMART : int 3 0 1 0 0 0 0 0 1
8 Malher 1 0 0 $ VANVES : int 0 2 0 0 0 0 1 0 0
9 Meyer 0 1 0 rownames(tabsql) <- tabsql[,1]
(tabsql <- tabsql[,-1])

sel <- sqldf("SELECT Nom, Ville FROM Habitants ;")


( tab <- table(sel) ) # class 'table'
str(tab) Exécution de la requête SQL :
as.data.frame(tab) # Résultat non attendu ! Pourquoi ? sqldf (sql)
class(tab) <- "matrix" sqlQuery (channel, sql)
as.data.frame(tab) # C'est mieux
24/04/2012
HAVING Clause " Where" d'un GROUP BY

Permet d'introduire une condition dans


un GROUP BY

Exemple : Qui a plus d'un téléphone dans les villes ayant un CP > 92150 ?

sql <- "SELECT Nom, Prénom, Count(Téléphone) AS NbTéléphone


FROM Habitants WHERE Code > 92150
GROUP BY Nom, Prénom
HAVING Count (Téléphone) >= 2 ;"

Nom Prénom NbTéléphone


1 Berrue Christiane 2

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
Jointure entre tables 1 - Jointure interne

1.1 - Equi-jointure : relier avec une relation d'égalité des tables par un champ commun

 Dans la clause WHERE


sql <- "SELECT Nom, Prénom, Ville FROM Localisation, Personnes WHERE
Localisation.id = id_localisation ;"
 Dans le FROM avec INNER JOIN ... ON
sql <- "SELECT Nom, Prénom, Ville FROM Localisation INNER JOIN Personnes
ON Localisation.id = id_localisation ;"

Nom Prénom Ville


1 Mahier Ludovic VANVES
2 Berrue Christiane VANVES
3 Berrue Christiane VANVES
4 Lecesve André CHATILLON
5 Larrouy Catherine CHATILLON
6 Larrouy Eric CHATILLON
7 Malher Goerges CHATILLON
8 Lipinski Ludovic CHATILLON Exécution de la requête SQL :
9 Meyer Michel CLAMART
10 Foucher Georges CLAMART
sqldf (sql)
11 Auquier Anne CLAMART sqlQuery (channel, sql)
12 Auquier Anne CLAMART
13 Auquier Bernard CLAMART
24/04/2012
Jointure entre tables 1 - Jointure interne

1.2 - Auto-jointure : jointure d'une table avec elle-même

 Utilisation obligatoire d'un alias

Rechercher des champs qui se trouvent à l'intérieur d'une même table.

Exemple : Qui partage le même téléphone ?

sql <- "SELECT a.Nom, a.Prénom, a.Téléphone FROM Habitants a, Habitants b


WHERE a.id <> b.id AND a.Téléphone = b.Téléphone;"

Nom Prénom Téléphone


1 Larrouy Catherine 140920841
2 Larrouy Eric 140920841

Exécution de la requête SQL :


sqldf (sql)
sqlQuery (channel, sql)

24/04/2012
Jointure entre tables 1 - Jointure interne

1.3 - Théta jointure : jointure avec un opérateur de comparaison autre que =

 Utilisation possible de : supérieur (>), inférieur (<), supérieur ou égal (>=),


inférieur ou égal (<=), différent (<>).

Exemple : Dans un ordre alphabétique, combien de villes sont après chaque ville ?
sql <- "SELECT a.Ville, COUNT(*) AS Reste FROM Localisation a, Localisation b
WHERE a.Ville < b.Ville GROUP BY a.Ville;"

Ville Reste
1 CHATILLON 2
2 CLAMART 1

Exécution de la requête SQL :


La liste est-elle complète ? sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
Jointure entre tables Remarques 1/2

 Une jointure sans clause WHERE réalise produit cartésien des tables impliquées
sql <- "SELECT count(*) FROM Localisation, Personnes ;"
count(*)
1 39
Vérification :
sqldf ("SELECT count(*) FROM Personnes;") * sqldf("SELECT count(*) FROM Localisation;")
count(*)
1 39 Nom Prénom Téléphone
1 Lecesve André 146542856
 Une jointure sur des champs non uniques 2
3
Larrouy Catherine 140920841
Larrouy Eric 140920841
réalise le produit entre ces champs 4 Malher
5 Lipinski
Goerges 146576986
Ludovic 147352329
6 Meyer Michel NA
sql <- "SELECT P.Nom, P.Prénom, P.Téléphone FROM 7 Foucher Georges 146449501
Personnes P, Habitants H 8 Auquier Anne 157750048
WHERE P.Nom= H.Nom AND P.Prénom= H.Prénom;" 9 Auquier Anne 157750048
10 Auquier Anne 636699001
11 Auquier Anne 636699001
Comment éliminer ces doublons ? 12 Auquier Bernard 146428564
13 Mahier Ludovic 147361266
14 Berrue Christiane 146381434
Exécution de la requête SQL : 15 Berrue Christiane 146381434
sqldf (sql) 16 Berrue Christiane 954912355
17 Berrue Christiane 954912355
sqlQuery (channel, sql) 24/04/2012
Jointure entre tables Remarques 2/2

 Jointure sur des champs contenant des valeurs nulles (NULL)


sql <- "SELECT P.Nom, P.Prénom, P.Téléphone FROM Personnes P, Habitants H
WHERE P.Nom= H.Nom AND P.Prénom= H.Prénom AND P.Téléphone = H.Téléphone;"
ou
sql <- "SELECT P.Nom, P.Prénom, P.Téléphone FROM Personnes P inner join Habitants H
ON P.Nom= H.Nom AND P.Prénom= H.Prénom AND P.Téléphone = H.Téléphone;"

Nom Prénom Téléphone


1 Lecesve André 146542856
2 Larrouy Catherine 140920841 Dans ce cas, il manque un nom car :
3 Larrouy Eric 140920841
4 Malher Goerges 146576986 Meyer Michel n'a pas de téléphone
5 Lipinski Ludovic 147352329
6 Foucher Georges 146449501
7 Auquier Anne 157750048
8 Auquier Anne 636699001
9 Auquier Bernard 146428564
10 Mahier Ludovic 147361266 Exécution de la requête SQL :
11 Berrue Christiane 146381434 sqldf (sql)
12 Berrue Christiane 954912355
sqlQuery (channel, sql)
24/04/2012
Jointure entre tables 2 – Jointure externe

{ LEFT | (RIGHT } OUTER JOIN : pour inclure tous les enregistrements d'une table et
seulement ceux de l'autre table pour lesquels les
champs joints sont égaux.
FULL OUTER JOIN : pour inclure les enregistrements pour lesquels les
champs joints sont égaux ou ont des valeurs nulles.

Utile quand les champs joints


ont des valeurs nulles
Exemple :

Habitants LEFT OUTER JOIN Comm2


ON Habitants.Code = Comm2.Code

sql <- "SELECT Habitants.Nom, Habitants.Prénom, Comm2.Ville


FROM Habitants LEFT OUTER JOIN Comm2 ON Habitants.Code = Comm2.Code;"
24/04/2012
Jointure entre tables 2 – Jointure externe

 LEFT OUTER JOIN


sql <- "SELECT Personnes.Nom, Personnes.Prénom, Personnes.Téléphone FROM
Personnes LEFT OUTER JOIN Habitants ON Personnes.Nom = Habitants.Nom AND
Personnes.Prénom = Habitants.Prénom AND Personnes.Téléphone = Habitants.Téléphone ;"

Nom Prénom Téléphone


1 Lecesve André 146542856 Résultat identique avec :
2 Larrouy Catherine 140920841 sql <- "SELECT P.Nom, P.Prénom, P.Téléphone
3 Larrouy Eric 140920841
4 Malher Goerges 146576986 FROM Personnes P, Habitants H WHERE
5 Lipinski Ludovic 147352329 (P.Nom= H.Nom AND P.Prénom= H.Prénom)
6 Meyer Michel NA AND
7 Foucher Georges 146449501 (P.Téléphone = H.Téléphone OR P.Téléphone is null;"
8 Auquier Anne 157750048
9 Auquier Anne 636699001
10 Auquier Bernard 146428564
11 Mahier Ludovic 147361266 Exécution de la requête SQL :
12 Berrue Christiane 146381434
13 Berrue Christiane 954912355 sqldf (sql)
sqlQuery (channel, sql)
 RIGHT OUTER JOIN
sql <- "SELECT Personnes.Nom, Personnes.Prénom, Personnes.Téléphone FROM
Habitants RIGHT OUTER JOIN Personnes ON Personnes.Nom = Habitants.Nom AND
Personnes.Prénom = Habitants.Prénom AND Personnes.Téléphone = Habitants.Téléphone ;"

Remarque : sqldf : RIGHT AND FULL OUTER JOINs are not currently supported
MS Access : FULL OUTER JOIN n'existe pas
24/04/2012
SELECT imbriqués
Permet d'utiliser dans la clause WHERE d'un SELECT le résultat d'un autre SELECT
S'utilise souvent à la place d'une la jointure

La sous requête peut retourner un sous ensemble de 0 à n valeurs.


En fonction de la condition de la clause WHERE du SELECT principal, on utilisera
pour la liaison entre le champ du SELECT principal et les valeurs renvoyées par la
sous requête :
 un des opérateurs de comparaison : =, >, <, >=, <=,<>
 un des prédicats : IN, ANY, ALL ou EXISTS

SELECT ... WHERE champ { opérateurs | prédicats } (SELECT ...

Suivant la condition souhaitée, le prédicat doit être :


IN Réalise l'égalité avec un OU entre toutes valeurs
ANY Vérifie si au moins une des valeurs satisfait la condition
ALL Vérifier si toutes les valeurs satisfont la condition
EXISTS La condition est VRAIE si n valeurs retournées > 0, FAUSSE si n = 0
24/04/2012
Corrélation SELECT imbriqués

Cas particulier :
Quand une condition fait intervenir le même champ de la même table

 Utilisation obligatoire d'alias


Exemple :
Nom des habitants dont l'adresse est dans la première moitié de la rue

sql <- "SELECT a.Nom, a.prénom, a.numéro, a.Adresse


FROM Habitants a
WHERE a.numéro <= (SELECT avg(b.numéro) FROM Habitants b
GROUP BY Adresse HAVING b.Adresse = a.Adresse) ;"

Nom Prénom numéro Adresse corrélation


1 Lecesve André 9 rue Gay Lussac
2 Larrouy Catherine 10 rue Gay Lussac
3 Larrouy Eric 10 rue Gay Lussac
4 Meyer Michel 15 rue Roissis Exécution de la requête SQL :
5 Foucher Georges 17 rue Roissis
6 Mahier Ludovic 3 avenue Verdun sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
IN, EXISTS SELECT imbriqués

Exemples d'utilisation

IN pour tester l'égalité avec toutes valeurs prises une par une (OU)

 Dans quelle(s) rue(s) des habitants n'ont pas de téléphone ?

sql <- "SELECT Adresse, Ville FROM Localisation


WHERE id IN (SELECT id_localisation FROM Personnes WHERE Téléphone IS NULL ) ;"

 Quel(s) habitant(s) ont la même ancienneté qu'Eric Larrouy ?


sql <- "SELECT DISTINCT Nom, Prénom , Depuis FROM Personnes
WHERE Depuis IN ( SELECT Depuis FROM Personnes
WHERE nom = 'Larrouy' AND Prénom ='Eric' )
AND NOT (nom = 'Larrouy' AND Prénom ='Eric') ;"
Pourquoi DISTINCT ?
# Avec une corrélation et EXISTS
sql <- "SELECT DISTINCT Nom, Prénom , Depuis FROM Personnes a
WHERE EXISTS ( SELECT * FROM Personnes b
WHERE b.nom = 'Larrouy' AND b.Prénom ='Eric'
AND b.Depuis = a.Depuis ) Exécution requête :
AND NOT (a.nom = 'Larrouy' AND a.Prénom ='Eric') ;"
sqldf (sql)
sqlQuery (channel, sql)
24/04/2012
ANY, ALL SELECT imbriqués

Exemples d'utilisation

 Quels habitants ont une ancienneté identique ou plus faible de celle d'Eric Larrouy ?
ANY pour tester si au moins une des valeurs satisfait la condition
sql <- "SELECT DISTINCT Nom, Prénom , Depuis FROM Personnes
WHERE Depuis >= ANY ( SELECT Depuis FROM Personnes
WHERE nom = 'Larrouy' AND Prénom ='Eric' )
AND NOT (nom = 'Larrouy' AND Prénom ='Eric') ;"

 Quels habitants ont une ancienneté plus élevée que ceux de l'avenue Verdun à
VANVES (92170)
ALL pour tester si toutes les valeurs satisfont la condition
sql <- "SELECT DISTINCT Nom, Prénom ,Ville, Depuis FROM Habitants
WHERE Depuis < ALL ( SELECT Depuis FROM Habitants
WHERE Adresse = 'avenue Verdun' AND Code = 92170 ) ;"

# comparer le résultat en utilisant ANY Habitants Vanves


Depuis
Exécution requête : 1 1983-05-07
sqldf (sql) 2 1985-10-21
3 1985-10-21
sqlQuery (channel, sql) 24/04/2012
UNION Pour fusionner les lignes issues de deux requêtes

Les requêtes doivent impérativement retourner des lignes de composition identique :


même champs à la même position

sql1 <- "SELECT DISTINCT Ville, Code sql2 <- "SELECT DISTINCT Ville, Code
FROM Localisation WHERE Ville LIKE 'c%' " FROM Habitants WHERE NOT Ville LIKE 'c%' ;"
sqldf(sql1) sqldf(sql2)
Ville Code Ville Code
1 CHATILLON 92320 1 VANVES 92170
2 CLAMART 92140

Faire attention au ; Ville Code


qui doit être absent de 1 CHATILLON 92320
la première requête 2 CLAMART 92140
(non obligatoire avec ACCESS) 3 VANVES 92170

Union des requêtes sql1 et sql2


sql <- paste (sql1, "UNION", sql2)
sqldf(sql)

Et avec
sql2 <- "SELECT DISTINCT Ville, Code, numéro FROM Habitants WHERE NOT Ville LIKE 'c%'"
sqlQuery(channel,sql) # [1] "[RODBC] ERROR: Could not SQLExecDirect"
sqldf(sql) # Erreur dans sqliteExecStatement 24/04/2012
INTERSECT
Sélection des lignes communes aux deux requêtes
S'utilise comme UNION

sql1 <- "SELECT Ville, Code FROM Localisation" sql2 <- "SELECT Ville, Code FROM Comm2"
sqldf(sql1) sqldf(sql2)

Intersection des requêtes sql1 et sql2


sql <- paste(sql1,"INTERSECT",sql2)
sqldf (sql)

Ville Code Ville Code


1 VANVES 92170 1 CHATILLON 92320
2 CHATILLON 92320 2 CLAMART 92140
3 CLAMART 92140 3 MALAKOFF 92240
Ville Code
1 CHATILLON 92320
2 CLAMART 92140

sqlQuery(channel,sql) # [1] "[RODBC] ERROR


 Utiliser des requêtes imbriquées
Si non implémenté dans le SQBDR
 Utiliser des jointures ... 24/04/2012
INTERSECT Si non implémenté dans le SQBDR
Comment faire ?

 En utilisant des jointures

sql <- "SELECT L.Ville, L.Code FROM Localisation L, Comm2 C


WHERE L.Ville = C.Ville AND L.Code = C.Code ;"

Exécution requête :
 Utiliser des requêtes imbriquées sqldf (sql)
sqlQuery (channel, sql)

sql <- "SELECT * FROM Comm2 C


WHERE EXISTS (SELECT * FROM Localisation L
WHERE L.Ville = C.Ville AND L.Code = C.Code) ;"
De même :
sql <- "SELECT L.Ville, L.Code FROM Localisation L
WHERE EXISTS (SELECT * FROM Comm2 C
WHERE L.Ville = C.Ville AND L.Code = C.Code) ;"

24/04/2012
EXCEPT
Sélection des lignes différentes d'une requête par rapport à l'autre
S'utilise comme UNION
sql1 <- "SELECT Ville, Code FROM Localisation" sql2 <- "SELECT Ville, Code FROM Comm2"
sqldf(sql1) sqldf(sql2)

Ville Code Ville Code


1 VANVES 92170 1 CHATILLON 92320
2 CHATILLON 92320 2 CLAMART 92140
3 CLAMART 92140 3 MALAKOFF 92240

Lignes de sql1 non dans sql2 Lignes de sql2 non dans sql1
sql <- paste(sql1,"EXCEPT",sql2) sql <- paste(sql2,"EXCEPT",sql1)
sqldf (sql) sqldf (sql)
Ville Code Ville Code
1 VANVES 92170 1 MALAKOFF 92240

sqlQuery(channel,sql) # [1] "[RODBC] ERROR


 Utiliser des requêtes imbriquées
Si non implémenté dans le SQBDR
 Utiliser des jointures ... 24/04/2012
EXCEPT Si non implémenté dans le SQBDR
Comment faire ?
 En utilisant des jointures
# Communes de Localisation non présentent dans Comm2
sql1 <- "SELECT L.Ville, L.Code FROM Localisation L LEFT JOIN Comm2 C
ON L.Ville = C.Ville AND L.Code = C.Code WHERE C.Code IS NULL ;"
Ville Code
1 VANVES 92170 Avec LEFT JOIN
# Communes de Comm2 non présentent dans Localisation
sql2 <- "SELECT C.Ville, C.Code FROM Comm2 C LEFT JOIN Localisation L
ON L.Ville = C.Ville AND L.Code = C.Code WHERE L.Code IS NULL ;"
Ville Code
1 MALAKOFF 92240 Exécution requête :
sqldf (sql1)
 En utilisant des requêtes imbriquées sqlQuery (channel, sql1)
# Communes de Localisation non présentent dans Comm2
sql1 <- "SELECT L.Ville, L.Code FROM Localisation L WHERE NOT EXISTS (SELECT * FROM Comm2 C
WHERE L.Ville = C.Ville AND L.Code = C.Code);"
Ville Code
1 VANVES 92170
# Communes de Comm2 non présentent dans Localisation
sql2 <- "SELECT * FROM Comm2 C WHERE NOT EXISTS (SELECT * FROM Localisation L
WHERE L.Ville = C.Ville AND L.Code = C.Code);"
id Ville Code
1 3 MALAKOFF 92240
sqldf(paste(sql1, "UNION", sql2))
24/04/2012
Commande DELETE
pour supprimer des lignes d'une table
Syntaxe
Légende :
DELETE * FROM table [alias] { } : Une des valeurs
séparées par '|'
[ WHERE { conditions de recherche | sous conditions} ] ; obligatoire.
[ ] : Valeur optionnelle.
# Création de la table de travail Personne2
Personnes <- sqlQuery(channel,"SELECT * FROM Personnes;")
sqlSave(channel, Personnes[,-7],"Personne2",rownames=FALSE)
sqlQuery(channel,"SELECT * FROM Personne2;")
Exemples
 Suppression dans la table Personne2 des lignes où le champ Téléphone est nul
sql <- "DELETE * FROM Personne2 WHERE Téléphone IS NULL"
 Suppression de toutes les lignes de la table Personne2 Exécution requête :
sql <- "DELETE * FROM Personne2 sqlQuery (channel, sql)

Remarque : la définition de la table est conservée


# Vérification
sqlQuery (channel, "SELECT * FROM Personne2;")
24/04/2012
Commande INSERT
pour insérer des lignes dans une table
Syntaxe INSERT INTO table [ (col [, col ] ...)] Légende :
{ } : Une des valeurs
{ VALUES ( val [, val ] ...) | SELECT } séparées par '|'
obligatoire.
[ ] : Valeur optionnelle
... : Répétition
Exemple
 Insérer dans la table Personne2 le contenu des champs Nom, Prénom, numéro,
id_localisation, Téléphone à partir de la table Personnes pour les habitants de
Clamart.
sql <- "INSERT INTO Personne2 ( Nom, Prénom, numéro, id_localisation, Téléphone )
SELECT DISTINCT P.Nom, P.Prénom, P.numéro, P.id_localisation, P.Téléphone
FROM Localisation L, Personnes P
WHERE L.id = P.id_localisation AND L.Ville='CLAMART' ;"

Exécution requête :
sqlQuery (channel, sql)
# Vérification
sqlQuery (channel, "SELECT * FROM Personne2;") # Que remarque-t-on et pourquoi ?

(afficher Habitants) 24/04/2012


Commande UPDATE
pour modifier le contenu des champs d'une table
Syntaxe
Légende :
UPDATE table [alias] [ INNER JOIN . ON ] { } : Une des valeurs
SET { col = expr [, col = expr ] ... | ( col [, col ] ... ) = ( SELECT ) } séparées par '|'
[ WHERE conditions de recherche ] obligatoire.
[ ] : Valeur optionnelle
... : Répétition
Exemples
 Mettre 999 dans le champ id de la table Personne2 pour Foucher
sql <- "UPDATE Personne2 SET id = '999' WHERE Nom ='Foucher' "

 Mettre à jour le champ id de la table Personne2 à partir de la table Personnes.


sql <- "UPDATE Personne2 INNER JOIN Personnes ON
(Personne2.Téléphone = Personnes.Téléphone)
AND (Personne2.Prénom = Personnes.Prénom)
AND (Personne2.Nom = Personnes.Nom)
SET Personne2.id = Personnes.id ;"
Exécution requête :
sqlQuery (channel, sql)
# Vérification
sqlQuery (channel, "SELECT * FROM Personne2;") (afficher Habitants) 24/04/2012
Commande CREATE TABLE DDL
pour créer une table
Syntaxe
CREATE TABLE table ( col datatype [DEFAULT expr] [constraint] [
, col datatype [DEFAULT expr] [constraint] ... ] )
Légende :
Exemple [ ] : Valeur optionnelle
... : Répétition
 Créer la table New avec deux colonnes

sql <- "CREATE TABLE New (col1 varchar(20), col2 integer) ;"

sqlQuery (channel,sql)
Exécution requête :
# Vérification sqlQuery (channel, sql)
sqlColumns (channel, "New")[, 3:7]

TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE


1 New col1 12 VARCHAR 20
2 New col2 4 INTEGER 10

24/04/2012
Commande DROP TABLE DDL
pour supprimer une table
Syntaxe
DROP TABLE table # Lister le nom des tables de la base
sqlTables (channel)$TABLE_NAME [-c(1:6)]

Exemple
 Supprimer les tables New et Personne2

sql <- "DROP TABLE New ;"

sql <- "DROP TABLE Personne2 ;" Exécution requête :


sqlQuery (channel, sql)

# Vérification
sqlTables(channel)$TABLE_NAME[-c(1:6)]

24/04/2012
Exercice
 Créer une table "communes" à partir de la table "localisation" avec uniquement les
communes CHATILLON et CLAMART et en y ajoutant MALAKOFF (92240).
La table commune n'a que les champs "Ville" et "Code".

24/04/2012
Exercice
 Créer une table "communes" à partir de la table "localisation" avec uniquement les
communes CHATILLON et CLAMART et en y ajoutant MALAKOFF (92240).
La table commune n'a que les champs "Ville" et "Code".
# 1 - Création de la table comex à partir d'un SELECT
sql <- "SELECT DISTINCT Ville, Code FROM Localisation WHERE Ville LIKE 'c%';"
sqlCopy(channel, sql, "comex",rownames="id", addPK=TRUE) # par défaut, dans la base
sqlQuery(channel,"SELECT * FROM comex ;") # Vérification
# 2 - Création du data.frame avec la nouvelle commune à ajouter
newcom <- as.data.frame(cbind("MALAKOFF","92240"))
str(newcom ) # Problèmes : factor
newcom [,1] <- as.character(newcom[,1])
newcom [,2] <- as.integer(as.character(newcom[,2]))
# Obligatoire :
colnames(newcom) <- c("Ville","Code") # noms champs de la table
rownames(newcom) <- "3" # bonne valeur de l'index ("id")
# 3 - Ajout du data.frame à la table
sqlSave(channel, newcom ,tablename ="comex",
rownames = "id", addPK = TRUE, append = TRUE)
# Vérification
sqlQuery(channel,"SELECT * FROM comex ;")
24/04/2012