Città con più persone

di il
12 risposte

Città con più persone

Buongionrno, mi potete dare una mano con questo esercizio: Visualizzare la città con più persone.
Bastano 2 tabelle: tbPersona e tbCittà?

SELECT C.Nome
FROM tbCittà As C, tbPersona As P
WHERE  P.CodiceCittà = C.Codice 
GROUP BY P.Codice, C.Nome
HAVING MAX()

12 Risposte

  • Re: Città con più persone

    Cosa contengono le tabelle?

    Basterebbe anche una tabella Città

    ID
    Nome
    Abitanti

    ma se non si conosce il contesto dell'esercizio è inutile dare risposte
  • Re: Città con più persone

    Allora
    
    TabellaPersona(
    Codice int PRIMARY KEY,
    Nome nvarchar(30) NULL,
    CodiceCittà int FOREIGN KEY REFERENCES TabellaCittà(Codice)
    )
    
    TabellaCitta(
    Codice int PRIMARY KEY,
    Nome nvarchar(30) null
    )
    
    Con queste due tabelle posso visualizzare il nome e il codice della città con più persone?Consigli subquery o funzioni da usare?
  • Re: Città con più persone

    Salve,
    ti consiglio l'utilizzo della windowing function RANK() [https://docs.microsoft.com/it-it/sql/t-sql/functions/rank-transact-sql?view=sql-server-ver15], dove puoi "ordinare" in base al count raggruppato, ottenendo quindi l'ordinalita' nel subset di ricerca, dal quale escludere tutte le valorizzazioni' superiori a 1...
    per capirci, [ho tolto la parola chiave CREATE] per non penalizzare e far bloccare la riposta dai filtri del forum:
    
    TABLE [dbo].[Citta] (
    	[Codice] varchar(9) NOT NULL PRIMARY KEY,
    	[Nome] varchar(10) NOT NULL
    	);
    
    TABLE [dbo].[Persone] (
    	[Id] int NOT NULL PRIMARY KEY,
    	[Nome] varchar(15) NOT NULL,
    	[CodiceCitta] varchar(9) NOT NULL
    		CONSTRAINT [fk_Persone$has$Citta] FOREIGN KEY
    			REFERENCES [dbo].[Citta] ([Codice])
    	);
    GO
    INSERT INTO [dbo].[Citta]
    	VALUES ( '403015146', 'MILANO' ), ( '408099013', 'RICCIONE' ), ( '412058091', 'ROMA' );
    
    INSERT INTO [dbo].[Persone]
    	VALUES ( 1, 'SuperManPC', '403015146' )
    		, ( 2, 'Oregon', '412058091' )
    		, ( 3, 'Andrea', '408099013' )
    		, ( 4, 'Toki', '412058091' )
    		, ( 5, 'Migliorabile', '403015146' )
    		, ( 6, 'Lorenzo', '403015146' )
    		, ( 7, 'AndBin', '412058091' );
    GO
    PRINT 'proiezioni raggruppata';
    SELECT c.[Codice], c.[Nome], COUNT(*) AS [c]
    	FROM [dbo].[Citta] c
    		JOIN [dbo].[Persone] p ON p.[CodiceCitta] = c.[Codice]
    	GROUP BY c.[Codice], c.[Nome]
    	ORDER BY COUNT(*) DESC;
    
    PRINT 'utilizzo della windowing function RANK() per ottenere l''ordine nel set in base al count';
    PRINT '  qui useremo appunto RANK() e non ROW_NUMBER() in quanto e'' ovviamente possibile che esistano';
    PRINT '  svariate entita'' con lo stesso "valore", sia esso il massimo, il minimo o nel mezzo,';
    PRINT '  poi filtreremo SOLO la/e riga/eh con il RANK = 1 per escludere le righe non interessanti;';
    
    WITH cteCount AS (
    	SELECT c.[Codice], COUNT(*) AS [c]
    		FROM [dbo].[Citta] c
    			JOIN [dbo].[Persone] p ON p.[CodiceCitta] = c.[Codice]
    		GROUP BY c.[Codice]
    	),
    	cteOrdered AS (
    	SELECT c.[Codice], c.[c], RANK() OVER (ORDER BY c.[c] DESC) AS [rnk]
    		FROM cteCount c
    	)
    	SELECT ci.[Nome], c.[c] AS [Ccount]
    		FROM cteOrdered c
    			JOIN [dbo].Citta ci ON ci.[Codice] = c.[Codice]
    		WHERE c.[rnk] = 1;
    
    come indicato, con RANK() possiamo ottenere l'ordinale in base al suo rango nel set, quindi ci e' facile escludere le righe che NON abbiano un rank = 1, quindi ottenendo solo Roma e Milano...
    salutoni romagnoli (qui esclusi per un rank fuori dalla ricerca)
    --
    Andrea
  • Re: Città con più persone

    Ok grazie, però non ho capito benissimo, qualcuno ha una soluzione più semplice?
  • Re: Città con più persone

    Salve,
    provo a "rispiegarmi" , che non e' cosi' complicato

    utilizzo 2 common table expression in cascata...
    la 1ma effettua il raggruppamento come desiderato, quindi ottengo il count di ogni citta'...
    la 2da prende questo risultato, ed effettua un'operazione di ranking in base al valore del count in ordine decrescente, cioe' "ordina" in maniera decrescente in base al valore di count, assegnando un valore di rango...

    da quest'ultima cte, filtro solo le righe che abbiano un rango pari a 1, cioe' "le prime e piu' alte qualificate" scartando tutto il resto...
    scusa se non riesco a spiegare meglio, mi pareva di essere stato abbastanza chiaro
    un salutone sempre romagnolo
    --
    Andrea
  • Re: Città con più persone

    SuperManPC ha scritto:


    Ok grazie, però non ho capito benissimo, qualcuno ha una soluzione più semplice?
    Ciao,
    forse questa con l'order by desc e la clausola top 1 with ties , ti risulta più familiare
    
    select  c.Codice, c.Nome, numAbitanti
    from
    (
    	select top 1 with ties 
    	CodiceCitta, count(*) as numAbitanti
    	from dbo.Persone 
    	group by codicecitta
    	order by numAbitanti desc
    ) as q
    inner join dbo.citta c
    on q.CodiceCitta=c.Codice
    
    EDIT
    nota che si sarebbe potuto scrivere anche così :
    
    select top 1 with ties 
    p.CodiceCitta, c.Nome, count(*) as numAbitanti
    from dbo.Persone p inner join dbo.citta c
    on p.CodiceCitta=c.Codice
    group by p.codiceCitta, c.Nome
    order by numAbitanti desc
    
    ma converrai che è conveniente prima raggruppare solo sul codice e ricavare i soli record di interesse e poi ricavare il nome della città

    HTH
  • Re: Città con più persone

    Grande, sei un genio!
  • Re: Città con più persone

    SuperManPC ha scritto:


    Grande, sei un genio!
    [OT]
    i programmatori sono strane bestie, esclusi i presenti ovviamente ;

    questo tipo di commenti infastidiscono ... basta un semplice grazie
    [/OT]
  • Re: Città con più persone

    Ah, grazie anche per questo allora.
  • Re: Città con più persone

    Ovviamente concordo con sspintux (che saluto, anche come attivo partecipante ad un altro forum ...) ...

    E sai perché infastidiscono? Perché se dai del genio a chi sa avvitare una vite sapendo usare un cacciavite (dato che tu non sai cosa sia un cacciavite), si sente preso in giro ...

  • Re: Città con più persone

    Si ho esagerato un po' perchè è il primo che mi ha dato la soluzione adatta al mio livello di sql, anzi 2 soluzioni.
  • Re: Città con più persone

    oregon ha scritto:


    (che saluto, anche come attivo partecipante ad un altro forum ...) ...
Devi accedere o registrarti per scrivere nel forum
12 risposte