0
votes

Les groupes d'identification ont les mêmes valeurs sur plusieurs colonnes SQL

J'essaie de comprendre comment coder une requête SQL qui identifiera un groupe dans une table qui contient la même valeur dans les enregistrements du groupe sur plusieurs colonnes.

Par exemple, étant donné l'exemple de tableau suivant:

 Nom Début Fin
Julie

Je cherche à identifier dans ce cas les noms pour lesquels tous les essais avaient les mêmes points de départ et d'arrivée. Seuls James et Frank remplissent ces critères selon les données. Je suis ne cherche pas à filtrer et à obtenir une sortie de requête qui me donne simplement tous les groupes avec "oui" ou "non". Je veux que la requête affiche la table entière avec le groupe étiqueté de manière appropriée. Comment procéder?

Ci-dessous, tout ce que j'ai obtenu. Je vois que lorsque je regroupe d'ici là, les groupes qui affichent toutes les valeurs identiques dans les colonnes d'intérêt se réduisent en un seul groupe. Mais si je lance un nouveau groupe dans lequel il y en a plusieurs lignes (essais) où chaque essai peut avoir les mêmes points de début et de fin, mais les différents essais pour le groupe ne sont pas les mêmes points, alors en fait le groupe devrait donner «non» même si chaque essai individuel montre les mêmes points de départ et d'arrivée. / p>

CREATE TABLE Trial
(Name nvarchar(100),
Trial nvarchar(10),
Start nvarchar(100),
[End] nvarchar(100))

INSERT INTO Trial

VALUES
('Julie', 'A', 'Ranch St', 'Ranch St'),
('Julie', 'B', 'Ranch St', 'North Blvd'),
('James', 'A', 'Deer Rd', 'Deer Rd'),
('James', 'B', 'Deer Rd', 'Deer Rd'),
('Emily', 'A', 'Oak St', 'Oak St'),
('Emily', 'B', 'Oak St', 'Elm Rd'),
('Frank', 'A', 'Main Ave', 'Main Ave'),
('Frank', 'B', 'Main Ave', 'Main Ave'),
('Frank', 'C', 'Main Ave', 'Main Ave'),
('Jeff', 'A', 'Main Ave', 'Main Ave'),
('Jeff', 'B', 'Oak St', 'Oak St')

SELECT
    a.[Name]
    ,CASE
    WHEN a.[Start] = a.[END] THEN 'Yes' ELSE 'No'
    END AS 'TrialChk'

FROM Trial AS a

GROUP BY a.[Name]
        ,a.[Start]
        ,a.[End]

ORDER BY Name ASC;

Je n'ai pas l'essai de Jeff dans mon exemple de tableau ci-dessus, mais Jeff donnera "oui" pour chaque essai, mais puisque tous les points ne sont pas e La sortie du groupe doit être "non".


0 commentaires

4 Réponses :


2
votes

Vous pouvez essayer la fonction fenêtrée Row_Number () comme indiqué ci-dessous:

Create table MyTable (Name varchar(50),
Trial Char(1),
Start Varchar(20),
[End] Varchar(20))

Insert into MyTable Values
('Julie', 'A', 'Ranch St', 'Ranch St'),
('Julie', 'B', 'Ranch St', 'North Blvd'),
('James', 'A', 'Deer Rd', 'Deer Rd'),
('James', 'B', 'Deer Rd', 'Deer Rd')

;with cte as (Select name
,trial
,start
,[End]
,Row_number() Over(Partition By [Start], [End] order by [Start], [End]) as SrNo
From MyTable
)
Select 
   name, trial, start, [End], 'Yes' as [Expected Output] 
from cte where name in ( Select name from cte where SrNo > 1)
union all
Select 
   name, trial, start, [End], 'No' as [Expected Output] 
from cte where name not in (Select name from cte where SrNo > 1)
order by name

Démo en direct


0 commentaires

1
votes

