¿Cómo puedo SELECCIONAR filas con MAX (valor de columna), DISTINCT por otra columna en SQL?


768

Mi mesa es:

id  home  datetime     player   resource
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399 
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
3  | 10  | 03/03/2009 | john   | 300
4  | 11  | 03/03/2009 | juliet | 200
6  | 12  | 03/03/2009 | borat  | 500
7  | 13  | 24/12/2008 | borat  | 600
8  | 13  | 01/01/2009 | borat  | 700

Necesito seleccionar cada distinto home tenga el valor máximo de datetime.

El resultado sería:

id  home  datetime     player   resource 
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
8  | 13  | 01/01/2009 | borat  | 700

Yo he tratado:

-- 1 ..by the MySQL manual: 

SELECT DISTINCT
  home,
  id,
  datetime AS dt,
  player,
  resource
FROM topten t1
WHERE datetime = (SELECT
  MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC

No funciona El conjunto de resultados tiene 130 filas, aunque la base de datos contiene 187. El resultado incluye algunos duplicados de home.

-- 2 ..join

SELECT
  s1.id,
  s1.home,
  s1.datetime,
  s1.player,
  s1.resource
FROM topten s1
JOIN (SELECT
  id,
  MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
  ON s1.id = s2.id
ORDER BY datetime 

No Da todos los registros.

-- 3 ..something exotic: 

Con varios resultados.

Respuestas:


940

¡Estás muy cerca! Todo lo que necesita hacer es seleccionar AMBOS el hogar y la fecha y hora máximas, luego unirse nuevamente a la toptentabla en AMBOS campos:

SELECT tt.*
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

55
Pruébelo para ver si hay dos fechas máximas iguales en la misma casa (con diferentes jugadores)
Maksym Gontar

55
Creo que la forma clásica de hacer esto es con una unión natural: "SELECCIONAR tt. * DESDE topten tt NATURAL JOIN (SELECCIONAR inicio, MAX (fecha y hora) COMO fecha y hora desde topten GRUPO POR hogar) más reciente;" La misma consulta exactamente, pero posiblemente más legible
Parker

32
¿Qué pasa si hay dos filas que tienen los mismos valores de campo 'home' y 'datetime'?
Kemal Duran

3
@Young, el problema con su consulta es que puede regresar id, playery resourcede una fila no máxima para un hogar dado, es decir, para home = 10, puede obtener: 3 | 10 | 04/03/2009 | john | 300 En otras palabras, no garantiza que todas las columnas de una fila en el conjunto de resultados pertenezcan a max (fecha y hora) para el hogar dado.
Sábado

1
El problema @ me1111 con su consulta es que puede / no puede devolver la fila con max (fecha y hora) para un hogar dado. Siendo GROUP BY razón buscará cualquier fila al azar para cada hogar y ORDER BY será sólo una especie del general todo el resultado como la producida por GROUP BY
sactiw

87

La MySQLsolución más rápida , sin consultas internas y sin GROUP BY:

SELECT m.*                    -- get the row that contains the max value
FROM topten m                 -- "m" from "max"
    LEFT JOIN topten b        -- "b" from "bigger"
        ON m.home = b.home    -- match "max" row with "bigger" row by `home`
        AND m.datetime < b.datetime           -- want "bigger" than "max"
WHERE b.datetime IS NULL      -- keep only if there is no bigger than max

Explicacion :

Únete a la tabla consigo mismo usando la homecolumna. El uso de LEFT JOINgarantiza que todas las filas de la tabla maparezcan en el conjunto de resultados. Aquellos que no tienen una coincidencia en la tabla btendrán NULLs para las columnas de b.

La otra condición en el JOINpide que coincida solo con las filas bque tienen un valor mayor en la datetimecolumna que la fila de m.

Usando los datos publicados en la pregunta, LEFT JOINproducirá estos pares:

+------------------------------------------+--------------------------------+
|              the row from `m`            |    the matching row from `b`   |
|------------------------------------------|--------------------------------|
| id  home  datetime     player   resource | id    home   datetime      ... |
|----|-----|------------|--------|---------|------|------|------------|-----|
| 1  | 10  | 04/03/2009 | john   | 399     | NULL | NULL | NULL       | ... | *
| 2  | 11  | 04/03/2009 | juliet | 244     | NULL | NULL | NULL       | ... | *
| 5  | 12  | 04/03/2009 | borat  | 555     | NULL | NULL | NULL       | ... | *
| 3  | 10  | 03/03/2009 | john   | 300     | 1    | 10   | 04/03/2009 | ... |
| 4  | 11  | 03/03/2009 | juliet | 200     | 2    | 11   | 04/03/2009 | ... |
| 6  | 12  | 03/03/2009 | borat  | 500     | 5    | 12   | 04/03/2009 | ... |
| 7  | 13  | 24/12/2008 | borat  | 600     | 8    | 13   | 01/01/2009 | ... |
| 8  | 13  | 01/01/2009 | borat  | 700     | NULL | NULL | NULL       | ... | *
+------------------------------------------+--------------------------------+

Finalmente, la WHEREcláusula mantiene solo los pares que tienen NULLs en las columnas de b(están marcados con* en la tabla anterior); Esto significa que, debido a la segunda condición de la JOINcláusula, la fila seleccionada mtiene el mayor valor en la columna datetime.

Lea el libro Antipatterns de SQL: Evitar las trampas de la programación de bases de datos para obtener otros consejos de SQL.


Con SQLite, el primero es mucho más lento que la versión de La Voie cuando no hay índice en la columna coincidente (es decir, "hogar"). (Probado con 24k filas que resultan en 13k filas)
Thomas Tempelmann

10
Esta es la mejor respuesta, si muestra el plan de ejecución, verá un paso menos con esta consulta
TlmaK0

lo que ocurrirá si 2 filas tienen el mismo homey datetime, y el datetimees el máximo para ese particular home?
Istiaque Ahmed

Ambas filas aparecen en el conjunto de resultados. Esta respuesta es una prueba de concepto. En su código real, probablemente tenga otro criterio para seleccionar solo uno de ellos en esta situación (tal vez el primero o el último o use otra columna para decidir). Simplemente agregue este criterio como una nueva condición en la ONcláusula. Fe ... ON ... AND m.id < b.idpara mantener la entrada más reciente (la que tiene la mayor id) cuando dos filas tienen los mismos valores en homey datetimecolumnas y es el máximo datetime.
axiac

¿Qué índices se optimizarían mejor para una consulta como esta?
AjaxLeung

73

Aquí va la versión T-SQL :

-- Test data
DECLARE @TestTable TABLE (id INT, home INT, date DATETIME, 
  player VARCHAR(20), resource INT)
INSERT INTO @TestTable
SELECT 1, 10, '2009-03-04', 'john', 399 UNION
SELECT 2, 11, '2009-03-04', 'juliet', 244 UNION
SELECT 5, 12, '2009-03-04', 'borat', 555 UNION
SELECT 3, 10, '2009-03-03', 'john', 300 UNION
SELECT 4, 11, '2009-03-03', 'juliet', 200 UNION
SELECT 6, 12, '2009-03-03', 'borat', 500 UNION
SELECT 7, 13, '2008-12-24', 'borat', 600 UNION
SELECT 8, 13, '2009-01-01', 'borat', 700

-- Answer
SELECT id, home, date, player, resource 
FROM (SELECT id, home, date, player, resource, 
    RANK() OVER (PARTITION BY home ORDER BY date DESC) N
    FROM @TestTable
)M WHERE N = 1

-- and if you really want only home with max date
SELECT T.id, T.home, T.date, T.player, T.resource 
    FROM @TestTable T
INNER JOIN 
(   SELECT TI.id, TI.home, TI.date, 
        RANK() OVER (PARTITION BY TI.home ORDER BY TI.date) N
    FROM @TestTable TI
    WHERE TI.date IN (SELECT MAX(TM.date) FROM @TestTable TM)
)TJ ON TJ.N = 1 AND T.id = TJ.id

EDITAR
Desafortunadamente, no hay función RANK () OVER en MySQL.
Pero se puede emular, consulte Funciones de Emulación Analítica (Clasificación AKA) con MySQL .
Entonces esta es la versión de MySQL :

SELECT id, home, date, player, resource 
FROM TestTable AS t1 
WHERE 
    (SELECT COUNT(*) 
            FROM TestTable AS t2 
            WHERE t2.home = t1.home AND t2.date > t1.date
    ) = 0

lo siento amigo, # 1064 - Tienes un error en tu sintaxis SQL; consulte el manual que corresponde a la versión de su servidor MySQL para obtener la sintaxis correcta para usar cerca de '() SOBRE (PARTICIÓN POR ORDEN krd POR DESC diurno) N DESDE @rapsa) M DONDE N =' en la línea 1
Kaptah

2
ah, entonces estás usando MySQL. ¡Eso es de lo que deberías comenzar! Actualizaré la respuesta pronto.
Maksym Gontar

@MaxGontar, tu solución mysql es genial, gracias. ¿Qué pasa si en su @_TestTable elimina la fila # 1>: SELECCIONE 1, 10, '2009-03-04', 'john', 399, esto es, qué pasa si tiene una sola fila para un valor de vivienda dado? gracias.
egidiocs

2
ERROR: Reemplace "RANK ()" con "ROW_NUMBER ()". Si tiene un empate (causado por un valor de fecha duplicado) tendrá dos registros con "1" para N.
MikeTeeVee

29

Esto funcionará incluso si tiene dos o más filas para cada una homecon igual DATETIME's:

SELECT id, home, datetime, player, resource
FROM   (
       SELECT (
              SELECT  id
              FROM    topten ti
              WHERE   ti.home = t1.home
              ORDER BY
                      ti.datetime DESC
              LIMIT 1
              ) lid
       FROM   (
              SELECT  DISTINCT home
              FROM    topten
              ) t1
       ) ro, topten t2
WHERE  t2.id = ro.lid

campo de tapa agregado en la tabla, No Good
Kaptah

1
Este no se ejecutó en PHPMyAdmin. La página se actualiza pero no hay resultado ni error ...
Kaptah

WHERE ti.home = t1.home- ¿Puedes explicar la sintaxis?
Istiaque Ahmed

@IstiaqueAhmed: ¿qué es exactamente lo que no entiendes aquí? Es una consulta correlacionada, y la expresión que menciona es una condición de correlación.
Quassnoi

@Quassnoi, la selectconsulta que tiene la línea WHERE ti.home = t1.home no necesita la FROMcláusula que define t1. Entonces, ¿cómo se usa?
Istiaque Ahmed

26

Creo que esto te dará el resultado deseado:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

PERO si necesita otras columnas también, solo haga una unión con la tabla original (verifique la Michael La Voierespuesta)

Atentamente.


8
Necesita otras columnas también.
Quassnoi

44
id, hogar, fecha y hora, jugador, recurso
Quassnoi

17

Dado que las personas parecen seguir encontrándose con este hilo (la fecha del comentario varía de 1.5 años) no es esto mucho más simple:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

No se necesitan funciones de agregación ...

Salud.


66
Esto no parece funcionar. Mensaje de error: la columna 'x' no es válida en la lista de selección porque no está contenida ni en una función agregada ni en la cláusula GROUP BY.
Fowl

Esto definitivamente no funcionará en SQL Server u Oracle, aunque parece que podría funcionar en MySQL.
ErikE

¡Esto es realmente hermoso! ¿Como funciona esto? ¿Al usar DESC y la columna de retorno de grupo predeterminada? Entonces, si lo cambié a ASC de fecha y hora, ¿devolvería la primera fila de cada hogar?
wayofthefuture

¡Esto es brillante!
Dog Lover

Este método directo no funciona si tiene columnas no agregadas (en MySQL).
user3562927

11

También puede probar este y para tablas grandes el rendimiento de la consulta será mejor. Funciona cuando no hay más de dos registros para cada hogar y sus fechas son diferentes. Una mejor consulta general de MySQL es una de Michael La Voie anterior.

SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
FROM   t_scores_1 t1 
INNER JOIN t_scores_1 t2
   ON t1.home = t2.home
WHERE t1.date > t2.date

O en el caso de Postgres o aquellos dbs que proporcionan funciones analíticas intente

SELECT t.* FROM 
(SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
  , row_number() over (partition by t1.home order by t1.date desc) rw
 FROM   topten t1 
 INNER JOIN topten t2
   ON t1.home = t2.home
 WHERE t1.date > t2.date 
) t
WHERE t.rw = 1

¿Es correcta esta respuesta? Traté de usarlo, pero parece no seleccionar el registro con la fecha más nueva para 'inicio', sino que solo elimina el registro con la fecha más antigua. Aquí hay un ejemplo: SQLfiddle
marcin93w

1
@kidOfDeath - Actualicé mi respuesta con el contexto y la consulta de Postgres
Shiva

Con SQLite, el primero es mucho más lento que la versión de La Voie cuando no hay índice en la columna coincidente (es decir, "inicio").
Thomas Tempelmann

8

Esto funciona en Oracle:

with table_max as(
  select id
       , home
       , datetime
       , player
       , resource
       , max(home) over (partition by home) maxhome
    from table  
)
select id
     , home
     , datetime
     , player
     , resource
  from table_max
 where home = maxhome

1
¿Cómo elige esto la fecha y hora máxima? pidió agrupar por hogar y seleccionar max datetime. No veo cómo esto hace eso.
n00b

8
SELECT  tt.*
FROM    TestTable tt 
INNER JOIN 
        (
        SELECT  coord, MAX(datetime) AS MaxDateTime 
        FROM    rapsa 
        GROUP BY
                krd 
        ) groupedtt
ON      tt.coord = groupedtt.coord
        AND tt.datetime = groupedtt.MaxDateTime

8

Pruebe esto para SQL Server:

WITH cte AS (
   SELECT home, MAX(year) AS year FROM Table1 GROUP BY home
)
SELECT * FROM Table1 a INNER JOIN cte ON a.home = cte.home AND a.year = cte.year

5
SELECT c1, c2, c3, c4, c5 FROM table1 WHERE c3 = (select max(c3) from table)

SELECT * FROM table1 WHERE c3 = (select max(c3) from table1)

5

Aquí está la versión de MySQL que imprime solo una entrada donde hay duplicados MAX (fecha y hora) en un grupo.

Puede probar aquí http://www.sqlfiddle.com/#!2/0a4ae/1

Data de muestra

mysql> SELECT * from topten;
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    3 |   10 | 2009-03-03 00:00:00 | john   |      300 |
|    4 |   11 | 2009-03-03 00:00:00 | juliet |      200 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    6 |   12 | 2009-03-03 00:00:00 | borat  |      500 |
|    7 |   13 | 2008-12-24 00:00:00 | borat  |      600 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+

Versión MySQL con variable de usuario

SELECT *
FROM (
    SELECT ord.*,
        IF (@prev_home = ord.home, 0, 1) AS is_first_appear,
        @prev_home := ord.home
    FROM (
        SELECT t1.id, t1.home, t1.player, t1.resource
        FROM topten t1
        INNER JOIN (
            SELECT home, MAX(datetime) AS mx_dt
            FROM topten
            GROUP BY home
          ) x ON t1.home = x.home AND t1.datetime = x.mx_dt
        ORDER BY home
    ) ord, (SELECT @prev_home := 0, @seq := 0) init
) y
WHERE is_first_appear = 1;
+------+------+--------+----------+-----------------+------------------------+
| id   | home | player | resource | is_first_appear | @prev_home := ord.home |
+------+------+--------+----------+-----------------+------------------------+
|    9 |   10 | borat  |      700 |               1 |                     10 |
|   10 |   11 | borat  |      700 |               1 |                     11 |
|   12 |   12 | borat  |      700 |               1 |                     12 |
|    8 |   13 | borat  |      700 |               1 |                     13 |
+------+------+--------+----------+-----------------+------------------------+
4 rows in set (0.00 sec)

Outout de respuestas aceptadas

SELECT tt.*
FROM topten tt
INNER JOIN
    (
    SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home
) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+
7 rows in set (0.00 sec)

Aunque me encanta esta respuesta, ya que me está ayudando mucho, tengo que señalar una falla importante, que depende del sistema mysql usado. Básicamente, esta solución se basa en la cláusula ORDER BY en la subselección. Esto PODRÍA, o NO PODRÍA funcionar en varios entornos mysql. No lo he probado en MySQL puro, pero seguro que esto no funciona CONFIABLEMENTE en MariaDB 10.1, como se explica aquí stackoverflow.com/questions/26372511/... pero el mismo código funciona bien en el Servidor Percona. Para ser precisos, PODRÍAS o NO PODRÍAS obtener los mismos resultados, dependiendo de la cantidad de columnas t1.
Radek

El ejemplo de esta declaración es que en MariaDB 10.1 funcionó, cuando usé 5 columnas de la tabla t1. Tan pronto como agregué la sexta columna, obviamente jugando con el tipo de datos "naturales" en la tabla original, dejó de funcionar. La razón es que los datos en la subselección se desordenaron y, por lo tanto, tuve la condición "is_first_appear = 1" cumplida varias veces. El mismo código, con los mismos datos, funcionó bien en Percona.
Radek

5

Otra forma de obtener la fila más reciente por grupo usando una subconsulta que básicamente calcula un rango para cada fila por grupo y luego filtra las filas más recientes como con rank = 1

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and a.`datetime` < b.`datetime`
) +1 = 1

MANIFESTACIÓN

Aquí está la demostración visual del rango no para cada fila para una mejor comprensión

Al leer algunos comentarios, ¿qué pasa si hay dos filas que tienen los mismos valores de campo 'home' y 'datetime'?

La consulta anterior fallará y devolverá más de 1 filas para la situación anterior. Para encubrir esta situación, será necesario otro criterio / parámetro / columna para decidir qué fila se debe tomar y que corresponde a la situación anterior. Al ver el conjunto de datos de muestra, supongo que hay una columna de clave principalid que debe establecerse en incremento automático. Entonces, podemos usar esta columna para elegir la fila más reciente ajustando la misma consulta con la ayuda de CASEdeclaraciones como

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and  case 
       when a.`datetime` = b.`datetime`
       then a.id < b.id
       else a.`datetime` < b.`datetime`
       end
) + 1 = 1

