8
votes

MySQL Sélectionnez une instruction distincte pour plusieurs colonnes

J'essaie actuellement de construire une déclaration de sélection MySQL quelque peu délicate. Voici ce que j'essaie d'accomplir:

J'ai une table comme celle-ci: xxx

basciellement, ce que je voudrais faire, c'est pouvoir sélectionner / grouper Par le stringid (image que le stringid est fileté) et ne pas avoir dupliqué. De plus, j'aimerais sélectionner la ligne stringid la plus récente (qui dans l'exemple ci-dessus est uniqueID 3).

Par conséquent, si je voudrais interroger la base de données, il retournerait ce qui suit (avec le Le plus récent uniqueId au sommet): xxx

J'espère que cela a du sens. Merci pour votre aide.


2 commentaires

Êtes-vous à 100% certain que l'ID est toujours l'identifiant le plus élevé de la table? Sinon, je vous suggère d'ajouter un horodatage pour le dernier.


En fait, j'ai une colonne d'horodatage (non incluse dans mon exemple ci-dessus). Alors, comment allais-je utiliser ma colonne horodatale alors? Max fonctionne-t-il avec une colonne TIMESTAMP? Merci.


5 Réponses :


9
votes

Essayez ce qui suit. Ce n'est peut-être pas la requête la plus efficace, mais cela fonctionnera:

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


2 commentaires

Cette requête a beaucoup aidé. En outre, j'ai remplacé le «uniqueID» avec la suggestion de Lexu ci-dessus, en utilisant l'horodatage. Merci beaucoup pour votre aide.


J'ai trouvé cela à la recherche d'une solution à un problème similaire. C'est une bonne solution, mais il y a un coup de pouce de performance à être utilisé en utilisant une table temporaire à la place du sous-sélection. Créez une table Temp basée sur le sous-sélection, dans lequel le SUB SELECT dans la requête principale va, mettez SELECT * de la table TEMP à sa place. Sur mon ensemble de données de 80000 lignes, la méthode de sous-sélection a pris des minutes à exécuter, tandis que l'utilisation d'une table temporaire a plutôt pris environ 15 secondes.



2
votes

EDIT: strong> Sur la base de nouvelles informations fournies par OP dans un commentaire, il serait préférable de s'appuyer sur uniqueID code>: xxx pré>

Si, en tant que Lexu mentionne dans un commentaire, vous êtes certain que la valeur la plus élevée uniqueId code> correspond toujours au sujet le plus récent, vous pouvez le faire: P>

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


2 commentaires

Cela sera effectivement pire. La sous-requête n'utilise aucune des colonnes de super-cultures et, par conséquent, est calculée une seule fois. Un max est beaucoup plus rapide que d'essayer de comparer chaque ID un par un. De plus, la jointure devra ensuite appliquer le où la clause . La sous-requête, cependant, créera une table de hachage qui sert de rechercher à chacun des identifiants. Ergo, une seule comparaison, et nous n'avons pas à vérifier la colonne une fois que toutes les comparaisons sont effectuées.


@ERIC - Votre argument a du sens mais Malheureusement, MySQL ne fonctionne pas actuellement de cette façon



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

FROM tblMyTBL

WHERE...
Order By...
Etc.

0 commentaires

0
votes

J'ai eu une situation similaire et j'ai trouvé une requête différente. Essayez ceci: xxx


1 commentaires

Lors de la fourniture de code qui résout le problème, il est préférable de donner au moins une courte explication de la manière dont il fonctionne afin que les gens ne soient pas obligés d'analyser mentalement la ligne par ligne pour comprendre les différences.



-1
votes
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);
        }

0 commentaires