2017-08-23 4 views
1

J'ai une table comme celle ci-dessous:Comment afficher une sortie comme celle-ci dans SQL?

+----------------+-------+----------+---------+ 
| Name   | Model | system | ItemTag | 
+----------------+-------+----------+---------+ 
| Alarm Id  | T58 | ASC  |   | 
+----------------+-------+----------+---------+ 
| Door Lock  | F48 | ASC  |   | 
+----------------+-------+----------+---------+ 
| AlarmSounder | T58 | ASC  |   | 
+----------------+-------+----------+---------+ 
| Card Reader | K12 | ASC  |   | 
+----------------+-------+----------+---------+ 
| Magnetic Lock | F48 | ASC  |   | 
+----------------+-------+----------+---------+ 
| T2 Card Reader | K12 | ASC  |   | 
+----------------+-------+----------+---------+ 
| Power Supply | Null | ASC  |   | 
+----------------+-------+----------+---------+ 
| Battery   | Null| ASC  |   | 
+----------------+-------+----------+---------+ 

Maintenant, je veux afficher les données comme ceci:

+-------------+-------+--------+--------+ 
| Name  | Model | system | count | 
+-------------+-------+--------+--------+ 
| Alarm  | T58 | ASC | 2  | 
+-------------+-------+--------+--------+ 
| Door Lock | F58 | ASC | 2  | 
+-------------+-------+--------+--------+ 
| Card Reader | K12 | ASC | 2  | 
+-------------+-------+--------+--------+ 
|Power supply | Null | ASC | 1  | 
+-------------+-------+--------+--------+ 
| Battery | Null | ASC | 1  | 
+-------------+-------+--------+--------+ 

Comment le faire dans SQL?

Mise à jour J'ai également inclus la colonne null comme deuxième mise à jour.

+0

Quelle est la logique? Pourquoi "AlarmSounder", "Magnetic Lock" et "T2 Card Reader" ne sont pas dans la sortie? –

+0

@ZoharPeled, mis à jour la question – aryan

+0

Toujours n'aide pas. Comment pouvez-vous faire la différence entre les lignes que vous voulez retourner et les lignes que vous ne voulez pas retourner? –

Répondre

1

Vous pouvez utiliser les fonctions fenêtrées:

SELECT Name, Model, system, cnt AS count 
FROM (SELECT *, COUNT(*) OVER(PARTITION BY Model) AS cnt, 
      ROW_NUMBER() OVER(PARTITION BY Model ORDER BY ...) AS rn 
     FROM your_tab) AS sub 
WHERE rn = 1; 

Rextester Demo

Gardez à l'esprit que vous avez besoin d'une colonne pour trier de façon (id/horodatage) doit être utilisé pour obtenir la première valeur d'un groupe .


EDIT:

Comme je l'ai un autre nom relatif à la colonne null. Comment puis-je séparer dehors

SELECT Name, Model, system, cnt AS count 
FROM (SELECT *, COUNT(*) OVER(PARTITION BY Model) AS cnt, 
      ROW_NUMBER() OVER(PARTITION BY Model ORDER BY id) AS rn 
     FROM my_tab 
     WHERE Model IS NOT NULL) AS sub 
WHERE rn = 1 
UNION ALL 
SELECT Name, Model, system, 1 
FROM my_tab 
WHERE Model IS NULL; 

RextesterDemo 2

+0

c'est presque parfait .. Toutes les lignes se retiennent avec le total Mais j'ai des problèmes dans la colonne nulle. Comme j'ai un Nom différent relatif à la colonne null. comment puis-je séparer – aryan

+0

@aryan Maintenant, vous étendez votre question. Je suggère de poser une nouvelle question avec des exemples de données et de résultats.Vous pouvez utiliser mon http://rextester.com pour fournir toutes les données nécessaires. – lad2025

+2

@aryan: Vous devez inclure tous les scénarios en question car nous essayons de construire une requête en fonction des données fournies en question. Il n'y a pas de null dans vos données d'échantillon. – zarruq

1

Vous pouvez avoir une requête simple comme ci-dessous

SELECT MIN(Name) Name, 
     Model, 
     system, 
     COUNT(*) [count] 
    FROM yourtable 
GROUP BY Model, system 

Résultat

Name  Model system count 
Door Lock F58  ASC  2 
Card Reader K12  ASC  2 
Alarm Id T58  ASC  2 
+0

a mis à jour la question – aryan

1

de la solut de lad2025 ion simplifié, calculer à la fois NULL et NOT NULL en une seule étape et ajouter une certaine logique pour les lignes NULL:

SELECT Name, Model, system, 
    CASE WHEN Model IS NULL THEN 1 ELSE cnt END AS count 
FROM 
(
    SELECT *, 
     COUNT(*) OVER(PARTITION BY Model) AS cnt, 
     ROW_NUMBER() OVER(PARTITION BY Model ORDER BY Name) AS rn 
    FROM my_tab 
) AS sub 
WHERE rn = 1   -- one row per model 
    OR Model IS NULL; -- all rows for the NULL model 
+0

qui était si gentil et bien fait. – aryan

+0

je n'ai pas eu la partie de déclaration de cas ..0CASE QUAND LE MODÈLE EST NULL ALORS 1 Son énonciation quand le modèle est nul alors 1, lequel un pointant ici. – aryan

+0

@aryan: Ceci remplace simplement le nombre de lignes NULL par 1 pour correspondre au résultat attendu :-) – dnoeth