MANIFESTACIÓN

La consulta anterior elegirá la fila con la identificación más alta entre los mismos datetimevalores

demostración visual para el rango no para cada fila


2

¿Por qué no usar: SELECT home, MAX (datetime) AS MaxDateTime, player, resource FROM topten GROUP BY home ¿Me perdí algo?


44
Eso solo sería válido con MySQL, y solo versiones anteriores a 5.7 (?) O posteriores a 5.7 con ONLY_FULL_GROUP_BY deshabilitado, ya que está SELECCIONANDO columnas que no se han agregado / GRUPADO (jugador, recurso), lo que significa que MySQL proporcionará valores elegidos al azar para esos Dos campos de resultados. No sería un problema para la columna del jugador ya que eso se correlaciona con la columna de inicio, pero la columna de recursos no se correlacionaría con la columna de inicio o fecha y hora y no puede garantizar qué valor de recurso recibiría.
simpleuser

+1 para la explicación, PERO con la pregunta formulada, esta consulta no devolverá el expectedresultado en MySQL versión 5.6 y beforedudo mucho que se comporte de otra manera en MySQL versión 5.7 y after.
Sábado

@simpleuser, `No sería un problema para la columna del jugador ya que eso se correlaciona con la columna de inicio`. ¿Puede explicar más?
Istiaque Ahmed

