IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Filtrer les données d'une table, qui n'existe pas


Sujet :

PHP & Base de données

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 227
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 227
    Par défaut Filtrer les données d'une table, qui n'existe pas
    Bonjour,

    Je travaille sur une requête MySQL que j'utilise depuis quelque temps.

    J'ai rajouté une table 'stations_notification_disable_by_user', qui va ajouter des lignes quand un paramètre change. (j'explique plus bas)

    1) J'ai une table 'fields_has_users' qui va contenir les terrains existant et les utilisateurs attitrés au(x) terrain(s).
    fields_has_users
    ===
    id_fields_id_field
    users_id_user
    fields_id_field
    roles_id_role
    2) J'ai une autre table 'stations' qui contient les informations sur mes stations (disons que cette table a 30 stations)
    stations
    ===
    id_station
    station_name
    station_detail
    3) J'ai une autre table 'stations_notification_disable_by_user'
    stations_notification_disable_by_user
    ===
    id_sndby (int(4))
    stations_id_station (int(4))
    sndbu_onesignalExtId (int(4)) (= user)
    notification_isDisabled (tinyint(1))
    create (datetime)
    Initialement, cette table est vide. Un utilisateur peut décider de recevoir ou pas des notifications d'une station, grâce au paramètre 'notification'

    • Si ce paramètre n'a pas encore été défini pour une station et pour un utilisateur, il n'y a pas de valeur dans la table 'stations_notification_disable_by_user', et le switch doit être en mode activé.
      [* ]Si l'utilisateur 2 décide que cette station (43) ne doit pas envoyer de notification à cet utilisateur, l'utilisateur va basculer le switch qui prendra le mode désactivé.
      Une nouvelle ligne sera alors ajouté dans la table pour l'utilisateur 2


    id_sndby => 1
    stations_id_station => 43
    sndbu_onesignalExtId => 2
    notification_isDisabled => 1
    create => 2026-07-01 23:00:00
    Si plus tard, il change d'avis, la ligne sera modifiée ainsi
    id_sndby => 1
    stations_id_station => 43
    sndbu_onesignalExtId => 2
    notification_isDisabled => 0
    create => 2026-07-01 23:00:00
    Le problème est que quand je charge ma page (je suis l'utilisateur 2) le swicth prend le bon état. Mais quand je défini une autre station, la deuxième station n'a pas toujours la bonne valeur pour le paramètre 'notification'. Des fois c'est 1, et des fois 0....

    J'ai modifié ma requete MySQL et j'ai dû faire faux à au niveau de JOIN LEFT LEFT JOIN stations_notification_disable_by_user AS sndbu ON st.id_station = sndbu.stations_id_station.


    PS: LEFT JOIN thresholds as th ON se.id_sensor = th.sensors_id_sensor, fonctionne, mais il est probable que je revoye ceci après

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    $sql_select ='SELECT fi.id_field, fi.field_name, st.id_station, st.station_name, st.station_longname, st.station_archive, st.station_active, sty.stations_type_awe, st.stations_types_id_stations_type, st.station_lat, st.station_lng, st.station_alt, st.alarm_is_enabled, sty.stations_type_name, se.id_sensor, se.sensor_active, se.sensor_name, se.sensor_longname, se.chart_borderWidth, se.chart_pointRadius, se.chart_pointHoverRadius, se.chart_showLine, se.chart_fill, sey.id_sensor_type, sey.sensor_type_name, sey.sensor_type_longname, sey.sensor_type_awe, sey.measure_unit, cs.chart_style_name, uf.roles_id_role, sndbu.notification_disabled, sndbu.sndbu_onesignalExtId,
    			cp.chart_pointStyle_value, th.threshold_max, th.threshold_min, th.threshold_operator,
    			col_bg.color_name as bg_color_name, 
    			col_bg.color_value as bg_color_value,
    			col_bd.color_name as bd_color_name, 
    			col_bd.color_value as bd_color_value
    			FROM fields AS fi
    			INNER JOIN users_has_fields AS uf ON fi.id_field = uf.fields_id_field
    			RIGHT JOIN stations AS st ON fi.id_field = st.fields_id_field
     
    		LEFT JOIN stations_notification_disable_by_user AS sndbu ON st.id_station = sndbu.stations_id_station
     
    			INNER JOIN sensors AS se ON st.id_station = se.stations_id_station
    			INNER JOIN stations_types as sty ON st.stations_types_id_stations_type = sty.id_stations_type
    			INNER JOIN chart_backgroundColor AS cbgc on cbgc.id_chart_backgroundColor=se.chart_backgroundColor_id_chart_backgroundColor
    			INNER JOIN colors AS col_bg on cbgc.colors_id_colors=col_bg.id_colors
    			INNER JOIN chart_borderColor AS cbdc on cbdc.id_chart_borderColor=se.chart_borderColor_id_chart_borderColor
    			INNER JOIN colors AS col_bd on cbdc.colors_id_colors=col_bd.id_colors
    			INNER JOIN chart_style as cs ON se.chart_style_id_chart_style = cs.id_chart_style
    			INNER JOIN chart_pointStyle AS cp on se.chart_pointStyle_id_chart_pointStyle = cp.id_chart_pointStyle
    			INNER JOIN sensor_types as sey ON se.sensor_types_id_sensor_type = sey.id_sensor_type
    			LEFT JOIN thresholds as th ON se.id_sensor = th.sensors_id_sensor
    			WHERE '.$whereFieldId.' st.station_active = 1 AND st.map = 1 AND fi.field_active = 1 AND uf.users_id_user = '.$user_id.' AND se.sensor_active = 1
    			ORDER BY sty.stations_type_name ASC, fi.id_field ASC, st.station_longname ASC, se.sensor_longname ASC';
     
    		$sql_result = $connect->query($sql_select);

    Actuellement, j'ai 4 lignes (ja'i mis n'importe quoi pour l'heure). L'utilisateur 2, à modifié les stations 43 et 30 et il ne veut pas recevoir de notification
    1 - 43 - 2 - 1 - 2026-07-01 23:00:00
    2 - 30 - 2 - 1 - 2026-07-01 23:00:00
    3 - 43 - 4 - 0 - 2026-07-01 23:00:00
    4 - 43 - 5 - 0 - 2026-07-01 23:00:00
    A mon avis, déjà pour les stations 1 à 29 et 31 à 42 et après 44

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $row['notification_disabled']
    me retourn NULL parce qu'il n'y a pas de saisies pour ces station

    mais pour la station 43, il y a 3 saisies alors que je suis l'utilisateur 2

    Est-ce que on peut modifier cette ligne
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    LEFT JOIN stations_notification_disable_by_user AS sndbu ON st.id_station = sndbu.stations_id_station
    pour qu'il tienne en compte que l'utilisateur sélectionné, dans mon cas l'utilisateur 2.
    • Si je suis l'utilisateur 2, $row['notification_disabled'] prend la valeur false si le champs 'notification_disabled' a la valeur 0
    • Si je suis l'utilisateur 2, $row['notification_disabled'] prend la valeur true si le champs 'notification_disabled' a la valeur 1
    • Si non $row['notification_disabled'] doit toujours etre false


    Bien entendu, si je suis un autre utilisateur, $row['notification_disabled'] doit prendre la valeur de true ou false, en fonction du contenu de la table 'stations_notification_disable_by_user'

    Ma question est comment modifier cette ligne LEFT JOIN stations_notification_disable_by_user AS sndbu ON st.id_station = sndbu.stations_id_station, (ou autrement) pour que l'id de la station et de l'utilisteur soient pris en compte, et si les valeurs des stations et des utilisateurs ne correspondent à aucunes lignes, la valeur false est retorunée...


    J'espère avoir bien expliquer mon cas....

  2. #2
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 374
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 374
    Billets dans le blog
    17
    Par défaut
    Salut pierrot10 !

    Ma question est comment modifier cette ligne LEFT JOIN stations_notification_disable_by_user AS sndbu ON st.id_station = sndbu.stations_id_station, (ou autrement) pour que l'id de la station et de l'utilisteur soient pris en compte, et si les valeurs des stations et des utilisateurs ne correspondent à aucunes lignes, la valeur false est retorunée...
    Quelle est la relation entre l'utilisateur et une station sur laquelle il n'a jamais eu de notification ?
    Si j'ai bien compris dans ce cas tu veux false également.

    Avec un schéma de ce genre :

    use tests;
    
    create table user (
    	id int unsigned auto_increment primary key,
    	name varchar(20) not null
    );
    
    create table station (
    	id int unsigned auto_increment primary key,
    	name varchar(20) not null
    );
    
    create table notification (
    	user_id int unsigned,
    	station_id int unsigned,
    	is_active bool not null,
    	primary key (user_id, station_id),
    	foreign key (user_id) references user (id) on update cascade on delete cascade,
    	foreign key (station_id) references station (id) on update cascade on delete cascade
    );
    Et le jeu de données suivant :

    insert into user (id, name)
    values (1, 'Martin'), (2, 'Valentine');
    
    insert into station (id, name)
    values (1, 'ALP-1'), (2, 'PYR-1'), (3, 'ALP-2');
    
    insert into notification (user_id, station_id, is_active)
    values (1, 2, true), (1, 3, true), (2, 3, false);
    Pour obtenir :

    Martin	ALP-1	0
    Martin	ALP-2	1
    Martin	PYR-1	1
    Valentine	ALP-1	0
    Valentine	ALP-2	0
    Valentine	PYR-1	0
    Il faut faire :

    select all
    	u.name as user_name, s.name as station_name, 
    	coalesce(n.is_active, false) as is_active
    from user as u
    cross join station as s
    left outer join notification as n on (u.id, s.id) = (n.user_id, n.station_id)
    order by 1 asc, 2 asc;
    Le cross join permet d'avoir toutes les combinaisons de user/station, ensuite le left join va chercher les notifications renseignées, si pas de ligne de notification pour un couple user/station alors le coalesce permet d'avoir un false par défaut.

    Voilà pour le principe
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

Discussions similaires

  1. Réponses: 8
    Dernier message: 02/05/2025, 23h11
  2. Réponses: 5
    Dernier message: 27/04/2010, 14h55
  3. Réponses: 10
    Dernier message: 18/06/2009, 13h27
  4. Réponses: 2
    Dernier message: 07/12/2007, 15h20
  5. Pb avec hibernate3, il cherche une table qui n'existe pas
    Par yeddoughmi dans le forum Hibernate
    Réponses: 2
    Dernier message: 22/08/2007, 12h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo