<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4047108984287742759</id><updated>2011-08-26T05:40:55.581-07:00</updated><title type='text'>Ejemplos de lenguaje sql para Access</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sqlraipon.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-3167393690967063710</id><published>2010-11-28T10:21:00.000-08:00</published><updated>2010-11-30T22:48:15.551-08:00</updated><title type='text'>NUEVA VERSION EDITOR SQL</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_ZmDkMzR6eqc/TPXtk0RgchI/AAAAAAAAAAk/KjX8sgA9cBA/s1600/Ajuda8.jpg"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 320px; FLOAT: left; HEIGHT: 246px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5545599732939780626" border="0" alt="" src="http://3.bp.blogspot.com/_ZmDkMzR6eqc/TPXtk0RgchI/AAAAAAAAAAk/KjX8sgA9cBA/s320/Ajuda8.jpg" /&gt;&lt;/a&gt;El título lo dice todo, hoy publico una nueva versión : &lt;a href="http://cid-074ad160daa33b17.office.live.com/self.aspx/Pu"&gt;Editor Sql 1.4&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;La principal novedad es que se ha mejorado la compatibilidad con las nuevas versiones de Access. Se puede utilizar con Access 2000, 2002, 2003, 2007 y 2010.&lt;br /&gt;&lt;br /&gt;Espero que os sea útil.&lt;br /&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;a href="http://3.bp.blogspot.com/_ZmDkMzR6eqc/TPXvAqn5zQI/AAAAAAAAAAs/aLpbO_Y49p8/s1600/Ajuda9.jpg"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 320px; FLOAT: left; HEIGHT: 246px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5545601310897327362" border="0" alt="" src="http://3.bp.blogspot.com/_ZmDkMzR6eqc/TPXvAqn5zQI/AAAAAAAAAAs/aLpbO_Y49p8/s320/Ajuda9.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Ramon Poch, raipon. Terrassa a 28/11/2010.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-3167393690967063710?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3167393690967063710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3167393690967063710'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2010/11/nueva-version-editor-sql.html' title='NUEVA VERSION EDITOR SQL'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ZmDkMzR6eqc/TPXtk0RgchI/AAAAAAAAAAk/KjX8sgA9cBA/s72-c/Ajuda8.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-2833386816458709276</id><published>2010-05-10T07:11:00.000-07:00</published><updated>2010-05-10T07:38:43.543-07:00</updated><title type='text'>JUGANDO CON LAS MATES (NÚMEROS PRIMOS)</title><content type='html'>Un pequeño divertimento : generar una tabla de números primos (de 0 a 1000) usando la tabla auxiliar Nums (con un único campo, entero, indexado -sin duplicados-, de nombre Num, con valores de 1 a 1000).&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Nums.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; T.Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T &lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Nums.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; T.Num Between 1 &lt;span style="color:#999999;"&gt;And&lt;/span&gt; 1000&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; Nums.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; T.Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Having&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(Nums.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; T.Num)&lt;span style="color:#999999;"&gt;=&lt;/span&gt;2;&lt;br /&gt;&lt;br /&gt;... y si queremos prescindir de la tabla Nums :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; R1.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; R2.Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (T2.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (T1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 6 &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 3&lt;br /&gt;)&lt;span style="color:#3333ff;"&gt; As&lt;/span&gt; Nums,&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Wher&lt;/span&gt;e Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Betwee&lt;/span&gt;n 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 6&lt;span style="color:#3333ff;"&gt; AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 3&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;T1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; R1,&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (T2.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (T1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;Id&lt;span style="color:#999999;"&gt; +&lt;/span&gt; 6 &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 3&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Nums,&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 5&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 6 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 3&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;R2&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; R1.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; R2.Num &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; 1000&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; R1.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; R2.Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;HAVING&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(R1.Num &lt;span style="color:#999999;"&gt;*&lt;/span&gt; R2.Num)&lt;span style="color:#999999;"&gt;=&lt;/span&gt;2&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 10/05/2010.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-2833386816458709276?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/2833386816458709276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/2833386816458709276'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2010/05/jugando-con-las-mates-numeros-primos.html' title='JUGANDO CON LAS MATES (NÚMEROS PRIMOS)'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5442800269387151229</id><published>2009-11-04T09:04:00.000-08:00</published><updated>2009-11-21T11:17:01.822-08:00</updated><title type='text'>EMULANDO AUTONUMERICOS</title><content type='html'>&lt;span style="color:#000000;"&gt;Un tema recurrente : generar una secuencia numérica correlativa, sin discontinuidades y a prueba de errores, para asignar valores a nuevos registros, al estilo de los autonuméricos, pero sin los inconvenientes de estos.&lt;br /&gt;Ciertamente hay variedad de recetas para abordar este problema, pero la piedra de toque de todos ellos es su empleo en sistemas con elevada concurrencia de usuarios y que dicho sistema sea también efectivo dentro de una instrucción sql (y que permita por tanto un insert masivo). Personalmente siempre he usado transacciones (ADO) para asegurar que la lectura del posible nuevo valor, quede bloqueado (para nuevas lecturas) hasta que finalice el proceso de adjudicación del mismo. Esta vez propongo utilizar efectivamente transacciones, pero de forma implícita dentro de una instrucción sql. Esto, en un SGDB como Sql Server es bien simple, pues todas las instrucciones contenidas en un procedimiento almacenado, utilizan la misma transacción, de tal forma que un error de ejecución de una de ellas, trunca todo el procedimiento. Pero en Access, puesto que su lenguaje sql no admite lotes de instrucciones (solo podemos ejecutar/llamar comandos de uno en uno), esto no es posible, a no ser que seamos capaces en una sola sentencia de obtener un nuevo valor, actualizar la tabla y recuperar el valor escrito (hay que tener en cuenta que, una de las características de los autonuméricos es devolver el nuevo valor insertado).&lt;br /&gt;Pongamos un ejemplo : Generar un nuevo número de factura. Para ello disponemos de un formulario para introducir la información de la cabecera del documento : Fecha, Cliente, Tarifa, etc, y un subformulario para los detalles de la misma. Una solución simple y clásica es obtener el mayor valor concedido al campo numerador mediante un Select Max() e incrementar en uno dicho dato ... Pero este sistema, desarrolla toda su lógica en el lado cliente y presenta inconvenientes evidentes en un entorno multiusuario. La solución que propongo consiste en tener dos tablas auxiliares, una en el 'lado datos' y otra en el 'lado cliente'. El objetivo es almacenar el último valor generado absoluto, y el relativo en cada máquina cliente. Ambas tablas deben estar accesibles en la base de datos donde ejecutemos el código : una como tabla local, y la otra (por ejemplo) como tabla vinculada.&lt;br /&gt;Recapitulemos : Tenemos en una base de datos (de servidor) una tabla Facturas, y una tabla Numeradores que contiene el último número de factura generado. Cuando necesitemos generar un nuevo documento solo tenemos que ejecutar esta instrucción sql :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Update&lt;/span&gt; Numeradores &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Facturas &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; 1&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;=&lt;/span&gt; T.NFactura&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1,&lt;br /&gt;Facturas.NFactura &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Numeradores.Numerador,&lt;br /&gt;Facturas.Fecha &lt;span style="color:#999999;"&gt;=&lt;/span&gt; #12/31/2009#,&lt;br /&gt;Facturas.Cliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 100,&lt;br /&gt;Facturas.Tarifa &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 1;&lt;br /&gt;&lt;br /&gt;Condiciones previas : Numeradores debe contener un solo registro con valor 1 (valor inicial del autonumérico).&lt;br /&gt;Dado que hemos relacionado de forma asimétrica ambas tablas, aún cuando la segunda tabla (en este caso una Select sobre Facturas) no devuelve resultados, puesto que hemos añadido la condición 1=0, la instrucción update (a efectos prácticos no es un update, sino un insert) afectará a tantos registros como haya en la tabla numeradores, es decir : uno. Al ejecutarse la sentencia, el valor del numerador se incrementa en 1 (no olvidemos que se trata de una instrucción update), en segundo lugar, el nuevo numerador generado se asigna al campo Nfactura de la tabla Facturas, pero dado que no hay ningún registro presente (en la consulta) de la tabla Facturas (hemos filtrado los resultados con esta condición imposible : 1=0), en realidad estamos insertando un nuevo registro en la tabla, y finalmente se actualizan el resto de los campos de Facturas con los valores incluidos en la instrucción sql.&lt;br /&gt;&lt;br /&gt;Vamos a hablar de la tabla local de numeradores a la que previamente haciamos referencia. Supongamos que necesitamos agregar registros de uno en uno desde un formulario, y que vamos a introducir desde el propio formulario los datos en cada uno de los campos de la tabla Facturas : Fecha, Cliente, Tarifa, etc. Así pues, necesitamos generar un nuevo registro en dicha tabla, y recuperar automáticamente dicho registro para poder trabajar con él. ¿ En un escenario multiusuario con acceso concurrente a la tabla Facturas, si insertamos una nueva línea, como podemos estar seguros de recuperar el registro que nosotros hemos generado y no otro ? … cabe pensar en la posibilidad que escasos instantes despues de insertar el registro y antes de recuperarlo, otro usuario ha añadido otra línea en la tabla … Si utilizamos Max(NFactura) o leemos el valor de la tabla Numeradores, no nos sirve, puesto que el inoportuno usuario ha modificado también ambos campos …&lt;br /&gt;&lt;br /&gt;La panacea a este dilema es incorporar una tabla de Numeradores local (o cliente) además de la tabla Numeradores del servidor que hasta ahora hemos ido usando en nuestra instrucción sql. Se trata de guardar en la tabla local el último Numerador asignado, y puesto que dicha tabla solo se modifica desde la aplicación cliente donde corre el código, tenemos la certeza de que el valor guardado en ella corresponde al último registro asignado por nosotros :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Update&lt;/span&gt; (&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; NumeradorServer,&lt;br /&gt;Numeradores_locales.Numerador &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; NumeradorLocal&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Numeradores&lt;br /&gt;&lt;span style="color:#999999;"&gt;Inner Join&lt;/span&gt;&lt;br /&gt;Numeradores_locales&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;&gt;= &lt;/span&gt;Numeradores_locales.Numerador) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; N&lt;br /&gt;&lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Facturas &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; 1&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; N.NumeradorServer &lt;span style="color:#999999;"&gt;=&lt;/span&gt; T.NFactura&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; N.NumeradorServer &lt;span style="color:#999999;"&gt;=&lt;/span&gt; N.NumeradorServer &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1,&lt;br /&gt;N.NumeradorLocal &lt;span style="color:#999999;"&gt;=&lt;/span&gt; N.NumeradorServer,&lt;br /&gt;Facturas.NFactura &lt;span style="color:#999999;"&gt;=&lt;/span&gt; N.NumeradorServer,&lt;br /&gt;Facturas.Fecha &lt;span style="color:#999999;"&gt;=&lt;/span&gt; #12/31/2009#,&lt;br /&gt;Facturas.Cliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 100, &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;Facturas.Tarifa &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 1;&lt;br /&gt;&lt;br /&gt;Para recuperar el último valor insertado (por nosotros) en la tabla Facturas :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Facturas.&lt;/span&gt;&lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Facturas&lt;br /&gt;&lt;span style="color:#999999;"&gt;Inner Join&lt;/span&gt; Numeradores_locales&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Facturas.NFactura &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Numeradores_locales.Numerador&lt;br /&gt;&lt;br /&gt;Pero … ¿ Solo puedo añadir registros de uno en uno ? …&lt;br /&gt;&lt;br /&gt;No. Supongamos que tenemos que insertar un conjunto de registros en la tabla Facturas, estos registros los obtiene una consulta llamada Nuevas_Facturas. Dicha consulta debe tener los campos que nos interesa grabar en Facturas, y además, un campo para relacionarlo con Facturas.Nfactura y Numeradores.Numerador. El valor de dicho campo ha de ser tal, que sea imposible que coincida en cualquiera de ambas tablas. Si hemos empezado la numeración de documentos a partir de 1, un valor aceptable para este propósito seria -1.&lt;br /&gt;Y esta es la sql a ejecutar :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Update&lt;/span&gt; (Numeradores&lt;br /&gt;&lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt;&lt;br /&gt;Nuevas_facturas&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;&lt;&gt;&lt;/span&gt; Nuevas_facturas.NFactura)&lt;br /&gt;&lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt;&lt;br /&gt;Facturas &lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Facturas.NFactura &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Nuevas_facturas.NFactura&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Numeradores.Numerador &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1,&lt;br /&gt;Facturas.NFactura &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Numeradores.Numerador,&lt;br /&gt;Facturas.Fecha &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Nuevas_facturas.Fecha,&lt;br /&gt;Facturas.Cliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Nuevas_facturas.Cliente,&lt;br /&gt;Facturas.Tarifa &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Nuevas_facturas.Tarifa;&lt;br /&gt;&lt;br /&gt;… con ello añadiremos tantos registros en la tabla Facturas como nos devuelva la consulta Nuevas_Facturas.&lt;br /&gt;En líneas anteriores comentaba la necesidad de que si alguna de las modificaciones en tabla, de alguno de los registros, fallara, se truncará todo el proceso. Podemos comprobar (manipulando la tabla Numeradores para producir duplicados en el campo clave Nfactura), que caso de haber un error, todo el proceso queda abortado, permaneciendo intactas ambas tablas.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;Ramon Poch, raipon. Terrassa a 04/11/2009.&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5442800269387151229?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5442800269387151229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5442800269387151229'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/11/emulando-autonumericos.html' title='EMULANDO AUTONUMERICOS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-982101868192688774</id><published>2009-07-09T01:06:00.001-07:00</published><updated>2009-07-09T01:17:41.773-07:00</updated><title type='text'>REVISION DE FORMULARIOS DESCONECTADOS</title><content type='html'>Hola, he revisado y actualizado el código de &lt;a href="http://sqlraipon.blogspot.com/2009/02/formularios-desconectados.html"&gt;Formularios desconectados.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-982101868192688774?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/982101868192688774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/982101868192688774'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/07/revision-de-formularios-desconectados.html' title='REVISION DE FORMULARIOS DESCONECTADOS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5199935147976712867</id><published>2009-03-01T01:00:00.000-08:00</published><updated>2009-07-11T10:10:14.422-07:00</updated><title type='text'>SERIES NUMÉRICAS (SIN TABLA NUMS)</title><content type='html'>El 23 de Abril de 2008, publiqué este artículo : &lt;a href="http://sqlraipon.blogspot.com/2008/04/series-numricas.html"&gt;http://sqlraipon.blogspot.com/2008/04/series-numricas.html&lt;/a&gt;, donde se explica como obtener, una consulta con una secuencia de números continua (de 1 a 100, de 1 a 1000, etc) a partir de una tabla ('Nums') con solo 10 registros. Dichas consultas resultan de gran utilidad y las he empleado en muchos de los ejemplos de este blog.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pues bien, es posible obtener los mismos resultados sin necesidad de la tabla 'Nums' :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Para bases de datos con formato Access 2000 :&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#33cc00;"&gt;-- En una base de datos nueva, en la que todavia no se haya creado&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- ningún objeto, la tabla del sistema MSysAccessObjects contiene &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- 4 registros, con valores de 0 a 3 en el campo Id. &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Es de resaltar, que en esta tabla jamás se elimina ningún registro,&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- cuando menos, la serie de valores del campo Id nunca presenta&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- discontinuidades.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Por tanto, esta consulta de unión nos asegura una serie numérica &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de 10 líneas con valores entre 0 y 9, sea cual sea el estado de la&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- base de datos (nueva o con múltiples objetos).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#3333ff;"&gt;As &lt;/span&gt;Num &lt;span style="color:#3333ff;"&gt;F&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;rom&lt;/span&gt; MSysAccessObjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;&lt;= &lt;/span&gt;3&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 4 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MSysAccessObjects&lt;span style="color:#3333ff;"&gt; Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt;3&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id + 8 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MSysAccessObjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;&lt;&lt;/span&gt; 2;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Para bases de datos en formato 2003 o 2007. Hay que tener en cuenta que la &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- tabla &lt;/span&gt;&lt;span style="color:#33cc00;"&gt;MSysAccessObjects no existe, por lo tanto emplearemos otra tabla del &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- sistema (MSysObjects). Es de destacar que en una base de datos nueva, están &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- siempre&lt;/span&gt;&lt;span style="color:#33cc00;"&gt; presentes cuatro registros (entre otros) con los siguientes Id : &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- 2, 3, 4 &lt;/span&gt;&lt;span style="color:#33cc00;"&gt;y 5. Por lo &lt;/span&gt;&lt;span style="color:#33cc00;"&gt;tanto,&lt;/span&gt; &lt;span style="color:#33cc00;"&gt;esta consulta de unión nos asegura igualmente 10 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- registros,&lt;/span&gt;&lt;span style="color:#33cc00;"&gt; con valores &lt;/span&gt;&lt;span style="color:#33cc00;"&gt;de 0 a 9&lt;/span&gt; &lt;span style="color:#33cc00;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;&lt;span style="color:#000000;"&gt;Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#999999;"&gt;And&lt;/span&gt; 5 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#999999;"&gt;And&lt;/span&gt; 5&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;All&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 6 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; msysobjects &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; 2 &lt;span style="color:#999999;"&gt;And&lt;/span&gt; 3;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A partir de aquí, solo tenemos que guardar una de las dos consultas con el nombre Nums, y ya podemos emplear las consultas del enlace arriba citado sin necesidad de tener en la base de datos la tabla Nums.&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;Ramon Poch, raipon. Terrassa a 10/01/2009.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5199935147976712867?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5199935147976712867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5199935147976712867'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/03/series-numericas-sin-tabla-nums.html' title='SERIES NUMÉRICAS (SIN TABLA NUMS)'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5961501217496915125</id><published>2009-02-25T04:56:00.000-08:00</published><updated>2009-07-09T01:05:35.016-07:00</updated><title type='text'>FORMULARIOS DESCONECTADOS</title><content type='html'>Hoy no hablaré directamente de sql, si no de la posibilidad de trabajar en Access, con formularios desconectados de su orígen, al estilo de visual basic.&lt;br /&gt;No es la primera vez que abordo este tema, pero siempre tropezamos con la misma piedra : la complejidad del código necesario. Pue bién, esta vez, y gracias a la clase 'cls_desc', este será todo el código necesario en un formulario (en este caso 'Proveedores' de 'Neptuno.mdb') :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Option Explicit &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Option Compare Database&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Private&lt;/span&gt; cl &lt;span style="color:#3333ff;"&gt;As New&lt;/span&gt; cls_desc&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Private Sub&lt;/span&gt; cmdGrabar_Click()&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On Error Resume Next&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;If&lt;/span&gt; Me.Dirty &lt;span style="color:#3333ff;"&gt;Then &lt;/span&gt;&lt;br /&gt;Me.Refresh&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;If&lt;/span&gt; cl.Dirty = &lt;span style="color:#3333ff;"&gt;True Then&lt;/span&gt;   &lt;br /&gt;cl.Actualizar CurrentProject.Connection&lt;br /&gt;MsgBox "Se han realizado : " &amp;amp; cl.RecordsAffected &amp;amp; " actualizaciones."&lt;br /&gt;MsgBox "Se han producido los siguientes errores : " &amp;amp; vbCrLf &amp;amp; cl.Errores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Private Sub&lt;/span&gt; Form_Open(Cancel &lt;span style="color:#3333ff;"&gt;As Integer&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; rst &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;New&lt;/span&gt; ADODB.Recordset&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Configuramos el recordset&lt;/span&gt;&lt;br /&gt;rst.CursorLocation = adUseClient&lt;br /&gt;rst.ActiveConnection = CurrentProject.Connection&lt;br /&gt;rst.LockType = adLockBatchOptimistic&lt;br /&gt;rst.CursorType = adOpenKeyset&lt;br /&gt;rst.Source = "Proveedores"&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Abrimos el recordset&lt;/span&gt;&lt;br /&gt;rst.Open&lt;br /&gt;'Desvinculamos el recordset de su orígen&lt;br /&gt;rst.ActiveConnection = &lt;span style="color:#3333ff;"&gt;Nothing&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Asignamos rst como recordset del formulario&lt;/span&gt;&lt;br /&gt;Set Me.Recordset = rst&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Configuramos la clase&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; cl.ActiveRecordset = rst&lt;br /&gt;cl.Campo_Clave = "IdProveedor"&lt;br /&gt;cl.Unique_Table = "Proveedores"&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End Sub&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;... ¿ no es demasiado complicado verdad ?. Y sin embargo podrás editar registros, añadir nuevos, eliminar, etc. y los cambios no se reflejarán en la base de datos a no ser que llamemos al método Actualizar de la clase. Puedes ver el código del módulo de clase 'cls_desc', así como un par de formularios de ejemplo en : &lt;a class="on" href="http://raipon.googlegroups.com/web/Formularios+desconectados.zip?gda=ydT5BU8AAADg1lG8zbN60bAEVqwHLJuSYOUTevwGBhB9zRUbWLKB5NlPm9zwDUlVRUTUSOpVtHjUfbY5aJ72V6IFDJOQDWDjnHMhSp_qzSgvndaTPyHVdA&amp;amp;gsc=jvXi4QsAAAATAtRqBO-B0ilClQSJDqkb" target="_blank" rel="nofollow"&gt;Formularios desconectados.zip &lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;Por si lo anterior te ha parecido insuficiente : Esta clase, permite trabajar con un recordset obtenido de una consulta no actualizable (excepto consultas de unión). El recordset, al estar desconectado permite editar los registros, y al llamar al método Actualizar, los cambios serán volcados en la tabla definida por la propiedad Unique_Table.&lt;br /&gt;Solo debes tener en cuenta que : este tipo de formularios no toleran bién los filtros y ordenar. Por lo demás han sido probados en las siguientes versiones de Access : XP, 2003 y 2007&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 24/02/2009.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5961501217496915125?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5961501217496915125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5961501217496915125'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/02/formularios-desconectados.html' title='FORMULARIOS DESCONECTADOS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5091076005587829881</id><published>2009-02-15T00:01:00.000-08:00</published><updated>2009-02-15T00:01:01.109-08:00</updated><title type='text'>DISTINGUIR MAYÚSCULAS Y MINÚSCULAS</title><content type='html'>A raiz de una pregunta en los grupos de discusión : microsoft.public.es.access : ¿ como conseguir que un campo de texto sea sensible al uso de mayúsculas y minúsculas ?, se me ocurrió la siguiente solución :&lt;br /&gt;&lt;br /&gt;Utilizar un campo tipo binary, ya que en este contexto Access guarda los datos como bytes y no como texto. Esto no lo podemos conseguir desde la vista diseño de una tabla, pues este tipo de campo no está disponible, lo más parecido es un campo 'Objeto Ole', o lo que es lo mismo 'Long Binary', pero para este propósito no nos sirve. Para ello utilizaremos una instrucción ddl (Create Table, o Alter Table), bién desde una consulta (teniendo activada, en 'Opciones', la compatibilidad con Sql Server) o mediante el método Execute de Ado.&lt;br /&gt;&lt;br /&gt;Ejemplo :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTabla (Campo1 &lt;span style="color:#3333ff;"&gt;Binary&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'A'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'a'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'B'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;('b'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'C'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'c'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'D'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'d'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'E'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'e'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt;, &lt;span style="color:#cc33cc;"&gt;A&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;sc&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Char_code &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Order By&lt;/span&gt; Campo1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; MiTabla;&lt;br /&gt;&lt;br /&gt;Al abrir la consulta de selección, vemos como efectivamente el órden establecido corresponde al código del caracter (a pesar de ordenar por 'Campo1'), y no al valor como texto. Por tanto, Access realiza implícitamente la conversión de texto a bytes cuando guardamos datos en este campo, y al reves (de bytes a texto) cuando nos muestra el contenido del mismo.&lt;br /&gt;&lt;br /&gt;Así mismo, esta técnica, nos permite tener un campo 'de texto', indexado, de valores únicos, que distinga entre mayúsculas y minúsculas. Ejemplo para crear un campo binary indexado sin duplicados :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTabla (Campo1 &lt;span style="color:#3333ff;"&gt;Binary Unique&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;o si queremos que sea el campo clave :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTabla (Campo1 &lt;span style="color:#3333ff;"&gt;Binary Primary Key&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 31/01/2009.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5091076005587829881?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5091076005587829881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5091076005587829881'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/02/distinguir-mayusculas-y-minusculas.html' title='DISTINGUIR MAYÚSCULAS Y MINÚSCULAS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-1687935911712894674</id><published>2009-02-01T00:01:00.000-08:00</published><updated>2009-02-01T00:01:00.943-08:00</updated><title type='text'>FIRST Y LAST</title><content type='html'>Si utilizamos estas funciones en una instrucción sql que apunte directamente sobre una tabla :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTabla (Campo1 &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (100));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Hola mundo'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values &lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'Prueba first y last'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Values &lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;'Fin de la prueba'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As &lt;/span&gt;Primero, &lt;span style="color:#cc33cc;"&gt;Last&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Último&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From &lt;/span&gt;MiTabla;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; MiTabla;&lt;br /&gt;&lt;br /&gt;... vemos que los resultados son absolutamente coherentes : first devuelve el valor para dicho campo del primer registro insertado en la tabla, y viceversa ...&lt;br /&gt;Sin embargo, estos resultados no se ven afectados si establecemos un orden concreto desde la vista 'hoja de datos' de la tabla. Es decir, si desde dicha vista establecemos un orden ascendente (alfabético) para campo1, y guardamos los cambios, First sigue devolviendo 'Hola mundo' en vez de 'Fin de prueba'. ¿ Significa esto que no podemos definir otro criterio de ordenación para establecer qué valor es primero o último ?. En la ayuda de Access podemos leer :&lt;br /&gt;&lt;br /&gt;"... Devuelven simplemente el valor de un campo especificado en el primer o el último registro, respectivamente, del conjunto de resultados devueltos por una consulta. Debido a que los registros se devuelven normalmente sin un orden determinado (a no ser que la consulta incluya una cláusula ORDER BY), los registros devueltos por estas funciones son arbitrarios."&lt;br /&gt;&lt;br /&gt;... vamos a probar :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Primero, &lt;span style="color:#cc33cc;"&gt;Last&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Último&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Campo1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTabla&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Order By&lt;/span&gt; Campo1&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;... pues no, no es cierto, o no quiere decir lo que parece; nada ha cambiado. Y da igual que guardemos la consulta embebida dentro de la cláusula From como una nueva consulta, que establezcamos también el orden desde la vista 'hoja de datos' de esta nueva consulta, ... nada, ¡ es inútil !. Sencillamente : &lt;strong&gt;el orden establecido en una instrucción 'Select', no es persistente para posteriores llamadas a la misma&lt;/strong&gt;.&lt;br /&gt;Si pensamos en ello detenidamente, este comportamiento es del todo lógico, ya que el orden de los resultados solo debe ser relevante en cuanto a una mejor interpretación de los mismos, pero no para la validez de los datos devueltos. Y en cambio, ordenar los registros para cada 'Select' en una serie de llamadas entre consultas, penalizaría sin duda el rendimiento. Sin embargo hay un escenario en donde los registros devueltos pueden ser distintos según el criterio establecido en 'Order By' : ... cuando usamos la cláusula Top para restringir los resultados a un determinado número de registros. ¿ Solucionará también la cláusula Top nuestro problema ?. Efectivamente, si utilizamos dicha cláusula, el orden permanece para una posterior llamada a la consulta :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Primero, &lt;span style="color:#cc33cc;"&gt;Last&lt;/span&gt;(Campo1) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Último&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select Top&lt;/span&gt; 100 &lt;span style="color:#3333ff;"&gt;Percent&lt;/span&gt; Campo1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTabla&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Order By&lt;/span&gt; Campo1&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;... y ahora sí, el valor devuelto por First es 'Fin de la prueba' y Last : 'Prueba first y last'. Valores coherentes si ordenamos alfabéticamente 'Campo1'. &lt;strong&gt;En conclusión : siempre que utilicemos dichas funciones, si queremos resultados consistentes y fiables debemos basar la sql sobre una consulta previa que incorpore la cláusula 'Top' (a no ser que deseemos recuperar valores directamente de la tabla según el orden de inserción).&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 20/12/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-1687935911712894674?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1687935911712894674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1687935911712894674'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/02/first-y-last.html' title='FIRST Y LAST'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-3142799238841021640</id><published>2009-01-18T00:01:00.000-08:00</published><updated>2009-01-18T00:01:00.749-08:00</updated><title type='text'>DESAFIO SQL (ORDER BY). LA SOLUCIÓN</title><content type='html'>&lt;p&gt;En primer lugar, un comentario sobre las 'herramientas' a utilizar.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Para descomponer la cadena en segmentos : &lt;a href="http://sqlraipon.blogspot.com/2008/04/descomponer-lista-csv-en-registros.html"&gt;http://sqlraipon.blogspot.com/2008/04/descomponer-lista-csv-en-registros.html&lt;/a&gt; Se trata de la adaptación a Access de un ejemplo del mismo Itzik Ben-Gan.&lt;/li&gt;&lt;li&gt;Dentro del ejemplo anterior, es necesario generar una secuencia continua de números : &lt;a href="http://sqlraipon.blogspot.com/2008/04/series-numricas.html"&gt;http://sqlraipon.blogspot.com/2008/04/series-numricas.html&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Las subconsultas, son para Access un 'cuello de botella', colapsando con facilidad la ejecución de una consulta, si hay que procesar una cantidad considerable de registros. Una alternativa válida en determinados casos, consiste en incorporar, la tabla orígen de la subconsulta a la clausula From de la consulta principal, relacionando ambas tablas con un left join, mas la misma expresión utilizada en la cláusula Where de la subconsulta, para filtrar los resultados de la subconsulta a los registros relacionados de la consulta principal. Finalmente, para obtener el valor que nos devolvía la subconsulta, utilizamos una función de agregado.&lt;br /&gt;Ejemplo sobre la base de datos Neptuno.mdb (tabla Pedidos). Se trata de numerar los pedidos de cada cliente, según la fecha del pedido :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(*) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; T.IdCliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Pedidos.IdCliente&lt;br /&gt;&lt;span style="color:#999999;"&gt;And&lt;/span&gt;&lt;br /&gt;T.FechaPedido &lt;span style="color:#999999;"&gt;&lt; &lt;/span&gt;Pedidos.FechaPedido) &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; NºPedido_Cliente,&lt;br /&gt;IdPedido, IdCliente, FechaPedido&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Pedidos.IdPedido, Pedidos.IdCliente, Pedidos.FechaPedido,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(T.FechaPedido) &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; NºPedido_Cliente&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt; Pedidos &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; T.IdCliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Pedidos.IdCliente &lt;span style="color:#999999;"&gt;And&lt;/span&gt; T.FechaPedido &lt;span style="color:#999999;"&gt;&lt;&lt;/span&gt; Pedidos.FechaPedido&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; Pedidos.IdPedido, Pedidos.IdCliente, Pedidos.FechaPedido;&lt;br /&gt;&lt;br /&gt;Ambas consultas devuelven los mismos resultados, pero la segunda es 10 veces más rápida que la primera.&lt;br /&gt;Esta técnica de substitución de subconsultas la he empleado, dentro de la solución al reto, en 'Qry2' y la consulta final.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Un conjunto de valores tal, que el resultado de todas las sumas posibles sea un valor único, irrepetible, y que la suma de los elementos menores de la lista, no pueda jamás alcanzar un elemento superior. Ejemplo : una lista de potencias 2, 4, 8, 16, 32, 64, etc o 3, 9, 27, 81, 243, etc.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Y esta es la solución :&lt;/p&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;CREATE TABLE&lt;/span&gt; t1 (id &lt;span style="color:#3333ff;"&gt;identity primary key&lt;/span&gt;, f_val Memo &lt;span style="color:#999999;"&gt;not&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'100'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'7.4.250'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.100.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.99.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.99.300.478.9999999'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'10.30.40.50.20.30.40'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val)&lt;span style="color:#3333ff;"&gt; values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'7.4.250'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-1'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-2'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-11'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-22'&lt;/span&gt; );&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-123'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-321'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.-100.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.-99.300.478.19710212'&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Nums (Num &lt;span style="color:#3333ff;"&gt;Long Primary Key&lt;/span&gt;); &lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (0);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (6);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (7);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (8);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (9);&lt;/p&gt;&lt;p&gt;&lt;span style="color:#33cc00;"&gt;-- Descomponemos la cadena f_val en tantos registros como segmentos&lt;br /&gt;-- (definidos por el caracter '.' como separador) tenga.&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;CREATE PROCEDURE&lt;/span&gt; Qry1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; id,&lt;br /&gt;Num,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;CLng&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(f_val,Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;(Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,f_val &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"."&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"."&lt;/span&gt;)&lt;span style="color:#999999;"&gt;-&lt;/span&gt;Num&lt;span style="color:#999999;"&gt;-&lt;/span&gt;1))) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Valor,&lt;br /&gt;f_val&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums As TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_2, t1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; Num&lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Len&lt;/span&gt;(f_val)&lt;br /&gt;&lt;span style="color:#999999;"&gt;And&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(f_val,&lt;span style="color:#cc33cc;"&gt;IIf&lt;/span&gt;(Num&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0,1,Num),1) &lt;span style="color:#999999;"&gt;=&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"."&lt;/span&gt; &lt;span style="color:#999999;"&gt;Or&lt;/span&gt; Num&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Añadimos un campo 'Nivel' que nos indica el número de segmento&lt;br /&gt;-- dentro de la cadena&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;CREATE PROCEDURE&lt;/span&gt; Qry2 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Qry1.Id, Qry1.Valor, Qry1.f_val, &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(T.Num) &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Nivel&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Qry1 &lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt; Qry1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Qry1.Id &lt;span style="color:#999999;"&gt;=&lt;/span&gt; T.Id &lt;span style="color:#999999;"&gt;And&lt;/span&gt; Qry1.Num &lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt; T.Num&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; Qry1.Id, Qry1.Valor, Qry1.f_val, Qry1.Num;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- El campo Orden se muestra solo a efectos didácticos&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id, f_val, &lt;span style="color:#cc33cc;"&gt;Sum&lt;/span&gt;(Orden2) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Orden&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;br /&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Calculamos la siguiente potencia :&lt;br /&gt;-- El valor máximo de nivel (obtenido mediante una subconsulta)&lt;br /&gt;-- lo elevamos al Nivel (en negativo).&lt;br /&gt;-- Y dicha expresión la multiplicamos por Orden. La idea es obtener&lt;br /&gt;-- una cifra tal, que la suma de todos los valores posibles para&lt;br /&gt;-- 'niveles' más pequeños de la misma cadena, no la pueda superar.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id, f_val, Orden &lt;span style="color:#999999;"&gt;*&lt;/span&gt; ((&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Max&lt;/span&gt;(Nivel) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Qry2) &lt;span style="color:#999999;"&gt;^&lt;/span&gt; (Nivel &lt;span style="color:#999999;"&gt;* -&lt;/span&gt;1)) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Orden2&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#009900;"&gt;&lt;span style="color:#33cc00;"&gt;-- Obtenemos para cada nivel, el número de registros más pequeños&lt;br /&gt;-- según valor.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Qry2.Id, Qry2.Nivel, Qry2.f_val, &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(T.Id) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Orden&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Qry2 &lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt; Qry2 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Qry2.Nivel &lt;span style="color:#999999;"&gt;=&lt;/span&gt; T.Nivel &lt;span style="color:#999999;"&gt;And&lt;/span&gt; Qry2.Valor &lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt; T.Valor&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; Qry2.Id, Qry2.Nivel, Qry2.f_val&lt;br /&gt;)&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; Id, f_val&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Order By&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Sum&lt;/span&gt;(Orden2);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Eliminamos los objetos :&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Drop Procedure&lt;/span&gt; Qry2;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Procedure&lt;/span&gt; Qry1;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; t1;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Nums;&lt;/p&gt;&lt;p&gt;Ramon Poch, raipon. Terrassa a 03/01/2009.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-3142799238841021640?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3142799238841021640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3142799238841021640'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/01/desafio-sql-order-by-la-solucin.html' title='DESAFIO SQL (ORDER BY). LA SOLUCIÓN'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5919335983325793878</id><published>2009-01-10T00:24:00.000-08:00</published><updated>2009-01-10T00:30:03.211-08:00</updated><title type='text'>Actualización Editor Sql 1.3</title><content type='html'>Hola, ayer subí de nuevo al servidor, el archivo Editor Sql 1.3.rar, con algunas correcciones. Si instalaste la versión 1.3 antes de 09/01/2009, puedes descargar de nuevo el archivo y ejecutar el Setup.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 10/01/2009.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5919335983325793878?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5919335983325793878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5919335983325793878'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/01/actualizacin-editor-sql-13.html' title='Actualización Editor Sql 1.3'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-73263934607631272</id><published>2009-01-03T00:01:00.000-08:00</published><updated>2009-01-08T12:05:08.566-08:00</updated><title type='text'>DESAFIO SQL (ORDER BY)</title><content type='html'>El 1 de Septiembre de 2008, Itzik Ben-Gan (MVP Sql Server) publicó en su blog el siguiente desafio &lt;a href="http://www.sqlmag.com/Article/ArticleID/100156/sql_server_100156.html"&gt;http://www.sqlmag.com/Article/ArticleID/100156/sql_server_100156.html&lt;/a&gt;, que adaptado al lenguaje sql de Access (a utilizar desde un 'lote sql' del Editor Sql 1.3) queda así :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;CREATE TABLE&lt;/span&gt; t1 (id &lt;span style="color:#3333ff;"&gt;identity primary key&lt;/span&gt;, f_val &lt;span style="color:#3333ff;"&gt;Memo&lt;/span&gt; &lt;span style="color:#999999;"&gt;not&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'100'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'7.4.250'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.100.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.99.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.99.300.478.9999999'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'10.30.40.50.20.30.40'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'7.4.250'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/*Aquí está la salida deseada:&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;id******f_val &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;---------------------------------------- &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;7*******7.4.250 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;2*******7.4.250 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;6*******10.30.40.50.20.30.40 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;5*******22.40.5.60.4.99.300.478.9999999 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;4*******22.40.5.60.4.99.300.478.19710212 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;3*******22.40.5.60.4.100.300.478.19710212 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;1*******100 &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;Puntos extra si su solución también apoyará negativos.&lt;br /&gt;Añádanse los siguientes datos de ejemplo para poner a prueba los negativos: */&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;-1'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-2'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-11'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt; '-22'&lt;/span&gt; );&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into &lt;/span&gt;&lt;span style="color:#000000;"&gt;t1&lt;/span&gt; (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-123'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'-321'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.-100.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;insert into&lt;/span&gt; t1 (f_val) &lt;span style="color:#3333ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'22.40.5.60.4.-99.300.478.19710212'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/*Incluida la salida deseada, los valores negativos:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;id******f_val &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;----------------------------------------&lt;br /&gt;13******-321&lt;br /&gt;12******-123&lt;br /&gt;11******-22&lt;br /&gt;10******-11&lt;br /&gt;9*******-2&lt;br /&gt;8*******-1&lt;br /&gt;7*******7.4.250&lt;br /&gt;2*******7.4.250&lt;br /&gt;6*******10.30.40.50.20.30.40&lt;br /&gt;14******22.40.5.60.4.-100.300.478.19710212&lt;br /&gt;15******22.40.5.60.4.-99.300.478.19710212&lt;br /&gt;5*******22.40.5.60.4.99.300.478.9999999&lt;br /&gt;4*******22.40.5.60.4.99.300.478.19710212&lt;br /&gt;3*******22.40.5.60.4.100.300.478.19710212&lt;br /&gt;1*******100&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Solución (Ramon Poch, raipon, Terrassa a 03/01/2009) :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;La publicaré, Dios mediante, dentro de 15 dias : el 18/01/2009.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/ &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;... pues eso, el 18/01/2009 publicaré mi solución a este problema. Sin embargo les animo&lt;/span&gt; a que me envien por correo (mirar en la parte de abajo de esta página) sus propias conclusiones, y las publicaré.&lt;br /&gt;Cabe decir que si utilizamos una función creada desde vba en nuestra consulta, la solución puede ser más sencilla. Pero dado que se puede lograr exclusivamente mediante sql y las funciones vba disponibles ordinariamente en el entorno sql, creo preferible ceñirse a este contexto. En el fondo esto no es un trabajo profesional, tan solo un reto.&lt;br /&gt;Naturalmente a estas alturas, en el blog de Itzik ya están colgadas varias soluciones a este reto, adaptadas a sql server. La solución mia la he diseñado antes de mirar dichas propuestas. No tendria sentido plantearlo de otra forma, ¿ cierto ?.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-73263934607631272?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/73263934607631272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/73263934607631272'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2009/01/desafio-sql-order-by.html' title='DESAFIO SQL (ORDER BY)'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-8318718154815165201</id><published>2008-12-22T00:12:00.000-08:00</published><updated>2008-12-22T02:48:52.417-08:00</updated><title type='text'>COMPARATIVA DE RENDIMIENTO</title><content type='html'>Desde la semana pasada está disponible la nueva versión del Editor Sql (1.3). Una de las mejoras en dicho complemento es la posibilidad de obtener estadísticas de tiempo de ejecución, de los 'Lotes' sql, lo que permite realizar comparativas de rendimiento entre distintas sentencias.&lt;br /&gt;A continuación expongo un ejemplo de Lote preparado para evaluar la velocidad de ejecución de distintos códigos, sobre la base de datos Neptuno.mdb. Solo comentar : para que los resultados sean fiables, es conveniente ejecutar el lote más de una vez.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;---- Evitar funciones en el lado izquierdo de la expresión -----&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;------------------------------------------------------------------------ &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Obtenemos los pedidos del mes de marzo, convirtiendo &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;los valores de FechaPedido mediante la función Month, &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;y comparando el resultado con un valor : 3&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Month&lt;/span&gt;(FechaPedido)&lt;span style="color:#999999;"&gt;=&lt;/span&gt;3;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Comparamos si FechaPedido se encuentra entre tres rangos, &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;que corresponden al mes de marzo de cada ejercicio. La sql &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;es más compleja y no se adapta dinámicamente si añadimos &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;nuevos registros (para un ejercicio diferente), pero es mucho &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;más rápida que la anterior puesto que no necesita procesar &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;con una función todos los registros.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt;&lt;br /&gt;FechaPedido &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; #03/01/1996# &lt;span style="color:#999999;"&gt;And&lt;/span&gt; #03/31/1996#&lt;br /&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;FechaPedido &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; #03/01/1997# &lt;span style="color:#999999;"&gt;And&lt;/span&gt; #03/31/1997#&lt;br /&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;FechaPedido &lt;span style="color:#999999;"&gt;Between&lt;/span&gt; #03/01/1998# &lt;span style="color:#999999;"&gt;And&lt;/span&gt; #03/31/1998#;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-------- Utilizar expresiones apropiadas al tipo de dato ------- &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;----------------------------------------------------------------------- &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Obtenemos los pedidos cuya cantidad es múltiplo de 10, &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;empleando para ello un operador de texto (Like).&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; [Detalles de pedidos]&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Cantidad &lt;span style="color:#999999;"&gt;like&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'%0'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Obtenemos los pedidos cuya cantidad es múltiplo de 10, &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;empleando para ello una función numérica. El rendimiento &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;mejora con respecto a la sql anterior.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;&lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; [Detalles de pedidos]&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Cantidad &lt;span style="color:#cc33cc;"&gt;Mod&lt;/span&gt; 10 &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 0;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;----------- Comparativa consultas de no coincidentes ---------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-----------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; IdCliente &lt;span style="color:#999999;"&gt;Not In&lt;/span&gt; (&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; IdCliente &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Clientes);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Pedidos.&lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#999999;"&gt;Left Join&lt;/span&gt; Clientes&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Pedidos.IdCliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Clientes.IdCliente&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Clientes.IdCliente &lt;span style="color:#999999;"&gt;Is&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Pedidos&lt;span style="color:#3333ff;"&gt;.*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#999999;"&gt;Not Exists&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; IdCliente &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Clientes &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Clientes.IdCliente &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Pedidos.IdCliente);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/*&lt;br /&gt;La sql más rápida la obtenemos al emplear Left Join,&lt;br /&gt;a continuación Where Exists, y el método con peor&lt;br /&gt;rendimiento es utilizar el operador IN.&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;---------- Comparativa uso de Like frente a InStr() -----------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; IdCliente &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;'%bo%'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;(1, IdCliente, &lt;span style="color:#ff0000;"&gt;'bo'&lt;/span&gt;) &lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt; 0;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Aún cuando el uso del comodín '%' al principio del valor a &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;buscar, impide que Access utilice el índice, el operador &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Like es mucho más eficiente que procesar cada registro &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;con la función InStr&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;------------ Comparativa Distinct versus Group By ------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Distinct&lt;/span&gt; FechaPedido, FechaEntrega, FechaEnvío&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; FechaPedido, FechaEntrega, FechaEnvío&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group By&lt;/span&gt; FechaPedido, FechaEntrega, FechaEnvío;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;... es más rápido Distinct que Group By ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;--- Comparativa relacionar tablas en clausulas From o Where --&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;--------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; NombreProducto, NombreCompañía&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Productos &lt;span style="color:#999999;"&gt;Inner Join&lt;/span&gt; Proveedores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On &lt;/span&gt;Productos.IdProveedor &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Proveedores.IdProveedor;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; NombreProducto, NombreCompañía&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From &lt;/span&gt;Productos, Proveedores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Productos.IdProveedor &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Proveedores.IdProveedor;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;El rendimiento es análogo.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;¡ FELIZ NAVIDAD !&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa, a 22/12/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-8318718154815165201?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8318718154815165201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8318718154815165201'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/12/comparativa-de-rendimiento.html' title='COMPARATIVA DE RENDIMIENTO'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-4269293036770925972</id><published>2008-11-02T23:48:00.000-08:00</published><updated>2008-11-03T02:36:29.786-08:00</updated><title type='text'>PROPIEDADES ÍNDICES</title><content type='html'>Se trata de una consulta que explora los í&amp;shy;ndices de una tabla determinada, devolviendo la siguiente información :&lt;br /&gt;&lt;br /&gt;- Nombre del í&amp;shy;ndice&lt;br /&gt;- Si es o no Clave primaria&lt;br /&gt;- Si es o no Clave externa&lt;br /&gt;- Si admite o no valores repetidos&lt;br /&gt;- Nombres de los campos que forman parte del í&amp;shy;ndice&lt;br /&gt;&lt;br /&gt;Para poder utiliar esta consulta, es imprescindible tener en la base de datos una tabla (de nombre 'Nums') con un solo campo (de nombre 'Num'), Entero largo, campo clave, con valores desde 0 a 99. Así mismo, puesto que usamos funciones de vba, será necesario establecer un nivel de seguridad apropiado (Dependerá de la versión de Access que utilicemos).&lt;br /&gt;&lt;br /&gt;Esta es la consulta :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PARAMETERS&lt;/span&gt; Tabla &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; ( 255 );&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; T.&lt;span style="color:#999999;"&gt;*&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CStr&lt;/span&gt;(T.Nombre_del_índice) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Fields("&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Num &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;").Name&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Nombre_del_campo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM &lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes("&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Num &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;").Name&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Nombre_del_índice,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Choose&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes("&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Num &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;").Primary&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;))&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;No&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Sí&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Es_clave_primaria,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Choose&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes("&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Num &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;").Foreign&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;))&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;No&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Sí&lt;/span&gt;") &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Es_clave_externa,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Choose&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes("&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Num &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;").Unique&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;))&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;No&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Sí&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Sin_repeticiones&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Nums.Num&lt;span style="color:#999999;"&gt;&lt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes.Count&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;)&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T,&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select Top&lt;/span&gt; 10 Num &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums&lt;br /&gt;) AS Nums&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE &lt;/span&gt;Num&lt;span style="color:#999999;"&gt;&lt;&lt;/span&gt;Eval(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.TableDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Tabla &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Indexes('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CStr&lt;/span&gt;(T.Nombre_del_índice) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Fields.Count&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; T.Nombre_del_índice;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa, a 07/12/2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-4269293036770925972?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/4269293036770925972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/4269293036770925972'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/11/propiedades-ndices.html' title='PROPIEDADES ÍNDICES'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-1772104832957725256</id><published>2008-10-31T05:01:00.000-07:00</published><updated>2008-10-31T05:13:47.568-07:00</updated><title type='text'>AUTONUMÉRICOS NEGATIVOS</title><content type='html'>En cierta ocasión me vi en la siguiente necesidad : asegurarme que los valores de dos campos autonuméricos (de dos tablas distintas), no pudieran tener valores iguales. Para lograr tal objetivo, utilicé la siguiente instrucción para crear dichos campos :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Alter Table&lt;/span&gt; Tabla1 &lt;span style="color:#3333ff;"&gt;Add Column&lt;/span&gt; Id_1 &lt;span style="color:#3333ff;"&gt;Counter&lt;/span&gt; (1,1) &lt;span style="color:#3333ff;"&gt;Primary Key&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Alter Table&lt;/span&gt; Tabla2 &lt;span style="color:#3333ff;"&gt;Add&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Column&lt;/span&gt; Id_2 &lt;span style="color:#3333ff;"&gt;Counter&lt;/span&gt; (-1,-1) &lt;span style="color:#3333ff;"&gt;Primary Key&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;La primera de las propiedades del campo, establece el valor inicial del autonumérico, mientras que el segundo define el valor de incremento.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 31/10/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-1772104832957725256?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1772104832957725256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1772104832957725256'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/10/autonumricos-negativos.html' title='AUTONUMÉRICOS NEGATIVOS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-7458664588553455227</id><published>2008-10-17T23:31:00.000-07:00</published><updated>2009-10-26T02:53:36.723-07:00</updated><title type='text'>NUMERAR REGISTROS EN BASE A UN CAMPO CON REPETICIONES</title><content type='html'>En el ejemplo anterior : &lt;a href="http://sqlraipon.blogspot.com/2008/09/devolver-n-registros.html"&gt;http://sqlraipon.blogspot.com/2008/09/devolver-n-registros.html&lt;/a&gt;, utilizábamos una subconsulta para contar los registros con un valor 'menor', tomando como referencia uno de los campos. Este campo, debía cumplir dos condiciones : que el orden que se establece al utilizarlo como referencia, coincida con nuestro criterio para numerar los resultados de la consulta, y que no tenga valores duplicados.&lt;br /&gt;&lt;br /&gt;Vamos a intentar numerar los resultados de una consulta, tomando como referencia para la precedencia entre registros uno de sus campos :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTbl (Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;, Fecha &lt;span style="color:#3333ff;"&gt;DateTime&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/02/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/01/2008#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/03/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/04/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/10/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#01/20/2007#);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#3333ff;"&gt;FROM&lt;br /&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;br /&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(*) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; T.Fecha &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; MiTbl.Fecha&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Numerador,&lt;br /&gt;MiTbl.*&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; Numerador;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; MiTbl;&lt;br /&gt;&lt;br /&gt;... los resultados devueltos son correctos (si queremos numerar según fecha), pero qué ocurre si hay fechas duplicadas ...&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTbl (Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;, Fecha &lt;span style="color:#3333ff;"&gt;DateTime&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/02/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/01/2008#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/03/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/04/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/10/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/10/2007#);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT &lt;/span&gt;* FROM&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(*) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; T.Fecha &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; MiTbl.Fecha&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Numerador,&lt;br /&gt;MiTbl.*&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; Numerador;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; MiTbl;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;... no hay Numerador = 4 y sin embargo hay dos registros con Numerador = 5. ¿ Cómo solucionarlo ? ... Tomando para la comparación tantos campos como sea preciso para crear valores únicos. En este caso incorporaremos el campo Id a la subconsulta :&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; MiTbl (Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;, Fecha &lt;span style="color:#3333ff;"&gt;DateTime&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/02/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/01/2008#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/03/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/04/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/10/2007#);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; MiTbl (Fecha) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;(#10/10/2007#);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#3333ff;"&gt;FROM&lt;br /&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(*) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CSng&lt;/span&gt;(T.Fecha) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; T.Id &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CSng&lt;/span&gt;(MiTbl.Fecha) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; MiTbl.Id&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Numerador,&lt;br /&gt;MiTbl.*&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTbl&lt;br /&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; Numerador;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; MiTbl;&lt;br /&gt;&lt;br /&gt;... los valores del campo Numerador ya son coherentes, a pesar de que ordenemos por Fecha, y que para esta columna existan valores repetidos. Cabe destacar que Access realiza de forma implícita cambios en el tipo de datos (en campos calculados). Por ejemplo esta expresión : UnaFecha &amp;amp; UnNúmero lo convierte en texto. Para establecer un orden correcto, esto no supone ningún problema excepto si empleamos campos Fecha/Hora (nuestro caso, ¡ Qué mala suerte !), en cuyo caso el orden alfabético no coincide con el orden según Fecha (#20/10/2008# &gt; #21/10/2007#, pero '20/10/2008' &lt; '21/10/2007'). Para sortear esta dificultad, es preferible convertir las fechas a Single (CSng(#20/10/2008#) = 39741, CSng(#21/10/2007#) = 39376), de hecho, Access almacena internamente las Fechas como Single, siendo la parte entera los dias transcurridos desde el 31 de Diciembre de 1899, y la fracción decimal : Horas, minutos, segundos ...&lt;/p&gt;Ramon Poch, raipon. Terrassa a 10/10/2008.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-7458664588553455227?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/7458664588553455227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/7458664588553455227'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/10/numerar-registros-por-un-campo-con.html' title='NUMERAR REGISTROS EN BASE A UN CAMPO CON REPETICIONES'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-8735782149844515940</id><published>2008-09-27T11:01:00.000-07:00</published><updated>2009-10-26T02:55:56.308-07:00</updated><title type='text'>DEVOLVER N REGISTROS (PAGINAR)</title><content type='html'>Para que una consulta devuelva una cantidad concreta de registros, utilizamos la cláusula top :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Top&lt;/span&gt; 10 &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos;&lt;br /&gt;&lt;br /&gt;O bien, si en vez de una cantidad, queremos un porcentaje :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select Top&lt;/span&gt; 10 &lt;span style="color:#3333ff;"&gt;Percent&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos;&lt;br /&gt;&lt;br /&gt;Pero puede presentarse la siguiente necesidad : Obtener n registros por grupo (ver &lt;a href="http://groups.google.es/group/microsoft.public.es.access/browse_thread/thread/e50cf402a9916ebb"&gt;http://groups.google.es/group/microsoft.public.es.access/browse_thread/thread/e50cf402a9916ebb&lt;/a&gt;#)&lt;br /&gt;En este ejemplo, evidentemente no nos sirve utilizar 'Top'. Una solución podría ser emplear una subconsulta que evaluara el número de registros devueltos para cada grupo. Y poner como condición que dicho número sea igual a n :&lt;br /&gt;&lt;br /&gt;Ejemplo preparado para ejecutar desde el Editor Sql 1.2 &lt;a href="http://groups.google.com/group/raipon?hl=es"&gt;http://groups.google.com/group/raipon?hl=es&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Parameters&lt;/span&gt; n &lt;span style="color:#3333ff;"&gt;Long&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Tareas (id Long Primary Key, titulo Text (255), ambito Text (255), prioridad Bit);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Avance_Tareas (id Long, fecha_avance DateTime, descripcion Text (255));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, &lt;span style="color:#ff0000;"&gt;'Primera'&lt;/span&gt;, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, &lt;span style="color:#ff0000;"&gt;'Segunda'&lt;/span&gt;, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, #09/30/2008#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, #10/01/2008#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, #10/02/2008#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, #10/06/2008#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, #09/30/2007#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, #10/10/2007#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, #10/11/2007#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Avance_Tareas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, #10/10/2008#, &lt;span style="color:#3333ff;"&gt;Null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; tareas.titulo, tareas.ambito, tareas.prioridad,&lt;br /&gt;avance_tareas.fecha_avance, avance_tareas.descripcion&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; tareas &lt;span style="color:#999999;"&gt;Inner&lt;/span&gt; Join Avance_Tareas&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; tareas.id &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Avance_Tareas.id&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(&lt;span style="color:#999999;"&gt;*&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; avance_tareas &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; T.id &lt;span style="color:#999999;"&gt;=&lt;/span&gt; tareas.Id &lt;span style="color:#999999;"&gt;And&lt;/span&gt; T.fecha_avance &lt;span style="color:#999999;"&gt;&gt;= &lt;/span&gt;Avance_Tareas.fecha_avance) &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; n;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Tareas;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Avance_Tareas;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 10/10/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-8735782149844515940?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8735782149844515940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8735782149844515940'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/09/devolver-n-registros.html' title='DEVOLVER N REGISTROS (PAGINAR)'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-8653993394162107596</id><published>2008-07-01T04:19:00.000-07:00</published><updated>2008-09-25T09:57:40.455-07:00</updated><title type='text'>CÓDIGO SQL EMBEBIDO</title><content type='html'>... la verdad es que pensaba titular este artículo así : 'Solo para valientes', pero no era demasiado descriptivo, ¿ o sí ?. En cualquier caso se trata de un tema solo recomendable a expertos en lenguaje sql, pues es fácil cometer errores que impidan el correcto funcionamiento de este sistema. Además, advierto que se debe proteger/controlar/verificar (mediante un formulario y el código que sea preciso) la 'bondad' de las reglas que se van a embeber. De no actuar así, estamos dejando una puerta abierta a que un usuario malintencionado nos haga un estropicio.&lt;br /&gt;&lt;br /&gt;Para explicar de qué se trata, quizás sea mejor mediante un ejemplo : Supongamos que deseamos mostrar, mediante una consulta, los mensajes de correo electrónico que tenemos guardados en una tabla 'Mensajes'. Pero, imitando a los programas de correo, queremos filtrar el contenido, o el título, o el remitente de dichos mensajes. Para ello, hemos creado una segunda tabla 'Reglas', donde pensamos guardar expresiones que actúen como regla de validación de los correos. Es decir, queremos guardar fragmentos de código sql, dentro de una tabla y después ejecutar estos trozos de código dentro de una consulta.&lt;br /&gt;Si habéis intentado algo por el estilo desde vba, ya sabréis que directamente no se puede, y que es necesario emplear 'un intermediario' que explique al compilador que una cadena de texto, no es tal, sino un fragmento de código. En este ejemplo hemos usado la función Eval() como intérprete de nuestros deseos. Sin embargo surge un problema con ello : para que este 'invento' tenga utilidad, es necesario, imprescindible, poder pasar valores por referencia, desde fuera de la regla, adentro de la misma. En concreto necesitamos que si en la regla escribimos el nombre de un campo de la tabla 'Mensajes', obtengamos el valor de dicho campo. Lamentablemente esto, en principio, no es posible, pero ... quizás es el momento de ver una secuencia (un lote) ejecutable desde el 'Editor Sql 1.1' que nos muestre cómo :&lt;br /&gt;&lt;br /&gt;Dos advertencias previas : He substituido el operador Like y el carácter comodín '*' por ALike y '%'. Ha sido necesario por la forma de trabajar interna del Editor, pero para ejecutarse en una consulta de Access, esto no es necesario (a no ser que, en Opciones, tengamos activada la compatibilidad con Sql Server).&lt;br /&gt;Para usar la función Eval() desde Sql, es necesario bajar el nivel de seguridad de Access.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* Filtros embebidos, Ramon Poch, raipon. Terrassa a 13/05/2008 */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Creamos una tabla de mensajes de correo electrónico&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Mensajes&lt;br /&gt;(&lt;br /&gt;Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;,&lt;br /&gt;Destinatario &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255),&lt;br /&gt;Titulo &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255),&lt;br /&gt;Cuerpo &lt;span style="color:#3333ff;"&gt;Memo&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Insertamos unos cuantos valores de prueba&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Mensajes (Destinatario, Titulo, Cuerpo)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;a href="mailto:UnaDireccion@UnServidor.com"&gt;&lt;span style="color:#ff0000;"&gt;UnaDireccion@UnServidor.com&lt;/span&gt;&lt;/a&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Prueba1&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Oferta de electrodomesticos de ocasión &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;.&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;.."&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Mensajes (Destinatario, Titulo, Cuerpo)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;a href="mailto:OtraDireccion@OtroServidor.com"&gt;&lt;span style="color:#ff0000;"&gt;OtraDireccion@OtroServidor.com&lt;/span&gt;&lt;/a&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Prueba2"&lt;/span&gt;&lt;span style="color:#000000;"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"¿ Cómo te han ido estos dias de vacaciones ..."&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Mensajes (Destinatario, Titulo, Cuerpo)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;a href="mailto:UnaDireccion@UnServidor.com"&gt;&lt;span style="color:#ff0000;"&gt;UnaDireccion@UnServidor.com&lt;/span&gt;&lt;/a&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Prueba3&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Compra venta de ..."&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Creamos una tabla de reglas&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Reglas (Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;, Regla &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Insertamos Reglas que sean capaces de restringir los mensajes&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Reglas (Regla)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"'•Destinatario•' ALike &lt;/span&gt;&lt;a href="mailto:"&gt;&lt;span style="color:#ff0000;"&gt;'%@TutiSpam%'&lt;/span&gt;&lt;/a&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Reglas (Regla)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values &lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"'•Titulo•' = 'Gran oferta'"&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Reglas (Regla)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"'•Cuerpo•' ALike '%Compra%' &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Or &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;'•Cuerpo•' ALike '%Venta%' &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;'•Cuerpo•' ALike 'Oferta'"&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Veamos los mensajes ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;span style="color:#3333ff;"&gt; From&lt;/span&gt; Mensajes;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Comprobamos qué efecto tiene el filtro :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Mensajes&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Not Exists&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Reglas&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Replace&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Replace&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Replace&lt;/span&gt;(Regla, &lt;span style="color:#ff0000;"&gt;"•Destinatario&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;•"&lt;/span&gt;, Destinatario),&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"•Titulo&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;•"&lt;/span&gt;,Titulo),&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"•Cuerpo&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;•"&lt;/span&gt;,Cuerpo)&lt;br /&gt;)=-1&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/* ¿ Qué hemos hecho ?. Para poder interpretar como código, el texto guardado en el campo Regla, utilizamos la función Eval(), sin embargo, desde dentro de esta función no podemos pasar valores por referencia de los campos 'Cuerpo', 'Titulo' o 'Destinatario' . Para solucionar este inconveniente empleamos la función Replace(), que sí que es capaz de leer por referencia los campos de la consulta y modificar la cadena de texto a interpretar por Eval(). Es decir, és la función Replace() la que 'pasa' el valor del campo a Eval(). Evidentemente es necesario emplear tantas veces la función Replace() embebida, como campos deseemos controlar. El carácter '•' (Alt 7) lo utilizamos para localizar de forma inequívoca el nombre del campo dentro de la regla.*/&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Eliminamos los objetos del ejemplo&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Mensajes;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Reglas;&lt;br /&gt;&lt;br /&gt;En resumidas cuentas, se trata de un método que nos permite añadir funcionalidad a nuestras aplicaciones : los usuarios pueden modificar dinámicamente el comportamiento de algunas consultas, sin necesidad de alterar el diseño de las mismas.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 13/05/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-8653993394162107596?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8653993394162107596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/8653993394162107596'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/07/cdigo-sql-embebido.html' title='CÓDIGO SQL EMBEBIDO'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-478680320144861956</id><published>2008-07-01T00:00:00.000-07:00</published><updated>2008-07-01T00:00:01.692-07:00</updated><title type='text'>FULL JOIN EN ACCESS</title><content type='html'>Del tutorial de sql de Claudio Casares (&lt;a href="http://personal.lobocom.es/claudio/sql008.htm"&gt;http://personal.lobocom.es/claudio/sql008.htm&lt;/a&gt;) : "... Full Join ... Este tipo de operador se utiliza para devolver todas las filas de una combinación tengan o no correspondencia. Es el equivalente a la utilización de LEFT JOIN y RIGHT JOIN a la misma vez ..."&lt;br /&gt;&lt;br /&gt;Lamentablemente no disponemos de este operador en Access. Sin embargo, podemos emular su comportamiento :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Supongamos una tabla Autores ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Autores (Id &lt;span style="color:#3333ff;"&gt;Int Primary Key&lt;/span&gt;, Nombre &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255));&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Autores&lt;span style="color:#3333ff;"&gt; Values&lt;/span&gt; (1, &lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Ludwig Van Beethoven&lt;/span&gt;");&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Autores &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, &lt;span style="color:#ff0000;"&gt;"Wolfgang Amadeus Mozart&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Autores &lt;span style="color:#3366ff;"&gt;Values&lt;/span&gt; (3, &lt;span style="color:#ff0000;"&gt;"Richard Strauss&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Autores &lt;span style="color:#3333ff;"&gt;Values &lt;/span&gt;(4, &lt;span style="color:#ff0000;"&gt;"Gioachino Rossini&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Autores &lt;span style="color:#3333ff;"&gt;Values &lt;/span&gt;(5, &lt;span style="color:#ff0000;"&gt;"Arrigo Boito&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Y una tabla de Operas ...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Operas (Id &lt;span style="color:#3333ff;"&gt;Int Primary Key&lt;/span&gt;, Título&lt;span style="color:#3333ff;"&gt; text&lt;/span&gt; (255), Autor &lt;span style="color:#3333ff;"&gt;Int&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Operas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1, &lt;span style="color:#ff0000;"&gt;"Fidelio"&lt;/span&gt;, 1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Operas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2, &lt;span style="color:#ff0000;"&gt;"La flauta mágica&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;, 2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Operas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3, &lt;span style="color:#ff0000;"&gt;"El Barbero de Sevilla&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;, 4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Operas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4, &lt;span style="color:#ff0000;"&gt;"Mefistofele&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;, 5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Operas &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5, &lt;span style="color:#ff0000;"&gt;"La Fuerza del destino&lt;/span&gt;", 6);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Y queremos mostrar en una consulta el nombre de la &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- ópera junto con el de su autor. En caso de que falte &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- algún dato, que aparezca el campo con valor nulo,&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- pero en cualquier caso que no omita el registro :&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Autores.Nombre &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Autor, Operas.Título&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Id &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Autor &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Autores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;Autor &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Operas&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T &lt;span style="color:#3333ff;"&gt;LEFT JOIN&lt;/span&gt; Operas&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; T.Autor &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Operas.Autor&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;LEFT JOIN&lt;/span&gt; Autores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; T.Autor &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Autores.Id;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Se trata por tanto de crear una consulta de unión &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- intermedia, que contenga todos los valores posibles&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de ambas tablas, y armar la consulta final en base&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- a ella.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Autores;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Operas;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 04/06/2008&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-478680320144861956?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/478680320144861956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/478680320144861956'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/07/full-join-en-access.html' title='FULL JOIN EN ACCESS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-3413940113553602334</id><published>2008-06-01T05:10:00.000-07:00</published><updated>2008-09-26T04:29:57.829-07:00</updated><title type='text'>RECURSIVIDAD EN ACCESS (SQL + VBA)</title><content type='html'>Podríamos definir la recursividad, como la capacidad de una instrucción de código, para llamarse a si misma, en busca de resultados más detallados. En las bases de datos, a veces puede ser necesario emplear esta técnica para explorar estructuras jerárquicas (en árbol). Si crees que esto es algo muy raro y alejado de la cotidianeidad, es conveniente que sepas que el propio Access utiliza este tipo de estructura en las tablas del sistema (MSysObjects, MSysQueries, etc). Sin embargo, el lenguaje sql de Access no admite recursividad, es decir, desde una consulta no podemos llamar a la propia consulta.&lt;br /&gt;&lt;br /&gt;Bien, pues en este artículo veremos cómo podemos explorar estructuras en árbol, empleando recursividad, o algo parecido ...&lt;br /&gt;&lt;br /&gt;Antes que nada, puesto que he afirmado que las tablas del sistema de Access almacenan la información de forma jerárquica, vamos a comprobarlo : Abrimos la tabla MSysObjects y veremos, entre otros, los siguientes campos : Id, Name, ParentId, ... si investigamos un poco la relación que existe entre los valores del primer y el último campo, comprobaremos que por ejemplo : del registro cuyo valor en el campo Name es 'Tables', cuelgan todas las tablas y consultas de la base de datos (ParentId = Id).&lt;br /&gt;&lt;br /&gt;¿ Y qué utilidad tiene disponer la información de esta forma ?, ¿ No seria más útil emplear el modelo relac¡onal ?. En primer lugar, las tablas del sistema (en Access), solo tienen un nivel de anidamiento, es decir, que cada registro 'Padre' solo puede tener un grupo de registros subordinados, truncándose a este nivel la descendencia, por tanto, al realizar una exploración, el coste del proceso es mínimo ya que sabemos de antemano que solo hay que explorar un nivel. Y por otra parte, al reunir todos los nombres de 'objetos' en un único campo : 'Name', mediante un solo índice compuesto por los campos 'Name' y 'ParentId' podemos controlar que no haya nombres repetidos para el mismo tipo de objetos, de forma mucho más rápida que si tuviéramos dicha información repartida en varias tablas. De hecho, si en la vista diseño de la tabla MSysObjects, abrimos la pantalla que nos muestra los índices de la tabla, veremos que este índice sobre los dos campos efectivamente existe.&lt;br /&gt;&lt;br /&gt;Para facilitar la creación de ejemplos, emplearemos una sola tabla : 'Empleados' de Neptuno.mdb, ya que a pesar de tener muy pocos registros, oculta una estructura jerárquica. Si la abrimos en vista diseño, podremos comprobar que cada registro, además de su correspondiente campo 'Id', dispone de un campo 'Jefe', que corresponde a un 'Id' de otro registro.&lt;br /&gt;&lt;br /&gt;Supongamos que la empresa 'Importadores Neptuno', necesita mejorar la comercialización de sus productos, y entre otras medidas, ha decidido que todo el personal de ventas debe realizar un curso de márketing. El gerente de la sociedad, así se lo ha comunicado al Sr. Andrew Fuller, vicepresidente comercial, y este a su vez, ha encargado a la Srta. Laura Callahan, Coordinador de ventas interno, la elaboración de un listado del personal adscrito a su departamento. Naturalmente la Srta Callahan está dispuesta a emplear la información de la tabla 'Empleados' para obtener el susodicho listado, sin embargo, rápidamente se ha percatado de una dificultad : el campo 'Jefe' de cada empleado, define el superior inmediato de cada uno de ellos, pero dicho superior, puede a su vez  estar subordinado a uno o varios responsables, ¿ cómo asegurarse de ir siguiendo todas las líneas ascendentes hasta llegar al Sr Fuller, sin olvidarse a nadie ?.&lt;br /&gt;&lt;p&gt;Hace varios años, leí una aportación de Marius Puig, en el foro de Access y vba : &lt;a href="http://www.mvp-access.com/foro/default.asp"&gt;http://www.mvp-access.com/foro/default.asp&lt;/a&gt;, sobre consultas recursivas. Lamentablemente, puesto que los mensajes con cierta antigüedad se van borrando, dudo mucho que se pueda encontrar el hilo original. Sin embargo, he aquí la técnica que él empleaba :&lt;br /&gt;&lt;br /&gt;Crear una función (pública) en un módulo. Dicho procedimiento, se encargará de devolver una cadena delimitada por comas (csv) de todos los 'hijos' de un determinado nodo. La función la utilizaremos en la cláusula 'Where' de una consulta.&lt;br /&gt;Estas son la función y la consulta :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Marius Puig&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Public Function&lt;/span&gt; AWniveles(Tabla, Hijo, Padre, Valor)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; Dato, strRst, rst &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; DAO.Recordset&lt;br /&gt;&lt;br /&gt;strRst = "select * from " &amp;amp; Tabla &amp;amp; " where " &amp;amp; Padre &amp;amp; "=" &amp;amp; Valor&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; rst = CurrentDb.OpenRecordset(strRst)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;With&lt;/span&gt; rst&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Do While&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Not&lt;/span&gt; .EOF&lt;br /&gt;Dato = Dato &amp;amp; AWniveles(Tabla, Hijo, Padre, .Fields(Hijo))&lt;br /&gt;.MoveNext&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Loop&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;End With&lt;br /&gt;&lt;/span&gt;AWniveles = Valor &amp;amp; ";" &amp;amp; Dato&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End Function&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;Empleados.IdEmpleado &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; IdJefe,&lt;br /&gt;Empleados.Nombre &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; NombreJefe,&lt;br /&gt;Duplicado.IdEmpleado &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; IdEmpleado,&lt;br /&gt;Duplicado.Nombre &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; NombreEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;Empleados, Empleados &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Duplicado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;AWniveles&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Empleados&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;, &lt;span style="color:#ff0000;"&gt;"IdEmpleado&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Jefe&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,Empleados.IdEmpleado&lt;br /&gt;), Duplicado.IdEmpleado &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;";"&lt;br /&gt;&lt;/span&gt;)&lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt;0&lt;br /&gt;&lt;span style="color:#999999;"&gt;And&lt;/span&gt;&lt;br /&gt;Empleados.IdEmpleado &lt;span style="color:#999999;"&gt;&lt;&gt;&lt;/span&gt; Duplicado.IdEmpleado;&lt;br /&gt;&lt;br /&gt;... ¡ Genial !, no solo va recorriendo todas las ramas del árbol, sino que además la función AWniveles se llama a sí misma de forma recursiva.&lt;br /&gt;Para obtener 'limpios' los empleados que dependen del Sr. Fuller, tan solo tenemos que añadir este criterio a la consulta :&lt;br /&gt;... And Empleados.IdEmpleado = 2 ...&lt;br /&gt;Sin embargo, esta estructura tiene un inconveniente : es necesario generar más registros de los que devuelve la tabla original, por lo que en la consulta empleamos un 'Cross Join' (no relacionar las tablas), de la tabla consigo misma, lo que nos devuelve una cantidad de registros equivalente a elevar al cuadrado la cantidad de líneas de la tabla. En este caso, 'Empleados' tiene 9 registros por lo que la consulta, antes de filtrarla en la cláusula 'Where' devuelve 81 items. Naturalmente, a poco que 'abulte' la tabla implicada, el rendimiento decae rápidamente (una tabla de 1.000 registros, devuelve 1.000.000).&lt;br /&gt;&lt;br /&gt;Una alternativa para evitar el 'Cross Join' : Emplear una tabla temporal para insertar recursivamente los registros :&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#33cc00;"&gt;'Ramon Poch, raipon. Terrassa a 24/05/2008&lt;br /&gt;'El parámetro 'Sql_Orígen', puede ser el nombre de una tabla&lt;br /&gt;'o consulta (emplear corchetes para delimitarlo si contiene&lt;br /&gt;'caracteres extraños o espacios), o una instrucción sql, en&lt;br /&gt;'cuyo caso, delimitaremos la instrucción sql entre paréntesis.&lt;br /&gt;&lt;/span&gt;Sub&lt;/span&gt; InsertRecursivo(Padre &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String, Hijo &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String, Sql_Orígen &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On Error GoTo&lt;/span&gt; Err_InsertRecursivo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; qdf As DAO.QueryDef&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; contador As Long&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; control As Long: control = 1&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Creamos la tabla para guardar la información&lt;/span&gt;&lt;br /&gt;CurrentProject.Connection.Execute _&lt;br /&gt;"Create Table Recursiva " &amp;amp; _&lt;br /&gt;"(" &amp;amp; _&lt;br /&gt;"Nivel Integer, Id_Parent Long, Id_Fill Long " &amp;amp; _&lt;br /&gt;")"&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Insertamos un primer nivel de exploración del árbol&lt;/span&gt; &lt;span style="color:#33cc00;"&gt;en la tabla temporal.&lt;/span&gt;&lt;br /&gt;CurrentDb.Execute _&lt;br /&gt;"Insert Into Recursiva " &amp;amp; _&lt;br /&gt;"Select 0 As Nivel, Temp.[" &amp;amp; Hijo &amp;amp; "] As Id_Parent, tbl_origen.[" &amp;amp; Hijo &amp;amp; "] As Id_Fill " &amp;amp; _&lt;br /&gt;"From (Select * From " &amp;amp; Sql_Orígen &amp;amp; ") As Temp " &amp;amp; _&lt;br /&gt;"Inner Join (Select * From " &amp;amp; Sql_Orígen &amp;amp; ") As tbl_origen " &amp;amp; _&lt;br /&gt;"On Temp.[" &amp;amp; Hijo &amp;amp; "] = tbl_origen.[" &amp;amp; Padre &amp;amp; "]"&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; qdf = CurrentDb.CreateQueryDef("", _&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;"Parameters p_Nivel Long; " &amp;amp; _&lt;br /&gt;"Insert Into Recursiva " &amp;amp; _&lt;br /&gt;"Select p_Nivel + 1 As Nivel, Temp.Id_Parent, Recursiva.Id_Fill " &amp;amp; _&lt;br /&gt;"From Recursiva As Temp Inner Join Recursiva " &amp;amp; _&lt;br /&gt;"On Temp.Id_Fill = Recursiva.Id_Parent " &amp;amp; _&lt;br /&gt;"Where Recursiva.Nivel = P_Nivel")&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Iniciamos un insert recursivo, filtrando su alcance a los registros&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'agregados en la última acción. Cuando la propiedad RecordsAffected&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'sea igual a cero, abandonamos el bucle ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Do While&lt;/span&gt; control &gt; 0&lt;br /&gt;qdf.Parameters("p_Nivel") = contador&lt;br /&gt;contador = contador + 1&lt;br /&gt;qdf.Execute&lt;br /&gt;control = qdf.RecordsAffected&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Loop&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; qdf = &lt;span style="color:#3333ff;"&gt;Nothing&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Exit_InsertRecursivo:&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Exit&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Err_InsertRecursivo:&lt;br /&gt;MsgBox Err.Description&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On Error Resume Next&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;If&lt;/span&gt; DCount("*", "MSysObjects", "Name = 'Recursiva' And Type = 1") &gt; 0 &lt;span style="color:#3333ff;"&gt;Then&lt;br /&gt;&lt;/span&gt;CurrentProject.Connection.Execute _&lt;br /&gt;"Drop Table Recursiva"&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End If&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Resume&lt;/span&gt; Exit_InsertRecursivo&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;&lt;br /&gt;End&lt;/span&gt; &lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'Procedimiento de llamada&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;Sub&lt;/span&gt; llamada()&lt;br /&gt;InsertRecursivo "Jefe", "IdEmpleado", "Empleados"&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End Sub&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;En este punto, si queremos recuperar la información de forma más legible, solo tenemos que realizar una consulta sobre los valores guardados en la tabla temporal : 'Recursiva' &lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Nombre &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Empleados &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; IdEmpleado = Id_Parent) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Jefe,&lt;br /&gt;(&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Nombre &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Empleados &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; IdEmpleado = Id_Fill) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Empleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Recursiva&lt;/p&gt;&lt;p&gt;O mejor aún, puesto que no utilizaremos subconsultas :&lt;/p&gt;&lt;p&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;E1.Nombre &lt;span style="color:#999999;"&gt;+&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;' '&lt;/span&gt; &lt;span style="color:#999999;"&gt;+&lt;/span&gt; E1.Apellidos &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Jefe,&lt;br /&gt;E2.Nombre &lt;span style="color:#999999;"&gt;+&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;' '&lt;/span&gt; &lt;span style="color:#999999;"&gt;+&lt;/span&gt; E2.Apellidos &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Empleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(Recursiva &lt;span style="color:#999999;"&gt;Inner Join&lt;/span&gt; Empleados &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; E1 &lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Recursiva.Id_Parent &lt;span style="color:#999999;"&gt;=&lt;/span&gt; E1.IdEmpleado)&lt;br /&gt;&lt;span style="color:#999999;"&gt;Inner Join&lt;/span&gt; Empleados &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; E2 &lt;span style="color:#3333ff;"&gt;On&lt;/span&gt; Recursiva.Id_Fill &lt;span style="color:#999999;"&gt;=&lt;/span&gt; E2.IdEmpleado&lt;/p&gt;&lt;p&gt;El procedimiento 'InsertRecursivo' es verdaderamente rápido, permitiéndonos incluso obtener cientos de miles de registros en escasos segundos. La desventaja es que debemos controlar la posterior eliminación de la tabla temporal 'Recursiva', o si queremos mantenerla en la base de datos : vaciarla antes o después de cada uso.&lt;/p&gt;&lt;p&gt;Ramon Poch, raipon. Terrassa a 24/05/2008.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-3413940113553602334?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3413940113553602334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3413940113553602334'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/06/recursividad-en-access-sql-vba.html' title='RECURSIVIDAD EN ACCESS (SQL + VBA)'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-7671779605347016251</id><published>2008-06-01T00:01:00.000-07:00</published><updated>2008-06-06T23:39:55.681-07:00</updated><title type='text'>PROPIEDAD COLUMN EN CONSULTA</title><content type='html'>El lenguaje sql de Access permite hacer referencia al valor de un control de un formulario :&lt;br /&gt;&lt;br /&gt;Ejemplos sobre Neptuno.mdb :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Proveedores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; IdProveedor &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Forms!Proveedores!IdProveedor&lt;br /&gt;&lt;br /&gt;pero si intentamos lo mismo con otras propiedades del control, por ejemplo Column, nos da error :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Proveedores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; NombreCompañía &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Forms!Proveedores!IdProveedor.Column(1);&lt;br /&gt;&lt;br /&gt;Normalente para manejar este tipo de casos, construimos dinámicamente la consulta desde vba, pero no es la única forma ...&lt;br /&gt;La solución : utilizar Eval(). Esta función nos permite crear un puente entre propiedades que solo están disponibles desde vba y sql :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; *&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM &lt;/span&gt;Proveedores&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; NombreCompañía &lt;span style="color:#999999;"&gt;= &lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Forms.Productos.IdProveedor.Column(1&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;)"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;Y ahora sí, al ejecutar la consulta, visualizaremos el registro del proveedor con el 'NombreCompañía' que muestre el combo IdProveedor en el formulario 'Productos' en ese momento.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 01/02/2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-7671779605347016251?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/7671779605347016251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/7671779605347016251'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/06/propiedad-column-en-consulta.html' title='PROPIEDAD COLUMN EN CONSULTA'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5296975033015393789</id><published>2008-05-25T23:31:00.000-07:00</published><updated>2009-11-21T11:25:09.934-08:00</updated><title type='text'>FUNCIÓN AGREGADA DE DOMINIO ENCADENAR</title><content type='html'>&lt;span style="color:#000000;"&gt;Se trata de una función creada en vba, po lo tanto, debe estar en un módulo :&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'////////////////////////////////////////////////////////////////////&lt;br /&gt;'Ramon Poch, raipon. Terrassa a 13/11/2005&lt;br /&gt;'Encadenar, permite obtener una cadena con los valores de un campo de&lt;br /&gt;'una Tabla, consulta o instrucción sql, separados por un caracter&lt;br /&gt;'a elegir. Su uso es muy similar a las funciones agregadas de dominio.&lt;br /&gt;'  -Separador es el caracter delimitador que escogemos para separar los&lt;br /&gt;'   distintos valores.&lt;br /&gt;'  -Tabla puede ser una la tabla, consulta, o intrucción sql.&lt;br /&gt;'  -Campo es una expresión que nos identifica una columna (de la Tabla,&lt;br /&gt;'   consulta o instrucción sql) de la que queremos concatenar sus valores.&lt;br /&gt;'  -Condición (opcional) nos permite filtrar los resultados. Similar a una condición&lt;br /&gt;'   Where  pero sin dicha palabra. Al igual que las funciones agregadas de dominio,&lt;br /&gt;'   debemos tener las siguientes precauciones al pasar un valor o una referéncia a &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;'   un campo :&lt;br /&gt;'  -Delimitar el valor o el campo según el tipo de dato (usar ' para&lt;br /&gt;'    texto y # para fechas.&lt;br /&gt;'    Ejemplo "Ciudad='Barcelona'" o "CampoFecha=#" &amp;amp; CampoFecha &amp;amp; "#"&lt;br /&gt;'   -Ademas, en lo que respecta a las fechas debemos formatearlas al&lt;br /&gt;'    estilo 'Americano'.&lt;br /&gt;'    Ejemplo "CampoFecha=#12/31/2005#" o&lt;br /&gt;'    "CampoFecha=#" &amp;amp; Format(CampoFecha, "mm/dd/yyyy") &amp;amp; "#"&lt;br /&gt;'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Public Function&lt;/span&gt; Encadenar(Separador &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String, tabla &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String, Campo &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String, _&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Optional&lt;/span&gt; Condición &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; String&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;On Error Resume Next&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; rst As New ADODB.Recordset&lt;br /&gt;&lt;br /&gt;rst.Open _&lt;br /&gt;"Select " &amp;amp; Campo &amp;amp; " From (" &amp;amp; tabla &amp;amp; ") WHERE " &amp;amp; Campo &amp;amp; " Is not null" &amp;amp; _&lt;br /&gt;IIf(Len(Condición) &gt; 0, " AND " &amp;amp; Condición, ""), _&lt;br /&gt;CurrentProject.Connection, adOpenStatic, adLockReadOnly&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;If&lt;/span&gt; Err.Number &gt; 0 &lt;span style="color:#3333ff;"&gt;Then&lt;/span&gt;&lt;br /&gt;Encadenar = ""&lt;br /&gt;rst.Close&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Exit Function&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;If&lt;/span&gt; rst.EOF &lt;span style="color:#3333ff;"&gt;Then&lt;/span&gt;&lt;br /&gt;Encadenar = ""&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Else&lt;/span&gt;&lt;br /&gt;Encadenar = rst.GetString(adClipString, , Separador, Separador)&lt;br /&gt;Encadenar = Left(Encadenar, Len(Encadenar) - Len(Separador))&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;rst.Close&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;End&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Una vez esté guardado el módulo, podemos llamar a dicha función obteniendo una cadena con los valores del campo escogido concatenados, delimitada por el caracter que hayamos definido. Ejemplo sobre la tabla Proveedores de Neptuno.mdb :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Proveedores.NombreCompañía,&lt;br /&gt;Encadenar(&lt;span style="color:#cc0000;"&gt;", &lt;/span&gt;&lt;span style="color:#cc0000;"&gt;"&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;"Productos&lt;/span&gt;&lt;span style="color:#cc0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#cc0000;"&gt;"&lt;/span&gt;&lt;span style="color:#cc0000;"&gt;NombreProducto&lt;/span&gt;&lt;span style="color:#cc0000;"&gt;"&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;"IdProveedor="&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;[Proveedores].[IdProveedor]) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Productos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Proveedores;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 13/11/2005&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5296975033015393789?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5296975033015393789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5296975033015393789'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/05/funcin-agregada-de-dominio-encadenar.html' title='FUNCIÓN AGREGADA DE DOMINIO ENCADENAR'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-1853999362260177262</id><published>2008-05-15T06:58:00.000-07:00</published><updated>2008-05-15T13:33:46.291-07:00</updated><title type='text'>SEGURIDAD CON RESTRICCIÓN CHECK</title><content type='html'>No, esta vez no voy a tratar el tema de la seguridad por usuarios, sino de un método alternativo que surgió a raíz de una pregunta en el 'Foro de Access y vba' : &lt;a href="http://www.mvp-access.com/foro/default.asp"&gt;http://www.mvp-access.com/foro/default.asp&lt;/a&gt; el día 07/05/2008. Se trata de impedir que nadie pueda insertar nuevos registros, o modificar los existentes, al margen de los formularios y herramientas que hayamos previsto para ello. En otras palabras, asegurarnos que no se pueda acceder directamente a las tablas de la base de datos.&lt;br /&gt;Para conseguir este objetivo obligaremos a los usuarios a entrar en nuestra aplicación con un acceso directo, que abra el programa en modo Runtime.&lt;br /&gt;Configuración del acceso directo : Escribir la propiedad 'Destino', del acceso directo según este esquema :&lt;br /&gt;&lt;br /&gt;"C:\Archivos de programa\Microsoft Office\OFFICE11\MSACCESS.EXE"&lt;br /&gt;"C:\MiAplicación.mdb" /Runtime&lt;br /&gt;&lt;br /&gt;Es decir, la ruta de la versión de Access que tengamos instalada (en este ejemplo Access 2003) y la ruta de la base de datos, seguida de la opción /Runtime.&lt;br /&gt;Bien, ¿ pero cómo impedir que alguien abra la aplicación en modo normal ? : no podemos. Pero sí que es posible crear una restricción check sobre la tabla/s que deseemos controlar, de tal manera que impida insertar nuevos registros o editarlos si no hemos abierto la aplicación en modo Runtime.&lt;br /&gt;&lt;br /&gt;Un ejemplo sobre una tabla llamada MiTabla :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Alter Table&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;Add&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Constraint&lt;/span&gt; Regla1 &lt;span style="color:#3333ff;"&gt;Check&lt;/span&gt;&lt;br /&gt;((&lt;span style="color:#3333ff;"&gt;Select Top&lt;/span&gt; 1 (&lt;span style="color:#cc33cc;"&gt;SysCmd&lt;/span&gt;(6) &lt;span style="color:#999999;"&gt;=&lt;/span&gt; True) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Regla &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MSysObjects)&lt;span style="color:#999999;"&gt;=&lt;/span&gt;True);&lt;br /&gt;&lt;br /&gt;Para ejecutar esta instrucción, lee el artículo anterior (Limitar nº registros en Tabla) o también puedes ejecutarla directamente mediante el Editor Sql 1.1 :&lt;br /&gt;&lt;a href="http://groups.google.com/group/raipon?hl=es"&gt;http://groups.google.com/group/raipon?hl=es&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Es de destacar, que dado el comportamiento de Access (ejecutarse siempre en el 'lado cliente'), si tenemos nuestra aplicación dividida entre Front End y Back End (Objetos &lt;=&gt; Datos), aún cuando la restricción check se guarde con los datos (ya que depende de la tabla), la función SysCmd(6) evaluará el modo de apertura desde la base de datos activa. Por tanto, este método también funciona correctamente si desde el Front End empleamos tablas vinculadas, o accedemos a los datos a través de Dao o Ado.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 09/05/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-1853999362260177262?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1853999362260177262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1853999362260177262'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/05/seguridad-con-restriccion-check.html' title='SEGURIDAD CON RESTRICCIÓN CHECK'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-1357208421659362889</id><published>2008-05-09T06:40:00.000-07:00</published><updated>2008-05-14T05:39:48.991-07:00</updated><title type='text'>LIMITAR Nº REGISTROS EN TABLA</title><content type='html'>Desde la versión 4.0 del motor Jet, se incorporaron algunas características nuevas, para mayor compatibilidad de Access con otros sistemas de bases de datos. En concreto esta versión de Jet, mediante ADO, permite crear restricciones Check sobre tablas o columnas, al estilo de Sql Server.&lt;br /&gt;Para ello, o modificamos (en versiones superiores a Access 2000) 'Herramientas' =&gt; 'Opciones' =&gt; 'Tablas o consultas' =&gt; 'Sintaxis compatible con Sql Server (ANSI 92)' =&gt; 'Esta base de datos' (Hay que marcar el check box), y ejecutamos la sentencia ddl desde la vista sql de una consulta, o deberemos utilizar ADO (esta instrucción sql fallará si intentamos ejecutarla mediante DAO).&lt;br /&gt;Una restricción Check es una regla de validación para una columna o una tabla. A diferéncia de la propiedad 'Regla de validación' de los campos de una tabla en vista diseño, con una restricción check podemos definir una regla basada en una instrucción sql (en la vista diseño de una tabla, ni siquiera podemos usar funciones agregadas de dominio como regla de validación).&lt;br /&gt;&lt;br /&gt;Ejemplo : Crear una regla de validación a nivel de tabla, que limite la cantidad de registros :&lt;br /&gt;&lt;br /&gt;(En este ejemplo, la tabla se llama MiTabla, y el número de registros que permitiremos será de 1)&lt;br /&gt;&lt;br /&gt;CurrentProject.Connection.Execute _&lt;br /&gt;"&lt;span style="color:#3333ff;"&gt;ALTER TABLE&lt;/span&gt; MiTabla&lt;span style="color:#3333ff;"&gt; ADD CONSTRAINT&lt;/span&gt; Regla1 " &amp;amp; _&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;CHECK&lt;/span&gt; ((Select &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(&lt;span style="color:#999999;"&gt;*&lt;/span&gt;) &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MiTabla) &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; 1);"&lt;br /&gt;&lt;br /&gt;Una vez ejecutado este código, el número máximo de registros que admitirá MiTabla será de uno. Tampoco podremos eliminar la tabla sin antes eliminar la restricción.&lt;br /&gt;&lt;br /&gt;Para eliminar la restricción anterior :&lt;br /&gt;&lt;br /&gt;CurrentProject.Connection.Execute _&lt;br /&gt;"&lt;span style="color:#3333ff;"&gt;ALTER TABLE&lt;/span&gt; MiTabla &lt;span style="color:#3333ff;"&gt;DROP CONSTRAINT&lt;/span&gt; Regla1"&lt;br /&gt;&lt;br /&gt;Finalmente comentar que este tipo de reglas solo están visibles en la tabla del sistema MSysObjects.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 03/01/2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-1357208421659362889?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1357208421659362889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1357208421659362889'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/05/limitar-n-registros-en-tabla.html' title='LIMITAR Nº REGISTROS EN TABLA'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-1856383161193799080</id><published>2008-04-26T04:26:00.000-07:00</published><updated>2008-04-28T11:11:37.115-07:00</updated><title type='text'>DESCOMPONER LISTA CSV EN REGISTROS</title><content type='html'>Esta idea, está basada en una genialidad de Itzik Ben-Gan, MVP de Sql Server. Si quereis ver el hilo de donde saqué el código original : &lt;a href="http://groups.google.es/group/microsoft.public.es.sqlserver/browse_thread/thread/488acae128396270/252b881f6ea6a573?lnk=gst&amp;amp;q=BEN+GAN#252b881f6ea6a573"&gt;http://groups.google.es/group/microsoft.public.es.sqlserver/browse_thread/thread/488acae128396270/252b881f6ea6a573?lnk=gst&amp;amp;q=BEN+GAN#252b881f6ea6a573&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- La clausula parameters la situamos al inicio de este lote, por exigencias del &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Editor Sql 1.1,&lt;/span&gt; &lt;span style="color:#33cc00;"&gt;pero de hecho corresponde a la consulta de selección.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- En 'Cadena' debemos escribir una lista separada por comas : ','&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PARAMETERS&lt;/span&gt; Cadena &lt;span style="color:#3333ff;"&gt;Text &lt;/span&gt;&lt;span style="color:#000000;"&gt;(255)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Creamos una tabla con números de 0 a 9 :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Nums (Num &lt;span style="color:#3333ff;"&gt;Long Primary Key&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (0);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (6);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (7);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (8);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (9);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Número,&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(Cadena,Número&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;(Número&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,Cadena,&lt;span style="color:#ff0000;"&gt;","&lt;/span&gt;)&lt;span style="color:#999999;"&gt;-&lt;/span&gt;Número&lt;span style="color:#999999;"&gt;-&lt;/span&gt;1))&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_2.Número&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10) &lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num*10) &lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_3&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; Número&lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Len&lt;/span&gt;(Cadena) &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; (Número &lt;span style="color:#999999;"&gt;&lt;&gt;&lt;/span&gt; 0 &lt;span style="color:#3366ff;"&gt;Imp&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(Cadena,Número,1)&lt;span style="color:#999999;"&gt;=&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;","&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;DROP TABLE&lt;/span&gt; Nums;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Veamos una aplicación práctica : Separar el contenido de un campo de texto, en tantos campos como palabras compongan dicho campo. Es decir, se trata de algo parecido a las consultas para separar nombre y apellidos, pero en este caso, el número de campos, puesto que se trata de una consulta de referencias cruzadas, no es fijo sino variable. Emplearemos como carácter delimitador de las palabras el 'espacio', y basaremos nuestra consulta en el campo 'NombreContacto' de la tabla 'Clientes' de Neptuno.mdb. Además, puesto que Access no permite crear una consulta de unión no basada en tabla alguna (ver ejemplo de Itzik), también será preciso disponer de una tabla (Nums) con valores entre 0 y 9 :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Nums (Num &lt;span style="color:#3333ff;"&gt;Long Primary Key&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (0);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (6);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (7);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (8);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (9);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(NombreContacto,Número,&lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;(Número,NombreContacto &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;" &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;")&lt;/span&gt;&lt;span style="color:#999999;"&gt;-&lt;/span&gt;Número))&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; NombreContacto&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_2.Número*10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num &lt;span style="color:#999999;"&gt;+&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;F&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;rom&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num*10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num&lt;span style="color:#3333ff;"&gt; As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_3, Clientes&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;Número&lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Len&lt;/span&gt;(NombreContacto) &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; "&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; NombreContacto,Número,1) &lt;span style="color:#999999;"&gt;=&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;" "&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; NombreContacto&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Segmento_"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Número&lt;span style="color:#999999;"&gt;-&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Len&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Replace&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Left&lt;/span&gt;(NombreContacto,Número),&lt;span style="color:#ff0000;"&gt;" &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;""&lt;/span&gt;))&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;DROP TABLE&lt;/span&gt; Nums;&lt;br /&gt;&lt;br /&gt;Otro ejemplo al hilo de las News. En este caso se trata de descomponer la lista embebida dentro del campo de texto, y repetir el mismo registro tantas veces como items tenga la susodicha lista :&lt;br /&gt;&lt;a href="http://groups.google.es/group/microsoft.public.es.access/browse_thread/thread/104f793a9ee8fd1e/ce28ad0e5aa2133b?lnk=raot#ce28ad0e5aa2133b"&gt;http://groups.google.es/group/microsoft.public.es.access/browse_thread/thread/104f793a9ee8fd1e/ce28ad0e5aa2133b?lnk=raot#ce28ad0e5aa2133b&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Nums (Num &lt;span style="color:#3333ff;"&gt;Long Primary Key&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (0);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (6);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (7);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (8);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (9);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; tbl_musica (Id &lt;span style="color:#3333ff;"&gt;Counter&lt;/span&gt;, Artista &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Pepe/Juan/Paco/Roberto'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Gema'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Ramon/Juan/Pepito/Roberto'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Irene/Juan/Paco/Roberto'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Alex/Juan/Paco/Roberto/Alejandro'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; tbl_musica (Artista) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;'Curro Romero'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT &lt;/span&gt;&lt;span style="color:#000000;"&gt;Id, Num, &lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(Artista,Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;InStr&lt;/span&gt;(Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1,Artista &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"/&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;"/&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;)&lt;span style="color:#999999;"&gt;-&lt;/span&gt;Num-1))&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt; Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Num&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_2, tbl_musica&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; Num&lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt;Len(Artista) &lt;span style="color:#3333ff;"&gt;And&lt;/span&gt; (&lt;span style="color:#cc33cc;"&gt;Mid&lt;/span&gt;(Artista,&lt;span style="color:#cc33cc;"&gt;IIf&lt;/span&gt;(Num&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0,1,Num),1) &lt;span style="color:#999999;"&gt;= &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"/"&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;Or&lt;/span&gt; Num&lt;span style="color:#999999;"&gt;=&lt;/span&gt;0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;DROP TABLE&lt;/span&gt; tbl_musica;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;DROP TABLE&lt;/span&gt; Nums;&lt;br /&gt;&lt;br /&gt;Puesto que las cadenas contenidas en el campo de texto son cortas, he usado una combinación que solo devuelve valores numéricos entre 0 y 100.&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 19/01/2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-1856383161193799080?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1856383161193799080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/1856383161193799080'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/descomponer-lista-csv-en-registros.html' title='DESCOMPONER LISTA CSV EN REGISTROS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-140998552199620558</id><published>2008-04-24T07:41:00.000-07:00</published><updated>2008-04-24T08:52:31.852-07:00</updated><title type='text'>USO DE CONSTANTES EN SQL</title><content type='html'>La cláusula 'Parameters', tan injustamente infrautilizada por los programadores de Access, además de dar la seguridad de que el valor que pasamos como parámetro, va a ser tratado adecuadamente según el tipo de dato, podemos emplearla para definir constantes a usar dentro de una sentencia sql.&lt;br /&gt;Veamos un ejemplo (sacado de una pregunta en las News) :&lt;br /&gt;Obtener el número de semana del mes de una fecha dada, por ejemplo para 31 de Marzo de 2008.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; ((&lt;span style="color:#cc33cc;"&gt;Day&lt;/span&gt;(#03/31/2008#) &lt;span style="color:#999999;"&gt;-&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;WeekDay&lt;/span&gt;((#03/31/2008#,2))&lt;span style="color:#999999;"&gt;\&lt;/span&gt;7)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(((&lt;span style="color:#cc33cc;"&gt;Day&lt;/span&gt;((#03/31/2008#) &lt;span style="color:#999999;"&gt;-&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;WeekDay&lt;/span&gt;((#03/31/2008#,2))&lt;span style="color:#999999;"&gt;Mod&lt;/span&gt; 7) &lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt; 0)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1&lt;br /&gt;&lt;br /&gt;Ha sido necesario escribir cuatro veces la fecha para obtener el valor : como mínimo tedioso ...&lt;br /&gt;&lt;br /&gt;Vamos a usar la propiedad 'Default' de un parámetro (no nos va a preguntar el valor, cuando ejecutemos la consulta), para crear algo parecido a una constante :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Parameters&lt;/span&gt; F &lt;span style="color:#3333ff;"&gt;DateTime&lt;/span&gt;=#03/31/2008#;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt;&lt;br /&gt;((&lt;span style="color:#cc33cc;"&gt;Day&lt;/span&gt;(F)&lt;span style="color:#999999;"&gt; -&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;WeekDay&lt;/span&gt;(F,2))&lt;span style="color:#999999;"&gt;\&lt;/span&gt;7)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Abs&lt;/span&gt;(((&lt;span style="color:#cc33cc;"&gt;Day&lt;/span&gt;(F) &lt;span style="color:#999999;"&gt;-&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;WeekDay&lt;/span&gt;(F,2))&lt;span style="color:#999999;"&gt;Mod&lt;/span&gt; 7) &lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt; 0)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1&lt;br /&gt;&lt;br /&gt;... más corto, más legible, más cómodo, ...&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa, a 01/04/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-140998552199620558?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/140998552199620558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/140998552199620558'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/uso-de-constantes-en-sql.html' title='USO DE CONSTANTES EN SQL'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-3078114764293544230</id><published>2008-04-23T22:41:00.000-07:00</published><updated>2008-04-24T07:41:26.504-07:00</updated><title type='text'>SERIES NUMÉRICAS</title><content type='html'>Cómo crear series numéricas a partir de una tabla (Nums) con diez dígitos : 0,1,2,3,4,5,6,7,8,9 en el campo Num :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Nums (Num &lt;span style="color:#3333ff;"&gt;Long Primary Key&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (0);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (1);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (2);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (3);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (4);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (5);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (6);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (7);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (8);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Nums &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (9);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de 1 a 100 :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; (TNums_1.Num*10)+Nums.Num+1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Número&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; (TNums_1.Num*10)+Nums.Num+1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de 1 a 1000 :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; (TNums_2.Número*10)+Nums.Num+1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num*10)+Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums AS TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_2, Nums&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; (TNums_2.Número*10)+Nums.Num+1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de 1 a 10.000&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; (TNums_3.Número*10)+Nums.Num+1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_2.Número*10)+Nums.Num As Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num*10)+Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_3, Nums&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; (TNums_3.Número*10)+Nums.Num+1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- de 1 a 100.000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; (TNums_4.Número*10)+Nums.Num + 1 &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_3.Número*10)+Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_2.Número*10)+Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num*10)+Nums.Num &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_2, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_3, Nums&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; TNums_4, Nums&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ORDER BY&lt;/span&gt; (TNums_4.Número*10)+Nums.Num + 1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;... etc, la idea es aprovechar, el no relacionar las tablas, para nuestro interés. La clausula Order by, la he incorporado para que si ejecutais estas consultas, obtengais un resultado ordenado y legible, pero obviamente demoran la ejecución de la 'select', así que si incorporais esta consulta dentro de otra, es recomendable eliminar el 'Order by'.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;Un ejemplo de las posibles aplicaciones de generar series numéricas de esta forma : una consulta de referencias cruzadas como calendario perpetuo :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PARAMETERS&lt;/span&gt; Año Value, Mes Value;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Temp.Número) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Dia&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CInt&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Format&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;DateSerial&lt;/span&gt;(Año,Mes,Temp.Número),&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;ww&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,2)) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Setmana&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; (TNums_1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1 &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Número&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Nums, Nums &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; TNums_1&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; (TNums_1.Num&lt;span style="color:#999999;"&gt;*&lt;/span&gt;10)&lt;span style="color:#999999;"&gt;+&lt;/span&gt;Nums.Num&lt;span style="color:#999999;"&gt;+&lt;/span&gt;1 &lt;span style="color:#999999;"&gt;&lt;=&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Day&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;DateSerial&lt;/span&gt;(Año, Mes+1,0))&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS &lt;/span&gt;Temp&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;CInt&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Format&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;DateSerial&lt;/span&gt;(Año,Mes,Temp.Número),&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;ww&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;,2))&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;WeekdayName&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Weekday&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;DateSerial&lt;/span&gt;(Año,Mes,Temp.Número),2),0,2);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Eliminamos la tabla de este ejemplo&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;span style="color:#3333ff;"&gt;DROP TABLE&lt;/span&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;Nums;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 20/12/2005.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-3078114764293544230?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3078114764293544230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/3078114764293544230'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/series-numricas.html' title='SERIES NUMÉRICAS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-776877026627781177</id><published>2008-04-22T03:51:00.000-07:00</published><updated>2008-04-22T05:36:01.716-07:00</updated><title type='text'>CAMPO AUTONUMÉRICO ¿ EDITABLE ?</title><content type='html'>En este ejemplo veremos como modificar un campo autonumérico para que permita ediciones.&lt;br /&gt;&lt;br /&gt;Advertencias previas :&lt;br /&gt;- Hoy (22/04/2008), he modificado el complemento 'Editor Sql 1.1' para que admita las instrucciones 'Grant' y 'Revoke'. Por tanto, si has obtenido el Editor en fecha anterior, bájalo de nuevo y vuélvelo a instalar.&lt;br /&gt;- Estas instrucciones solo funcionarán correctamente en bases de datos con formato 2000 y 2003.&lt;br /&gt;- El campo autonumérico efectivamente permitirá ediciones, pero solo desde lenguaje sql.&lt;br /&gt;- En principio, modificar un autonumérico es una mala praxis, pero de todas formas hay ocasiones en que puede ser útil saberlo hacer. Y aquí estamos para eso, para explicar 'cosas raras'.&lt;br /&gt;- Para este ejemplo, se utiliza el usuario 'Admin', que es el usuario predeterminado de Access.&lt;br /&gt;&lt;br /&gt;Esta secuencia de instrucciones está pensada para ejecutarla directamente como un nuevo 'Lote', en el 'Editor Sql'. Dado que está profusamente comentada, no añadiré nada más :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;/*Ejemplo del uso del permiso UpdateIdentity */ &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;br /&gt;-- Creamos la tabla&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Create Table&lt;/span&gt; Ejemplo (Id &lt;span style="color:#3333ff;"&gt;Counter Primary Key&lt;/span&gt;, Campo1 &lt;span style="color:#3333ff;"&gt;Text&lt;/span&gt; (255));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Insertamos valores de ejemplo&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Ejemplo (Campo1) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Valor1&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Ejemplo (Campo1) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Valor2&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Ejemplo (Campo1) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Valor3&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Ejemplo (Campo1) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Valor4&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Insert Into&lt;/span&gt; Ejemplo (Campo1) &lt;span style="color:#3333ff;"&gt;Values&lt;/span&gt; (&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Valor5&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Mostramos el contenido de la tabla&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Ejemplo;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Eliminamos un registro para crear una discontinuidad&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Delete&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Ejemplo &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;=&lt;/span&gt; 3;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Iniciamos secuencia para renumerar los valores, y restaurar&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- la continuidad en la serie de valores del campo 'Id'&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GRANT&lt;/span&gt; UPDATEIDENTITY &lt;span style="color:#3333ff;"&gt;ON TABLE&lt;/span&gt; Ejemplo &lt;span style="color:#3333ff;"&gt;TO&lt;/span&gt; Admin;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Update&lt;/span&gt; Ejemplo &lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;=&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;-&lt;/span&gt; 1 &lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; Id &lt;span style="color:#999999;"&gt;&gt;=&lt;/span&gt; 3;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Restauramos los permisos originales&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;REVOKE&lt;/span&gt; UPDATEIDENTITY &lt;span style="color:#3333ff;"&gt;ON TABLE&lt;/span&gt; Ejemplo &lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Admin;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Si además, queremos evitar que la inserción de un nuevo registro&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- cree otra discontinuidad (puesto que el siguiente valor para 'Id'&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- será : 6, modificamos el campo 'Id' para que el nuevo valor sea 5 :&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Alter Table&lt;/span&gt; Ejemplo &lt;span style="color:#3333ff;"&gt;Alter Column&lt;/span&gt; Id &lt;span style="color:#3333ff;"&gt;Identity&lt;/span&gt; (5, 1);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Mostramos el contenido de la tabla, renumerada&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; &lt;span style="color:#999999;"&gt;*&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Ejemplo;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;-- Finalmente, eliminamos la tabla Ejemplo&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Drop Table&lt;/span&gt; Ejemplo;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 22/04/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-776877026627781177?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/776877026627781177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/776877026627781177'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/campo-autonumrico-editable.html' title='CAMPO AUTONUMÉRICO ¿ EDITABLE ?'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-5037049244040495785</id><published>2008-04-21T09:34:00.000-07:00</published><updated>2008-04-22T05:45:26.201-07:00</updated><title type='text'>BUSCAR PALABRA EN CONSULTAS</title><content type='html'>¿ Quieres saber en qué consultas empleas una función determinda, o está implicada una tabla, o un campo concreto, o utilizas un valor 'x' para filtrar los resultados, o ... ?. Si la respuesta a esta pregunta es afirmativa, quizás te interese la siguiente consulta, pues es capaz de buscar palabras completas dentro de las consultas de la base de datos.&lt;br /&gt;Es imprescindible bajar el nivel de seguridad de la base de datos al mínimo, puesto que la sql de la consulta llamará a funciones de vba, caso contrario se producirá un error.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; T.Name&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; Name &lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; MsysObjects&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Where&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Left$&lt;/span&gt;(MsysObjects.Name,1)&lt;span style="color:#999999;"&gt;&lt;&gt;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"~"&lt;/span&gt; &lt;span style="color:#999999;"&gt;And&lt;/span&gt; Type &lt;span style="color:#999999;"&gt;= &lt;/span&gt;5 &lt;span style="color:#999999;"&gt;And&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;             Len&lt;/span&gt;(&lt;span style="color:#cc33cc;"&gt;Trim&lt;/span&gt;(Palabra_a_buscar))&lt;span style="color:#999999;"&gt;&gt;&lt;/span&gt;0&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; T&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;WHERE&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;)&lt;/span&gt; &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; Palabra_a_buscar&lt;br /&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;"CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; Palabra_a_buscar &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+,"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]*"&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;/span&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;"CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; Palabra_a_buscar &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"]*"&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;/span&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"*[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+,"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Palabra_a_buscar&lt;br /&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"*]"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Palabra_a_buscar&lt;br /&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"*]"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Palabra_a_buscar &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+,"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]*"&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;/span&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"*[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+," &lt;/span&gt;&lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]" &lt;/span&gt;&lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Palabra_a_buscar &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; "]*"&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;/span&gt;&lt;span style="color:#999999;"&gt;Or&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;/span&gt;&lt;span style="color:#cc33cc;"&gt;Eval&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;CurrentDb.QueryDefs('"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Name &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;').Sql&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;"&lt;/span&gt;) &lt;span style="color:#999999;"&gt;Like&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"*[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+,"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Palabra_a_buscar &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"[ -/,',:,;,&gt;,&lt;,&lt;&gt;,=,^,\,[,-,+,"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Chr&lt;/span&gt;(13) &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"]*"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 26/03/2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-5037049244040495785?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5037049244040495785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/5037049244040495785'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/buscar-palabra-en-consultas.html' title='BUSCAR PALABRA EN CONSULTAS'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4047108984287742759.post-640837405551331899</id><published>2008-04-21T00:11:00.000-07:00</published><updated>2008-05-21T22:51:21.386-07:00</updated><title type='text'>CONSULTA DE REFERENCIAS CRUZADAS DE MÚLTIPLES VALORES.</title><content type='html'>Los ejemplos están basados en la base de datos Neptuno.mdb.&lt;br /&gt;En principio, una consulta de referencias cruzadas solo puede tener una expresión para calcular los encabezados de columna. Es decir, como ejemplo : no podemos obtener el número de pedidos por empleado y año, y al mismo tiempo, la fecha del último pedido por empleado y año.&lt;br /&gt;Para solucionar este inconveniente, desde Microsoft proponen esta solución : http://support.microsoft.com/kb/304458/es&lt;br /&gt;El inconveniente de este método es que necesita conocer previamente los nombres de las columnas generadas por las consultas de referencias cruzadas, pues desde la consulta donde se combinan las dos consultas previas, se hace referencia explícita a cada uno de los campos por su nombre. Esto, si las consultas devuelven un número fijo de campos no es problema, pero si el número de campos es variable ...&lt;br /&gt;Una solución seria no llamar los campos directamente, sino utilizar el asterisco para seleccionarlos todos :&lt;br /&gt;Supongamos que tenemos estas dos consultas :&lt;br /&gt;&lt;br /&gt;RefCruzPedidosCantidad&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(Pedidos.IdPedido) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; CuentaDeIdPedido&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Pedidos.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; Pedidos.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt; "Pedidos_" &amp;amp; &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido);&lt;br /&gt;&lt;br /&gt;RefCruzPedidosÚltimo&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;Max&lt;/span&gt;(Pedidos.FechaPedido) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; MaxDeFechaPedido&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT &lt;/span&gt;Pedidos.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; Pedidos.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt; "Último_" &amp;amp; &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido);&lt;br /&gt;&lt;br /&gt;Para mostrar todos los resultados a la vez :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; RefCruzPedidosCantidad.&lt;span style="color:#999999;"&gt;*&lt;/span&gt;, RefCruzPedidosÚltimo.&lt;span style="color:#999999;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM &lt;/span&gt;RefCruzPedidosCantidad &lt;span style="color:#3333ff;"&gt;INNER JOIN &lt;/span&gt;RefCruzPedidosÚltimo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;ON&lt;/span&gt; RefCruzPedidosCantidad.IdEmpleado = RefCruzPedidosÚltimo.IdEmpleado;&lt;br /&gt;&lt;br /&gt;Bien, efectivamente ahora se muestran todas las columnas sin necesidad de llamarlas de forma explícita. Sin embargo nos encontramos con el inconveniente de que el campo IdEmpleado aparece dos veces.&lt;br /&gt;Para solucionar este problema, un método alternativo, que gracias a una consulta de unión, embebida dentro de la consulta de referencias cruzadas, permite obtener directamente los resultados :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Temp.Valor)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Temp.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select&lt;/span&gt; IdEmpleado, Count(IdPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Valor, Year(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Año,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Pedidos_"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Año &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Campo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group by&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union Select&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Max&lt;/span&gt;(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Valor, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Año,&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;"Último_"&lt;/span&gt; &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; Año &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Campo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group by&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido)&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Temp&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt; Campo;&lt;br /&gt;&lt;br /&gt;Finalmente, debido a que las columnas se generan en base al campo 'Campo', la consulta anterior muestra los campos en este orden :&lt;br /&gt;IdEmpleado, Pedidos_1996, Pedidos_1997, Pedidos_1998, Último_1996, etc&lt;br /&gt;Si queremos que aparezcan agrupadas por año, es necesario cambiar la expresión que genera los títulos de columna para que establezca otro orden :&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;TRANSFORM&lt;/span&gt; &lt;span style="color:#cc33cc;"&gt;First&lt;/span&gt;(Temp.Valor)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;SELECT&lt;/span&gt; Temp.IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;FROM&lt;/span&gt;&lt;br /&gt;(&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Select &lt;/span&gt;IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Count&lt;/span&gt;(IdPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Valor, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Año,&lt;br /&gt;Año &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"_Pedidos"&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Campo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group by&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Union Select&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Max&lt;/span&gt;(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Valor, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido) &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Año,&lt;br /&gt;Año &lt;span style="color:#999999;"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"_Último"&lt;/span&gt; &lt;span style="color:#3333ff;"&gt;As&lt;/span&gt; Campo&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;From&lt;/span&gt; Pedidos&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Group by&lt;/span&gt; IdEmpleado, &lt;span style="color:#cc33cc;"&gt;Year&lt;/span&gt;(FechaPedido)&lt;br /&gt;) &lt;span style="color:#3333ff;"&gt;AS&lt;/span&gt; Temp&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;GROUP BY&lt;/span&gt; IdEmpleado&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;PIVOT&lt;/span&gt; Campo;&lt;br /&gt;&lt;br /&gt;Ahora el orden de las columnas es :&lt;br /&gt;IdEmpleado, 1996_Pedidos, 1996_Último, 1997_Pedidos, 1997_Último, etc&lt;br /&gt;&lt;br /&gt;Ramon Poch, raipon. Terrassa a 05/01/2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4047108984287742759-640837405551331899?l=sqlraipon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/640837405551331899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4047108984287742759/posts/default/640837405551331899'/><link rel='alternate' type='text/html' href='http://sqlraipon.blogspot.com/2008/04/consulta-de-referencias-cruzadas-de.html' title='CONSULTA DE REFERENCIAS CRUZADAS DE MÚLTIPLES VALORES.'/><author><name>Ramon Poch, raipon</name><uri>http://www.blogger.com/profile/06015558697033574494</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
