2009-08-11 14 views
12
 
id | photo title  | created_date 

XEi43 | my family  | 2009 08 04 
dDls | friends group | 2009 08 05 
32kJ | beautiful place | 2009 08 06 
EOIk | working late | 2009 08 07 

Di que tengo el id 32kJ. ¿Cómo obtendré la siguiente fila o la anterior?sql tirando de una fila para la fila siguiente o anterior de una fila actual

+0

El concepto de "siguiente" o "anterior" depende del orden. Probablemente lo haga de forma programática, recuperando un DataSet usando ado.net u otra tecnología, y luego recorriendo los registros de esa representación de los datos. – pvieira

+1

Es fácilmente factible si su campo de Id. Fue secuencial y numérico, el hecho de que esté usando caracteres alfabéticos lo hace mucho más complicado. http: // www.scottklarr.com/topic/111/how-to-select-previousnext-rows-in-mysql/ –

Respuesta

17

Esto es lo que uso para buscar registros anteriores/siguientes. Cualquier columna de la tabla se puede utilizar como columna de ordenación, y no se une o se requieren cortes desagradables:

Siguiente conjunto de datos (fecha mayor de registro actual):

SELECT id, title, MIN(created) AS created_date 
FROM photo 
WHERE created > 
    (SELECT created FROM photo WHERE id = '32kJ') 
GROUP BY created 
ORDER BY created ASC 
LIMIT 1; 

Registro anterior (fecha menos del actual registro):

SELECT id, title, MAX(created) AS created_date 
FROM photo 
WHERE created < 
    (SELECT created FROM photo WHERE id = '32kJ') 
GROUP BY created 
ORDER BY created DESC 
LIMIT 1; 

Ejemplo:

CREATE TABLE `photo` (
    `id` VARCHAR(5) NOT NULL, 
    `title` VARCHAR(255) NOT NULL, 
    `created` DATETIME NOT NULL, 
    INDEX `created` (`created` ASC), 
    PRIMARY KEY (`id`) 
) 
ENGINE = InnoDB; 

INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('XEi43', 'my family',  '2009-08-04'); 
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('dDls', 'friends group', '2009-08-05'); 
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('32kJ', 'beautiful place', '2009-08-06'); 
INSERT INTO `photo` (`id`, `title`, `created`) VALUES ('EOIk', 'working late', '2009-08-07'); 

SELECT * FROM photo ORDER BY created; 
+-------+-----------------+---------------------+ 
| id | title   | created    | 
+-------+-----------------+---------------------+ 
| XEi43 | my family  | 2009-08-04 00:00:00 | 
| dDls | friends group | 2009-08-05 00:00:00 | 
| 32kJ | beautiful place | 2009-08-06 00:00:00 | 
| EOIk | working late | 2009-08-07 00:00:00 | 
+-------+-----------------+---------------------+ 


SELECT id, title, MIN(created) AS next_date 
FROM photo 
WHERE created > 
    (SELECT created FROM photo WHERE id = '32kJ') 
GROUP BY created 
ORDER BY created ASC 
LIMIT 1; 

+------+--------------+---------------------+ 
| id | title  | next_date   | 
+------+--------------+---------------------+ 
| EOIk | working late | 2009-08-07 00:00:00 | 
+------+--------------+---------------------+ 

SELECT id, title, MAX(created) AS prev_date 
FROM photo 
WHERE created < 
    (SELECT created FROM photo WHERE id = '32kJ') 
GROUP BY created 
ORDER BY created DESC 
LIMIT 1; 

+------+---------------+---------------------+ 
| id | title   | prev_date   | 
+------+---------------+---------------------+ 
| dDls | friends group | 2009-08-05 00:00:00 | 
+------+---------------+---------------------+ 
+0

no lo he intentado, pero estoy seguro de que esto sacará el resultado, solo me pregunto, cuál es la consulta más rápida. – Basit

+0

¿Por qué usa funciones agregadas si ya ha ordenado los resultados y lo ha limitado a 1 fila? – PhoneixS

0

horrible truco - No me gusta esto, pero podría funcionar ..

with yourresult as 
(
select id, photo_title, created_date, ROW_NUMBER() over(order by created_date) as 'RowNum' from your_table 
) 
-- Previous 
select * from yourresult where RowNum = ((select RowNum from yourresult where id = '32kJ') -1) 
-- Next 
select * from yourresult where RowNum = ((select RowNum from yourresult where id = '32kJ') +1) 

Eso de alguna utilidad?

+0

¿funcionaría en mysql? – Basit

+0