@IstiaqueAhmed cuando lo miro nuevamente, esa declaración es incorrecta. Pensé que cada jugador siempre tenía el mismo valor de casa, pero ahora veo que no lo tienen, por lo que también se producirá el mismo problema de selección aleatoria para esa columna
usuario simple

1

Prueba esto

select * from mytable a join
(select home, max(datetime) datetime
from mytable
group by home) b
 on a.home = b.home and a.datetime = b.datetime

Saludos K


55
Pruébelo para ver si hay dos fechas máximas iguales en la misma casa (con diferentes jugadores)
Maksym Gontar

El alias de max(datetime) es datetime. ¿No hará ningún problema?
Istiaque Ahmed

¿Cómo se datetimeselecciona el más alto ?
Istiaque Ahmed

1

esta es la consulta que necesitas:

 SELECT b.id, a.home,b.[datetime],b.player,a.resource FROM
 (SELECT home,MAX(resource) AS resource FROM tbl_1 GROUP BY home) AS a

 LEFT JOIN

 (SELECT id,home,[datetime],player,resource FROM tbl_1) AS b
 ON  a.resource = b.resource WHERE a.home =b.home;

¿Puedes explicar tu respuesta?
Istiaque Ahmed

1

@Michae La respuesta aceptada funcionará bien en la mayoría de los casos, pero falla para una de las siguientes.

En caso de que haya 2 filas con HomeID y Datetime iguales, la consulta devolverá ambas filas, no HomeID diferente según sea necesario, para eso agregar Distinct en la consulta como se muestra a continuación.

SELECT DISTINCT tt.home  , tt.MaxDateTime
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

el resultado muestra - "# 1054 - Columna desconocida 'tt.MaxDateTime' en 'lista de campos'"
Istiaque Ahmed

@IstiaqueAhmed ¿tiene MaxDatetime archivado, es decir, cualquier nombre de columna como ese ...?
Manoj Kargeti

No, la tabla en OP no tiene ninguna columna de este tipo.
Istiaque Ahmed

el error también dice lo mismo por favor ... ¿qué es exactamente lo que quieres hacer? ¿Puedes enviar la estructura de la tabla y tu consulta?
Manoj Kargeti

1

Espero que debajo de la consulta se obtenga el resultado deseado:

Select id, home,datetime,player,resource, row_number() over (Partition by home ORDER by datetime desc) as rownum from tablename where rownum=1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.