====== Requêtes SQL ====== ====== SELECT ====== SELECT champ1, champ2 FROM table WHERE condition ORDER BY champ1 ASC, champ2 DESC; Doc : [[http://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_10002.htm#i2129937|Oracle]] ===== Gérer valeur NULL ===== Utiliser la fonction standard COALESCE : -- Téléphone fixe, ou mobile sinon SELECT COALESCE (cli.telephonefixe, cli.telephonemobile) AS telephone FROM clients Doc : [[https://en.wikibooks.org/wiki/Structured_Query_Language/SELECT:_IS_NULL_Predicate#Coalesce()_and_Similar_Functions|Wikibooks]], [[https://docs.microsoft.com/fr-fr/sql/t-sql/language-elements/coalesce-transact-sql|MS SQL]] Chez Oracle il existe aussi une fonction non standard Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm|NVL]] ===== Switch Case ===== SELECT CASE WHEN prix<10 THEN 'Moins de 10 €' WHEN prix<20 THEN 'Entre 10 € et 20 €' WHEN prix<40 THEN 'Entre 20 € et 40 €' ELSE 'Plus de 40 €' END FROM produits; Doc : [[http://docs.oracle.com/cd/B13789_01/server.101/b10759/expressions004.htm|Oracle]] ===== Portion de chaîne ===== **Oracle :** SELECT -- Ne garder que les 3e et 4e caractères du code SUBSTR(codecoloris, 3, 2) AS ancien_coloris, FROM produits_coloris Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions162.htm|Oracle]] **MS SQL Server :** SELECT -- Séparer heures et minutes SUBSTRING (a.actvissalheurearr, 1, 2) + ':' + SUBSTRING (a.actvissalheurearr, 3, 2) AS "Heure" FROM ACTEVISITESALARIE a Doc : https://docs.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql?view=sql-server-ver15 Pour le faire selon une expression régulière : [[http://docs.oracle.com/cd/B14117_01/server.101/b10759/functions116.htm|REGEXP_SUBSTR chez Oracle]], [[http://www.postgresql.org/docs/9.1/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP|SUBSTRING w/ POSIX Regular Expressions chez PostgreSQL]] Portion avant et après un caractères séparateur : SELECT SUBSTR(pam.codeelementligne, 0 , INSTR(pam.codeelementligne, '|', 1, 1)-1), SUBSTR(pam.codeelementligne, INSTR(pam.codeelementligne, '|', 1, 1)+1, LENGTH(pam.codeelementligne)) FROM xanaka.lignes_perimetre_action_mkt pam ===== Transtypages ===== ==== Nombre -> texte ==== Fonctions CAST ou TO_CHAR SELECT CAST(nombre AS VARCHAR2(255)) AS idtexte, FROM latable SELECT TO_CHAR(nombre, 'FM990.09') AS idtexte, FROM latable -- 139,95 -> 139.95 -- 7 -> 7.0 Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions016.htm#i1269136|Oracle CAST]] ou [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions181.htm|TO_CHAR]] ==== Date -> texte ==== === Oracle === SELECT TO_CHAR(jour, 'dd/mm/yyyy HH24:MI') FROM latable -- Donne par exemple : '04/07/2012 13:37' Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions180.htm#i1009324|Oracle]] et [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#sthref419|formats]] === MySQL === select DATE_FORMAT(d.date_der_exe,'%Y%m%d%H%i%S') from latable -- Donne par exemple : '20160719010041 Doc : [[https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format|MySQL]] === MS SQL Server === select CONVERT(varchar, LOGDate, 103) from latable -- Donne par exemple : '28/03/2020' Doc : [[https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15#date-and-time-styles|CAST and CONVERT (Transact-SQL)]] ==== Date -> numéro de semaine ==== SELECT jour, TO_CHAR(jour, 'iw') FROM latable -- Donne par exemple : 2015-04-28 => 18 ==== DateTime -> Date ==== === Microsoft SQL Server === SELECT cast([DateTime] As Date) AS jour FROM table Source : https://stackoverflow.com/a/923322 ==== Texte -> date ==== === Oracle === Fonction TO_DATE SELECT * FROM latable WHERE datedebut = TO_DATE('2012-02-15', 'yyyy-mm-dd') Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm#i1003589|Oracle]] === Microsoft SQL Server === CAST('17/07/2019 00:00:00' AS date) SELECT * FROM latable WHERE TOTAL_DATE = CAST('17/07/2019 00:00:00' AS date) Ou en précisant le format : SELECT * FROM latable WHERE date = CONVERT(date, '20210825', 112) Doc : https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017#g-using-cast-and-convert-with-datetime-data === MySQL === SELECT STR_TO_DATE("2022/03/25", "%Y/%m/%d") Doc : [[https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date| STR_TO_DATE(str,format)]] et [[https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format|formats]] ===== IN ===== SELECT * FROM clients WHERE email IN ('test1@example.com', 'test2@example.org', 'test3@example.net') Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/conditions013.htm#i1050801|Oracle]] ==== Avec dédoublonnage ==== S'il y a plusieurs comptes pour un email, n'extraire que le compte le plus récent : SELECT * FROM clients WHERE codeclient IN ( SELECT MAX(codeclient) FROM clients WHERE email IN ('test1@example.com', 'test2@example.org', 'test3@example.net') GROUP BY email ); ===== Agrégation ===== SELECT department_id, MIN(salary), MAX(salary) FROM employees GROUP BY department_id; Doc : [[http://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_10002.htm#i2066419|Oracle]] ===== Plus petite valeur entre 2 colonnes ===== SELECT LEAST(prd.datemodification, art.datemodification) FROM articles art LEFT JOIN produits prd ON art.codeproduit = prd.codeproduit Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions075.htm|Oracle]] ===== Plus grande valeur entre 2 colonnes ===== SELECT GREATEST(stk.stock, 0) AS stock, FROM stock stk Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions060.htm|Oracle]] Pour la plus petite valeur, utiliser la fonction ''LEAST'' SELECT LEAST(datemodification, datecreation) FROM matable Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions075.htm|Oracle 10g]] ===== Plus grande valeur entre plusieurs lignes ===== Par exemple, ne garder d'une table que la ligne la plus récente pour chacun des utilisateurs... WITH nom_alias AS ( SELECT * , ROW_NUMBER() OVER(PARTITION BY userid ORDER BY datecreation DESC) AS position FROM table_a_filtrer ) SELECT ... FROM nom_alias f INNER JOIN ... WHERE f.position = 1 -- uniquement dernier document AND ... ORDER BY ... ====== INSERT ====== INSERT INTO employees (employee_id, last_name, email, hire_date, job_id, salary, commission_pct) VALUES (207, 'Gregory', 'pgregory@oracle.com', sysdate, 'PU_CLERK', 1.2E3, NULL); Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9014.htm|Oracle]] ===== Depuis une sous-requête ===== Si la table existe déjà, sinon utiliser [[#creer_table_a_partir_d_une_requete]] INSERT INTO bonuses SELECT employee_id, salary*1.1 FROM employees WHERE commission_pct > 0.25; Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9014.htm#i2126076|Oracle]] ===== Plusieurs enregistrements en une requête ===== INSERT ALL INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3') INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3') INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3') . . . SELECT 1 FROM DUAL; ====== UPDATE ====== UPDATE unetable SET champ = valeur WHERE champ = valeur Plusieurs champs, depuis une sous-requête : UPDATE tableA a SET (champA1, champA2) = (SELECT champB1, champB2 FROM tableB b WHERE a.bid = b.id) WHERE bid = 123; Doc : [[http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10007.htm#i2189756|Oracle]] ===== Remplacer caractères ===== Remplacer les points-virgules par des points dans une chaîne de caractères : UPDATE unetable SET champ = REPLACE(champ , ';', '.') WHERE champ LIKE '%;%' Doc : [[http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions153.htm#SQLRF00697|Oracle]] ====== DELETE ====== DELETE FROM bonus WHERE sales_amt < quota; Doc : [[http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems014.htm|Oracle]] ===== Avec jointures ===== Avec Oracle, impossible d'utiliser des jointures comme habituellement. Voici la syntaxe à utilise : DELETE FROM refint.ecom_cmd_lignes_int l WHERE EXISTS ( SELECT 1 FROM refint.ecom_cmd_entete_int t WHERE t.num_commande = l.num_commande AND t.idlot = l.idlot AND t.etat_integration IS NULL ) -- Pour supprimer les lignes suivantes : SELECT * FROM refint.ecom_cmd_lignes_int l INNER JOIN refint.ecom_cmd_entete_int t ON t.num_commande = l.num_commande AND t.idlot = l.idlot WHERE t.etat_integration IS NULL ====== CREATE TABLE ====== ===== Clé primaire composée ===== CREATE TABLE tmp_photos_articles ( codeinternearticle NUMBER(8), numvue NUMBER(1), cheminphoto varchar2(128), CONSTRAINT tmp_photos_articles_pk PRIMARY KEY (codeinternearticle, numvue) ); Doc : [[http://docs.oracle.com/cd/B14117_01/server.101/b10759/statements_7002.htm|Oracle]] ===== Créer table à partir d'une requête ===== Testé avec postgresql 9 et Oracle 10g : CREATE TABLE nom_table AS SELECT champ1 AS nom_colonne1, champ2 AS nom_colonne2, champ3 AS nom_colonne3 FROM tables_source WHERE ... Doc : [[http://www.postgresql.org/docs/9.0/static/sql-createtableas.html|PostgreSQL]] Testé avec M$ SQL Server : SELECT * INTO destination FROM source; Doc : https://learn.microsoft.com/en-us/sql/t-sql/queries/select-into-clause-transact-sql ====== ALTER TABLE ====== ALTER TABLE nom_table ADD (nouveau1 NUMBER(6,0) DEFAULT 10267 NOT NULL, nouveau2 VARCHAR2(3) ); ====== MSSQL : lier un utilisateur à une connexion ====== USE NomDelaBase GO ALTER USER Utilisateur WITH LOGIN = Connexion GO ====== MSSQL : copier des tables d'un schéma à un autre ====== > Use the Generate Scripts Wizard in SSMS for generating the script for constraints and indexes. > >Follow these steps: > >1. Open SSMS >2. Expand databases and select the database->tasks->generate scripts to launch the GSW >3. click next and set "Script Check Constraints" to true, "Script Indexes " to true, "ScriptDependencies" to true and set whatever is needed. >4. Select the tables for which the script is needed >5. Click next ->next->finish > >This generates the script for table with indexes, constraints etc. > >More information: http://msdn.microsoft.com/en-us/library/ms178078.aspx Source : https://social.msdn.microsoft.com/Forums/en-US/17a16dc4-dcf1-4de8-baba-6949c55a4c5d/copy-constraints-and-indexes-from-one-database-to-another?forum=transactsql ====== MSSQL : trouver les verrous sur une table ====== SELECT object_name(object_id) AS objet_bloque, lock.resource_type, db.name AS db_name, lock.resource_associated_entity_id, lock.request_mode, lock.request_session_id, task.blocking_session_id, task.* FROM sys.dm_tran_locks lock INNER JOIN sys.partitions p ON p.hobt_id= lock.resource_associated_entity_id INNER JOIN sys.databases db ON db.database_id = lock.resource_database_id LEFT JOIN sys.dm_os_waiting_tasks as task ON lock.lock_owner_address = task.resource_address LEFT JOIN sys.dm_os_tasks AS STasks ON STasks.task_address = task.waiting_task_address WHERE resource_database_id = 20 AND object_name(object_id) = 'NOM_DE_LA_TABLE' ====== Documentations ====== * PostgreSQL 9.1 : http://docs.postgresql.fr/9.1/ * Oracle * 11g : https://docs.oracle.com/cd/E11882_01/server.112/e41084/toc.htm * 10g : https://docs.oracle.com/cd/B19306_01/server.102/b14200/toc.htm * Microsoft SQL Server : * 2017 : https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-2017