2009-07-25 26 views
8

Actualmente estoy tratando de construir una Declaración Selectiva de MySQL algo complicada. Esto es lo que estoy tratando de lograr:MySQL Select Statement DISTINCT para Columnas Múltiples

Tengo una tabla como la siguiente:

data_table 

uniqueID  stringID   subject 
    1    144   "My Subject" 
    2    144   "My Subject - New" 
    3    144   "My Subject - Newest" 
    4    211   "Some other column" 

Bascially, lo que me gustaría hacer es ser capaz de seleccionar/GRUPO POR el stringID (imagen que la stringID está enhebrado) y no lo tiene duplicado. Además, me gustaría SELECCIONAR la fila stringID más reciente, (que en el ejemplo anterior es uniqueID 3).

Por lo tanto, si tuviera que consultar la base de datos, sería devolver el siguiente (con el más reciente IDunico en la parte superior):

uniqueID stringID subject 
4   211  "Some other column" 
3   144  "My Subject - Newest" //Notice this is the most recent and distinct stringID row, with the proper subject column. 

Espero que esto tenga sentido. Gracias por tu ayuda.

+2

¿Estás 100% seguro IDunico siempre será el más alto de identificación en la tabla? Si no, le sugiero que agregue una marca de tiempo para la última. – lexu

+0

De hecho tengo una columna de marca de tiempo (no incluida en mi ejemplo anterior). Entonces, ¿cómo voy a usar mi columna timestamp entonces? ¿MAX funciona con una columna de marca de tiempo? Gracias. –

Respuesta

9

Intente lo siguiente. Puede que no sea la consulta más eficiente, pero funcionará:

SELECT uniqueID, stringID, subject 
FROM data_table 
WHERE uniqueID IN 
(
    SELECT MAX(uniqueID) 
    FROM data_table 
    GROUP BY stringID 
) 
ORDER BY uniqueID DESC 
+1

Esta consulta ayudó más. Además, reemplacé el 'uniqueID' con la sugerencia de lexu anterior, utilizando la marca de tiempo. Muchas gracias por su ayuda. –

+2

Encontré esto buscando una solución a un problema similar. Es una buena solución, pero se puede obtener un aumento en el rendimiento mediante el uso de una tabla temporal en lugar de la subselección. Cree una tabla temporal basada en la selección secundaria, luego donde va la selección secundaria en la consulta principal, ponga select * from temp table en su lugar. En mi conjunto de datos de más de 800 filas, el método de subselección tomó minutos para ejecutarse, mientras que el uso de una tabla temporal en su lugar tomó alrededor de 15 segundos. – GordonM

2

Editar: Sobre la base de nueva información proporcionada por el PO en un comentario, esto sería preferible a depender de uniqueID:

select t.uniqueID 
     , t.stringID 
     , t.subject 
     , t.your_timestamp_col 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.your_timestamp_col > t.your_timestamp_col 
where t2.uniqueID is null 

Si, como Lexu menciones en un comentario, está seguro de que el valor más alto uniqueID siempre se corresponde con la más reciente tema, usted puede hacer esto:

select t.uniqueID 
     , t.stringID 
     , t.subject 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.uniqueID > t.uniqueID 
where t2.uniqueID is null 

Lo que básicamente significa: devuélveme solo los registros desde data_table donde no existe un valor más alto uniqueID.

+1

Realmente tendrá un peor rendimiento. La subconsulta no utiliza ninguna de las columnas de superqueries y, por lo tanto, se calcula solo una vez. Un 'máximo' es mucho más rápido que tratar de comparar cada identificación uno por uno. Además, la unión tendrá que aplicar la cláusula 'where'. La subconsulta, sin embargo, creará una tabla hash que sirve como una búsqueda de cada uno de los ID. Ergo, solo una comparación, y no tenemos que verificar la columna después de todas las comparaciones. – Eric

+0

@Eric - Su argumento tiene sentido pero [desafortunadamente MySQL actualmente no funciona de esa manera] (http: // stackoverflow.com/questions/3417074/why-would-an-condition-be-slower-than-in-sql/3417190 # 3417190) –

3
SELECT DISTINCT(a), 
    (SELECT DISTINCT(b)) AS b, 
    (SELECT DISTINCT(c)) AS c 

FROM tblMyTBL 

WHERE... 
Order By... 
Etc. 
0

Tuve una situación similar y encontré una consulta diferente. Prueba esto:

SELECT MAX(uniqueID), stringID, subject 
FROM data_table 
GROUP BY stringID 
+0

Al proporcionar el código que resuelve el problema, es mejor también dar al menos una breve explicación de cómo funciona para que la gente que lee no tenga que analizarlo mentalmente línea por línea para entender las diferencias. – Fluffeh

-1
private void LoadAllFamilyMembers(string relationShip) 
     { 
      lbFamilyMembers.SelectedIndexChanged -= new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
      SqlCommand cmd = new SqlCommand("select familymemberid,name from FamilyMembers where relationship = @relationship", con); 
      cmd.Parameters.AddWithValue("@relationship", relationShip); 
      DataTable dt = new DataTable(); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      adapter.Fill(dt); 
      lbFamilyMembers.DataSource = dt; 
      lbFamilyMembers.DisplayMember = "name"; 
      lbFamilyMembers.ValueMember = "familymemberid"; 
      lbFamilyMembers.SelectedIndex = -1; 
      lbFamilyMembers.SelectedIndexChanged += new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
     } 
Cuestiones relacionadas