probablemente no, desafortunadamente. Es MS SQL - Tuve un almuerzo de quik think ayer, pero no tuve mucho tiempo - Voy a tener otra mirada esta noche ... – Tikeb

+0

estoy recibiendo este error # 1064 - Usted tiene un error en su sintaxis de SQL; revise el manual que corresponde a su versión del servidor MySQL para la sintaxis correcta para usar cerca de 'con su resultado como ( seleccione photo_id, title, fecha_adicted, ROW_NUMBER() sobre (ord' en la línea 1 – Basit

2

me doy cuenta de que está utilizando MySQL, pero apenas para la referencia, aquí es cómo se podría hacer esto utilizando las funciones analíticas de Oracle avance y retroceso:

select empno, ename, job, 
    lag(ename, 1) over (order by ename) as the_guy_above_me, 
    lead(ename, 2) over (order by ename) as the_guy_two_rows_below_me 
from emp 
order by ename 

Creo que hay una razón por Oracle cuesta dinero y MySQL es gratis ... :-)

Esta página muestra how to emulate analytic functions in MySQL.

+2

Obtiene estas funciones analíticas en Postgres 8.4 también: p – araqnid

2

¿Quería la fila siguiente/anterior por fecha? Si es así, puede hacer esto:

select MyTable.* 
from MyTable 
join 
    (select id 
    from MyTable 
    where created_date < (select created_date from MyTable where id = '32kJ') 
    order by created_date desc, id desc 
    limit 1 
) LimitedTable on LimitedTable.id = MyTable.fund_id; 
+0

, si ... intentaré esto. – Basit

+0

jeremy stein, ¿puede decirme también, si puedo verificar la posición de la fila actual a partir del total de filas (mostrando 6 de 100 filas), puede esta consulta hacerlo o ¿Tendría que ampliar la consulta, si se extiende, cómo y qué debo hacer? Solo quiero saber también la posición de la fila actual a partir de las filas totales, así puedo hacer que funcione con la siguiente y la anterior ... para que los usuarios saber dónde están, como en Facebook. – Basit

+0

Quiero agregar el posicionamiento también para la fila actual, otra vez la siguiente y la anterior ... ¿cómo puedo hacer eso? http://stackoverflow.com/questions/2036425/little-complex-sql -row-postion – Basit

1

Usando Mike's truco MAX/MIN podemos hacer previos \ next saltos para todo tipo de cosas. Este ejemplo de msAccess devolverá el cierre anterior para cada registro en una tabla de datos bursátiles. Nota: el '< =' es para fines de semana y días festivos.

SELECT 
    tableName.Date, 
    tableName.Close, 
    (SELECT Close 
     FROM tableName 
     WHERE Date = (SELECT MAX(Date) FROM tableName 
        WHERE Date <= iJoined.yesterday) 
    ) AS previousClose 
FROM 
(SELECT Date, DateAdd("d",-1, Date) AS yesterday FROM tableName) 
    AS iJoined 
INNER JOIN 
    tableName ON tableName.Date=iJoined.Date; 

... 'ayer' muestra el uso de una función ( Fecha-1) saltar; podríamos haber utilizado simplemente ...

(SELECT Date FROM tableName) AS iJoined 
    /* previous record */ 
(SELECT MAX(Date) FROM tableName WHERE Date < iJoined.Date) 
    /* next record */ 
(SELECT MIN(Date) FROM tableName WHERE Date > iJoined.Date) 

El truco es que puede anterior \ siguiente # de lo (s) con MAX \ MIN y una función de salto()

0

que considera como principal ID clave en la tabla (y como "número de fila"), y lo usó para comparar cada registro con el registro anterior. El siguiente código debe funcionar.

CREATE SCHEMA temp 
create table temp.emp (id integer,name varchar(50), salary varchar(50)); 
insert into temp.emp values(1,'a','25000'); 
insert into temp.emp values(2,'b','30000'); 
insert into temp.emp values(3,'c','35000'); 
insert into temp.emp values(4,'d','40000'); 
insert into temp.emp values(5,'e','45000'); 
insert into temp.emp values(6,'f','20000'); 

select * from temp.emp 

SELECT 
    current.id, current.name, current.salary, 
    case 
     when current.id = 1 then current.salary 
     else 
      case 
       when current.salary > previous.salary then previous.salary 
       else current.salary 
      end 
    end 
FROM 
    temp.emp AS current 
    LEFT OUTER JOIN temp.emp AS previous 
    ON current.id = previous.id + 1 
+0

¿Necesita solución para comparar el registro anterior y el siguiente en una sola consulta? Así que trate arriba ... –

Cuestiones relacionadas