web-dev-qa-db-fra.com

MySQL - CHOISISSEZ toutes les colonnes O one une colonne est DISTINCT

Je suis vraiment désolé si la question semble trop basique.
J'ai surfé sur Internet et StackOverflow pour trouver une solution complète et je n'ai rien trouvé que je puisse comprendre et je ne peux pas l'écrire moi-même.

J'ai une base de données MySQL.
Il a une table nommée "posté".
Il a 8 colonnes.

J'ai besoin de sortir ce résultat:

SELECT DISTINCT link FROM posted WHERE ad='$key' ORDER BY day, month

Mais j'ai besoin non seulement de la colonne "link", mais également d'autres colonnes pour cette ligne.
Comme pour chaque ligne renvoyée avec cette requête, j'ai également besoin de connaître son "id" dans la table, les valeurs "jour" et "mois", etc.

S'il vous plaît dites-moi ce que je devrais lire pour le faire, ou comment le faire.
Veuillez rester aussi simple que possible car je ne suis pas un expert en MySQL.

Edit: J'ai essayé ceci:

SELECT DISTINCT link,id,day,month FROM posted WHERE ad='$key' ORDER BY day, month

Ça ne marche pas Il retourne trop de lignes. Supposons qu'il y a 10 lignes avec les mêmes liens, mais un jour/mois/identifiant différent. Ce script renverra tous les 10, et je ne veux que le premier (pour ce lien).

49
John Smith

Le problème provient de la croyance instinctive que DISTINCT est un pré-modificateur local pour une colonne.

Par conséquent, vous "devriez" être capable de taper

XXbadXX SELECT col1, DISTINCT col2 FROM mytable XXbadXX 

et le renvoyer des valeurs uniques pour col2. Malheureusement non. DISTINCT est en fait un post-modificateur global pour SELECT, autrement dit, par opposition à SELECT ALL (renvoyant toutes les réponses), il est SELECT DISTINCT (renvoyant toutes les réponses uniques). Donc, une seule DISTINCT agit sur TOUTES les colonnes que vous lui donnez. 

Cela rend très difficile l’utilisation de DISTINCT sur une seule colonne, tout en récupérant les autres colonnes, sans faire de très gros backflips extrêmement laids. 

La bonne réponse consiste à utiliser un GROUP BY sur les colonnes pour lesquelles vous souhaitez avoir des réponses uniques:SELECT col1, col2 FROM mytable GROUP BY col2vous donnera des lignes col2 uniques arbitraires, ainsi que leurs données col1.

81
DragonLord

J'ai essayé ceci:

SELECT DISTINCT link,id,day,month FROM posted
     WHERE ad='$key' ORDER BY day, month

Ça ne marche pas Il retourne trop de lignes. Disons qu'il y a 10 lignes avec mêmes liens, mais jour/mois/id différent. Ce script retournera tout 10, et je ne veux que le premier (pour ce lien).

Ce que vous demandez n'a pas de sens.

Soit vous voulez la valeur distincte de l'ensemble link, id, day, month, soit vous devez rechercher un critère pour choisir laquelle des valeurs de id, day, month vous souhaitez utiliser, si vous souhaitez au plus une valeur distincte de link.

Autrement, ce que vous recherchez ressemble à aux colonnes cachées de MySQL dans les instructions GROUP BY/HAVING , qui est du code SQL non standard et qui peut en réalité être assez déroutant.

Vous pouvez en fait utiliser un GROUP BY link s'il est logique de sélectionner une ligne pour une valeur link donnée.

Vous pouvez également utiliser une sous-sélection pour sélectionner la ligne avec la variable id minimale pour une valeur de chaque link (comme décrit dans cette réponse ):

 SELECT link, id, day, month FROM posted
     WHERE (link, id) IN
           (SELECT link, MIN(id) FROM posted ad='$key' GROUP BY link)
8
Bruno

Si ce que vous demandez est de ne montrer que les lignes qui ont un lien pour elles, vous pouvez utiliser ce qui suit:

SELECT * FROM posted WHERE link NOT IN 
(SELECT link FROM posted GROUP BY link HAVING COUNT(LINK) > 1)

Encore une fois, cela suppose que vous souhaitiez supprimer tout lien dupliqué.

3
Joe Meyer

Je pense que la meilleure solution serait de faire une sous-requête puis de la joindre à la table. La sous-requête renverrait la clé primaire de la table. Voici un exemple:

select *
from (
          SELECT row_number() over(partition by link order by day, month) row_id
          , *

          FROM posted 
          WHERE ad='$key' 
          ) x
where x.row_id = 1

La fonction row_number crée une séquence numérique partitionnée par chaque lien distinct qui aboutit à la requête.

En prenant uniquement les numéros_lignes qui = 1, vous ne renvoyez qu'une ligne pour chaque lien.

La façon dont vous modifiez le lien marqué "1" s'effectue via la clause order-by de la fonction row_number.

J'espère que cela t'aides.

2
Walker Farrow
SELECT Id, Link, Day, Month FROM Posted
WHERE Id IN(
   SELECT Min(Id) FROM Posted GROUP BY Link)
2
Sinaesthetic
SELECT DISTINCT link,id,day,month FROM posted WHERE ad='$key' ORDER BY day, month

OR

SELECT link,id,day,month FROM posted WHERE ad='$key' ORDER BY day, month
2
mlishn

Si vous voulez toutes les colonnes où le lien est unique:

SELECT * FROM posted WHERE link in
     (SELECT link FROM posted WHERE ad='$key' GROUP BY link);
1
Zonata

Ce que vous voulez, c'est ce qui suit:

SELECT DISTINCT * FROM posted WHERE ad='$key' GROUP BY link ORDER BY day, month

s'il y a 4 lignes, par exemple, où le lien est le même, il n'en choisira qu'une (je suppose la première).

1
Failon
  SELECT OTHER_COLUMNS FROM posted WHERE link in (
  SELECT DISTINCT link FROM posted WHERE ad='$key' )
  ORDER BY day, month
1
arunmoezhi

Dans MySQL, vous pouvez simplement utiliser "group by". Ci-dessous, sélectionnez ALL, avec un "col" DISTINCT

SELECT *
FROM tbl
GROUP BY col
0
Robert Sinclair

J'ai eu un problème similaire, peut-être aider quelqu'un, par exemple - tableau avec 3 colonnes

SELECT * FROM DataTable WHERE Data_text = 'test' GROUP BY Data_Name ORDER BY Data_Name ASC

ou 

SELECT Data_Id, Data_Text, Data_Name FROM DataTable WHERE Data_text = 'test' GROUP BY Data_Name ORDER BY Data_Name ASC

Deux façons fonctionnent pour moi.

0
syp_dino