1
votes

afficher une ligne supplémentaire où la valeur de la colonne est nulle

J'ai ci-dessous la structure du tableau

+-----+------+-----+------------+-------+
| sch | clas | std |    date    | count |
+-----+------+-----+------------+-------+
| A   | a1   | Ax  | 31 nov2018 | 2     |
| A   | a1   | Bo  | 1-Dec-19   | 7     |
| A   | a1   | Ct  | null       | null  |
| A   | b1   | Ax  | 3-Oct-19   | 3     |
| A   | b1   | Bo  | null       | null  |
| A   | b1   | Ct  | 2-Dec-10   | 2     |
+-----+------+-----+------------+-------+

dans laquelle je dois afficher une ligne comme ci-dessous

+-----+------+-----+------------+-------+
| sch | clas | std |    date    | count |
+-----+------+-----+------------+-------+
| A   | a1   | Ax  | 31 nov2018 |     2 |
| A   | a1   | Bo  | 1-Dec-19   |     7 |
| A   | b1   | Ax  | 3-Oct-19   |     3 |
| A   | b1   | Ct  | 2-Dec-10   |     2 |
+-----+------+-----+------------+-------+

Colonne "std" ayant des valeurs pour toute la classe ie. Axe, Bo et Ct. Si ceux-ci ne sont pas disponibles, vous devez afficher une ligne avec des valeurs nulles pour la date et le nombre. En PLSQL, c'est facilement réalisable, mais ici, je dois le faire dans un serveur SQL ou SQL ou Postgresql.

Nous apprécions votre aide.


4 commentaires

En supposant que je comprends ce que vous recherchez, vous voulez en gros joindre toutes les combinaisons sch / clas / std distinctes, puis rejoindre votre table d'origine où il y a des correspondances ...


Merci pour votre réponse. Pouvez-vous expliquer ce que vous avez suggéré de faire.


En gros, faites ce que la réponse de Tim suggère, sauf que les CTE seraient remplacés par SELECT DISTINCT sch FROM mytable , SELECT DISTINCT clas FROM mytable etc.


Soyez simplement curieux de voir à quel point c'est facile avec PLSQL.


4 Réponses :


1
votes

Nous pouvons utiliser un tableau de calendrier ici, pour générer les données manquantes. Ensuite, rejoignez votre table à gauche.

WITH sch AS (
    SELECT 'A' AS sch
),
clas AS (
    SELECT 'a1' AS clas UNION ALL
    SELECT 'b1'
),
std AS (
    SELECT 'Ax' AS std UNION ALL
    SELECT 'Bo' UNION ALL
    SELECT 'Ct'
)

SELECT
    s.sch,
    c.clas,
    st.std,
    t.date,
    t.count
FROM sch s
CROSS JOIN clas c
CROSS JOIN std st
LEFT JOIN yourTable t
    ON t.sch = s.sch AND t.clas = c.clas AND t.std = st.std
ORDER BY
    s.sch,
    c.clas,
    st.std;


2 commentaires

Sélectionnez cs.sch, cs.cls, cs.std, d.date, d.count From (Sélectionnez c.sch, c.cls, s.std From (Sélectionnez distinct sch, cls from Data) c --List of school / classes Cross Join (sélectionnez un std distinct dans Data) s --list of std) cs - toutes les combinaisons possibles d'école / classes et std jointure externe gauche Données D sur D.sch = cs.sch et D.cls = cs. cls et D.std = cs.std - essayez et joignez les données d'origine Cela fonctionne parfaitement s'il vous plaît aider avec la partie de réglage car les données sont énormes.


veuillez aider à régler la partie car les données sont énormes ... vous devriez ouvrir une nouvelle question.



1
votes

- Modifié: Si vous modifiez votre exigence de INSERT lignes à table en SHOW résultat de la table, vous pouvez utiliser ceci:

WITH std_table AS
(
    SELECT 'Ax' AS std UNION ALL
    SELECT 'Bo' UNION ALL
    SELECT 'Ct' 
)
, tmp_table AS 
(
    SELECT t.sch, t.clas, s.std 
    FROM (SELECT DISTINCT sch, clas FROM table_name) t
    CROSS JOIN std_table s
)
INSERT INTO table_name (sch, clas, std)
SELECT t.sch, t.clas, t.std
FROM tmp_table t
LEFT JOIN table_name t1
ON t.sch = t1.sch AND t.clas = t1.clas AND t.std = t1.std
WHERE t1.std IS NULL;

- Fin de la modification

Vous pouvez utiliser ceci, supposons que le nom de votre table est table_name p >

WITH std_table AS
(
    SELECT 'Ax' AS std UNION ALL
    SELECT 'Bo' UNION ALL
    SELECT 'Ct' 
)
, tmp_table AS 
(
    SELECT t.sch, t.clas, s.std 
    FROM (SELECT DISTINCT sch, clas FROM table_name) t
    CROSS JOIN std_table s
)
SELECT t.sch, t.clas, t.std, t1.date, t1.count
FROM tmp_table t
LEFT JOIN table_name t1
ON t.sch = t1.sch AND t.clas = t1.clas AND t.std = t1.std
ORDER BY t.sch, t.clas, t.std;


0 commentaires

2
votes

Vous pouvez générer les lignes avec une jointure croisée , puis utiliser jointure gauche pour importer les valeurs.

D'après ce que j'ai compris:

< pré> XXX


2 commentaires

J'ai beaucoup apprécié vos réponses. Je ne veux pas insérer de données dans le tableau, il suffit d'afficher les données comme indiqué dans le dernier tableau. Il faut également regrouper avec sch, class et order by std car il montre Ax, Bo et Ct dans l'ordre. Comme sch A - Classe a1 puis séquence std


Vous pouvez simplement classer les lignes en utilisant order by .



2
votes

En supposant que votre table s'appelle Data, alors ce

  • obtient une liste d'écoles - classes à partir du tableau (c)
  • obtient une liste de std à partir de la ou des tables
  • les jointures croisées pour obtenir toutes les combinaisons possibles
  • joint à gauche cela aux données d'origine

Si vous avez d'autres tables avec les données école / classe / std valides, alors il serait probablement préférable d'en obtenir les données, car cela ne fonctionnera pas pour toute valeur qui n'existe pas dans la table de données au moins une fois.

Select cs.sch, cs.cls, cs.std, d.date, d.count
From 
(
   Select c.sch, c.cls, s.std
   From (Select distinct sch, cls from Data) c  --List of school/classes
   Cross Join (select distinct std from Data) s --list of std
) cs  --every possible combination of school/classes and std
left outer join Data D on D.sch = cs.sch and D.cls = cs.cls and D.std = cs.std  --try and join to the original data


1 commentaires

Avec une énorme quantité de données, il faut du temps, alors aidez-moi à régler la partie.