problème d'expression SQL
-
22-08-2019 - |
Question
Voici ma table, un utilisateur peut avoir plusieurs profils dans certaines langues, les profils non anglophones ont une priorité plus élevée.
+----------+--------+----------------+----------------+ |ProfileID |UserID |ProfileLanguage |ProfilePriority | +----------+--------+----------------+----------------+ |1 |1 |en-US |2 | +----------+--------+----------------+----------------+ |2 |1 |es-MX |1 | +----------+--------+----------------+----------------+ |3 |1 |ja-JP |1 | +----------+--------+----------------+----------------+ |4 |2 |es-MX |1 | +----------+--------+----------------+----------------+ |5 |2 |ja-JP |2 | +----------+--------+----------------+----------------+ |6 |2 |de-DE |1 | +----------+--------+----------------+----------------+ |7 |3 |en-US |2 | +----------+--------+----------------+----------------+
Par exemple: Quand un visiteur hispanophone demande mon site (où ProfileLanguage = 'es-MX' ou ProfilePriority = 2), je veux les dossiers comme ci-dessous:
+----------+--------+----------------+----------------+ |ProfileID |UserID |ProfileLanguage |ProfilePriority | +----------+--------+----------------+----------------+ |2 |1 |es-MX |1 | +----------+--------+----------------+----------------+ |5 |2 |ja-JP |2 | +----------+--------+----------------+----------------+ |7 |3 |en-US |2 | +----------+--------+----------------+----------------+
Ci-dessous, est le SQL de base pour obtenir les utilisateurs:
SELECT UserID, MIN(ProfilePriority) AS ProfilePriority
FROM Profile
WHERE ProfileLanguage = 'es-MX' OR ProfilePriority = 2
GROUP BY UserID
Mais comme vous le savez, je ne peux obtenir le code d'utilisateur, mais je dois aussi d'autres informations sur les colonnes, comme ProfileID etc .. J'espère donc que les experts ici pourrait me dire l'expression SQL correcte pour obtenir les enregistrements droite.
La solution
Cela peut fonctionner, si profilepriority et userid pourrait être une clé composite unique,
select p.* from Profile p join
(SELECT UserID, MIN(ProfilePriority) AS ProfilePriority
FROM Profile
WHERE ProfileLanguage = 'en-US' OR ProfilePriority = 2
GROUP BY UserID) tt
on p.userID = tt.UserID and p.ProfilePriority = tt.ProfilePriority
Autres conseils
SELECT *
FROM Profile as tb1 inner join
(SELECT UserID, MIN(ProfilePriority) AS ProfilePriority
FROM Profile
WHERE ProfileLanguage = 'es-MX' OR ProfilePriority = 2
GROUP BY UserID) as tb2 on
tb1.userid = tb2.userid and tb1.ProfilePriority = tb2.ProfilePriority
Entrez toutes les colonnes dont vous avez besoin dans séparés par une virgule au lieu de * dans la requête ci-dessus.
Il me semble, qu'il ne soit pas clair sans votre table et peut-être quelques exemples de données, que votre problème est résolu par simplement l'extension de votre groupe comme suit:
SELECT UserID, ProfileID, MIN(ProfilePriority) AS ProfilePriority
FROM Profile
WHERE ProfileLanguage = 'en-US' OR ProfilePriority = 2
GROUP BY UserID, ProfileID
Je suppose que vous avez une priorité si profilepriority et les deux profilelanguage sont corrects. Donc, cela peut aider dans ce cas;
select p.* from
(select tt1.userid, min(tt.pr) pr from
(
SELECT profileid, UserID, MIN(ProfilePriority) AS ProfilePriority, 1 as pr
FROM Profile
WHERE ProfileLanguage = 'en-US' and ProfilePriority = 2
GROUP BY profileid, UserID
union
SELECT profileid, UserID, MIN(ProfilePriority) AS ProfilePriority, 2 as pr
FROM Profile
WHERE ProfileLanguage = 'en-US' or ProfilePriority = 2
GROUP BY profileid, UserID
) tt1
group by userid) tt2
join
(
SELECT profileid, UserID, MIN(ProfilePriority) AS ProfilePriority, 1 as pr
FROM Profile
WHERE ProfileLanguage = 'en-US' and ProfilePriority = 2
GROUP BY profileid, UserID
union
SELECT profileid, UserID, MIN(ProfilePriority) AS ProfilePriority, 2 as pr
FROM Profile
WHERE ProfileLanguage = 'en-US' or ProfilePriority = 2
GROUP BY profileid, UserID
) tt3
on tt2.userId = tt3.userId and tt2.pr = tt3.pr
join profile p on p.profileid = tt3.profileid