Vérifier la requête donnée

DECLARE @Counter int  
DECLaRE @CMS_Query varchar(MAX)
DECLARE @total_Row int
DECLARE Cur_1 CURSOR FOR select Name from Trial group by Name

Create Table #MainTrial(
[Name] varchar(MAX),
Trial varchar(MAX),
[Start] varchar(MAX),
[END] varchar(MAX),
[TrialChk] varchar(3)
)
OPEN Cur_1
    DECLARE @Name varchar(MAX)
    FETCH NEXT FROM Cur_1 INTO @Name
        WHILE (@@FETCH_STATUS = 0)
            Begin
                
                SELECT  a.[Name],Trial,Start,[End],CASE WHEN a.[Start] = a.[END] THEN 'Yes' ELSE 'No'END AS 'TrialChk' into #Trial1 FROM Trial AS a  where Name = @Name

                select @total_Row = count(*) from #Trial1
                select @Counter = COUNT(*) from #Trial1 where TrialChk = 'Yes'

                IF @total_Row != @Counter
                    BEGIN
                        UPDATE #Trial1 SET TrialChk = 'No' where [Name] = @Name
                    END
                insert into #MainTrial select * from #Trial1
                DROP Table #Trial1
                FETCH NEXT FROM Cur_1 INTO @Name
            END
CLOSE Cur_1
DEALLOCATE Cur_1
select * from #MainTrial
drop table #MainTrial

 entrez la description de l'image ici


0 commentaires

1
votes

Utilisez simplement case avec les fonctions de fenêtre:

select t.*,
       (case when min(start) over (partition by name) = max(start) over (partition by name) and
                  min(end) over (partition by name) = max(end) over (partition by name) and
                  start = end
             then 'Yes' else 'No'
        end) as flag
from trial t;

Voici un violon db .

Remarque: end est un nom très pauvre pour une colonne car il s'agit d'un mot-clé SQL.


0 commentaires

1
votes

Si vous GROUP BY Name et comptez le nombre distinct de Start s et End , comme le fait cette requête:

> Name  | Trial | Start    | End        | Result
> :---- | :---- | :------- | :--------- | :-----
> Emily | A     | Oak St   | Oak St     | No    
> Emily | B     | Oak St   | Elm Rd     | No    
> Frank | A     | Main Ave | Main Ave   | Yes   
> Frank | B     | Main Ave | Main Ave   | Yes   
> Frank | C     | Main Ave | Main Ave   | Yes   
> James | A     | Deer Rd  | Deer Rd    | Yes   
> James | B     | Deer Rd  | Deer Rd    | Yes   
> Jeff  | A     | Main Ave | Main Ave   | No    
> Jeff  | B     | Oak St   | Oak St     | No    
> Julie | A     | Ranch St | Ranch St   | No    
> Julie | B     | Ranch St | North Blvd | No  

vous obtenez ces résultats:

SELECT t.*,
  CASE WHEN c.start_counter = 1 AND c.end_counter = 1 THEN 'Yes' ELSE 'No' END Result
FROM Trial t 
INNER JOIN (
  SELECT Name, COUNT(DISTINCT Start) start_counter, COUNT(DISTINCT [End]) end_counter
  FROM Trial
  GROUP BY Name
) c ON c.Name = t.Name 

Vous pouvez donc joindre la requête ci-dessus à votre table et définir 'Oui' où les 2 compteurs sont tous deux égaux à 1, sinon définissez 'No':

> Name  | start_counter | end_counter
> :---- | ------------: | ----------:
> Emily |             1 |           2
> Frank |             1 |           1
> James |             1 |           1
> Jeff  |             2 |           2
> Julie |             1 |           2

Voir le démo .
Résultats:

SELECT Name, COUNT(DISTINCT Start) start_counter, COUNT(DISTINCT [End]) end_counter
FROM Trial
GROUP BY Name


0 commentaires