Tengo una situación bastante interesante. Tengo una base de datos SQLite llena de direcciones y mensajes (las direcciones no son únicas, los mensajes son). Cada mensaje también tiene una fecha asociada. Lo que quiero hacer es seleccionar la primera dirección del mensaje, mensaje, fecha y cuántos mensajes están asociados con la dirección.¿Cómo construir una consulta SQLite a GROUP por ORDEN?
Entonces, pensé: "Puedo simplemente AGRUPAR por la dirección para obtener solo un mensaje por dirección, luego ORDENAR por la fecha y también obtener el COUNT de la columna de la dirección".
Lo hice, y funciona ... un poco. Busca el recuento correcto, busca solo un mensaje por dirección y los ordena por fecha, pero no selecciona el más reciente mensaje para la dirección. Parece ser arbitrario.
Como un ejemplo, tengo tres mensajes (más temprana a la última) A, B, C de la dirección Y, y tres mensajes D, E, F desde la dirección Z. La consulta pueden obtener los mensajes B y E, entonces ordenarlos por fecha. Es debería buscar los mensajes C y F, y ordenarlos por fecha.
Esto es lo que tengo hasta ahora:
// Expanded version:
Cursor cursor = db.query(
/* FROM */ "messages_database",
/* SELECT */ new String[]{ "*", "COUNT(address) AS count" },
/* WHERE */ null,
/* WHERE args */ null,
/* GROUP BY */ "address",
/* HAVING */ null,
/* ORDER BY */ "date DESC"
);
// Or, same code on one line:
Cursor cursor = db.query("messages_database", new String[]{ "*", "COUNT(address) AS count" }, null, null, "address", null, "date DESC");
siento que esto puede tener que ver con la cláusula HAVING
, pero realmente no lo sé. He usado mucho MySQL con PHP, pero nunca tuve que tocar HAVING
antes. Intenté configurar mi cláusula HAVING
en "MAX(date)"
, pero no tuvo ningún efecto. Si configuro mi GROUP BY
cláusula para que sea "address, date"
, entonces están ordenados por fecha, pero por supuesto son todos individuales en lugar de agrupados (ya que las fechas difieren).
Las búsquedas en Google han resultado infructuosas; consultas como "android sqlite antes del grupo" y "android sqlite group por orden" no arrojan resultados relacionados.
¿Cómo puedo seleccionar el mensaje una última para cada dirección sin tener que quitar la cláusula GROUP
(como COUNT()
basa en esto)? ¿Necesito dos consultas?
Editar: Basado en the answer @Adrian me unía a en los comentarios, me ocurrió con dos consultas, que tanto produjo el mismo resultado; una fila, en la que el recuento fue 7 (que es el número total de direcciones, no los mensajes por dirección), y la dirección que se muestra no era la del último mensaje.
Las dos consultas fueron:
Cursor cursor = db.rawQuery(
"SELECT t.*, COUNT(t.message_content) AS count "
+ "FROM messages_database t "
+ "INNER JOIN ("
+ " SELECT address, MAX(date) AS maxdate "
+ " FROM messages_database "
+ " GROUP BY address "
+ ") ss ON t.address = ss.address AND t.date = ss.maxdate",
null
);
Cursor cursor = db.rawQuery(
"SELECT t1.*, COUNT(t1.message_content) AS count "
+ "FROM messages_database t1 "
+ "LEFT OUTER JOIN messages_database t2 "
+ "ON (t1.address = t2.address AND t1.date < t2.date) "
+ "WHERE t2.address IS NULL",
null
);
Parece que tiene un problema [tag: greatest-n-per-group] en sus manos. Lea aquí, lo más probable es que lo ayude: http://stackoverflow.com/a/7745635/570191 –
@Adrian He comprobado esa respuesta e intenté incorporar esas ideas. Sin embargo, simplemente parecen proporcionar una fila, que contiene un recuento de una columna diferente. He publicado mis consultas anteriormente, así como un resultado más detallado de lo que no funcionó. – Eric