Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Ergebnisse aufgrund mehrerer Bedingungen filtern (NOT IN ...)

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Ergebnisse aufgrund mehrerer Bedingungen filtern (NOT IN ...)

    Bei einer Datenbankabfrage möchte ich sicherstellen, dass ein Video nicht in einer bestimmten Kategorie ist.

    Code:
    SELECT video.*
    FROM videos AS video
    WHERE 1=1
    AND 12 NOT IN (SELECT cat_id FROM videos_cat_relation AS vcr WHERE video.id = vcr.video_id)
    (Es gibt noch andere Bedingungen, die ich mit "1=1" abgekürzt habe.)
    Die Sub-Query wird benötigt, da ein Video in mehr als einer Kategorie sein kann.

    Jetzt möchte ich das ganze erweitern. Alle Videos die in Kategorie 12 oder 13 sind, sollen nicht abgefragt werden.
    Wie kann ich das machen?

  • #2
    Erst einmal solltest du wissen, dass eine select-Abfrage mit * niemals benutzt werden sollte...

    Was dein Problem angeht, denke ich, dass ein Subselect sinnlos ist.

    PHP-Code:
    select
        videos
    .*
    from
        videos
    inner join
        videos_cat_relation vcr
    on
        videos
    .id vcr.video_id and
        
    vcr.cat_id not in (121315)
    where
        1 

    Kommentar


    • #3
      Zitat von Asterixus Beitrag anzeigen
      dass eine select-Abfrage mit * niemals benutzt werden sollte...
      Warum? Wenn ich nun alle abgefragten Felder der Tabelle benutze, dann sehe ich keinen Grund, nicht "*" zu benutzen.

      Kommentar


      • #4
        Deine Lösung wird mir durch den Join mehrere Ergebnisse pro Video liefern.
        Ein SELECT DISTINCT könnte das zwar beheben. Ist aber glaube ich keine gute Lösung.

        Kommentar


        • #5
          Das wäre eine Lösung oder die Videos gruppieren.

          Kommentar


          • #6
            Die Abfrage in #2 liefert imho ein falsches Ergebnis, weil es auch Videos enthält, die Zuordnungen zu einer beliebigen anderen Kategorie nebst der Kategorie 12, 13 besitzen.
            Es sei denn es war dies gemeint
            Alle Videos die ausschließlich in Kategorie 12 oder 13 sind, sollen nicht abgefragt werden.

            Kommentar


            • #7
              Ich habe den Vorschlag gerade implementiert und Harry_X hat Recht:
              wenn ein Video z.B. in Kategorie 1 und 12 ist, dann wird es trotzdem abgefragt, obwohl es eigentlich ausgefiltert werden soll (Kategorie 12).

              Kommentar


              • #8
                Das geht vermutlich nur mit nem join und subselect, dann aber sicher auf mehreren Wegen. Ich versuch mal n ansatz:

                a = erste Selection auf die überhaupt interessanten video,
                b = Kategorientabelle
                c = alle videos mit allen Kategorien
                d = alle Videos mit gruppierten Kats als zeichenkette
                e = die Kat-Zeichenkette auf die ungewünschten Kats untersucht

                PHP-Code:
                SELECT
                     e
                .id
                FROM
                (SELECT
                     d
                .id,
                     
                SUM (LOCATE (d.allcats,'|12|') + LOCATE(d.allcats,'|13|')) as badcatflag
                FROM
                (SELECT 
                     c
                .id,
                     
                CONCAT('0|',GROUP_CONCAT(c.cat,'|'),'|') as allcats
                FROM
                (SELECT 
                      a
                .id,
                      
                b.id as cat
                FROM
                (SELECT
                    id
                FROM video WHERE 
                (1=1)) acats b
                      WHERE a
                .catid b.id
                      GROUP BY c
                .id e
                      WHERE e
                .badcatflag 

                naja.... gibt vllt elegantere Lösungen

                Kommentar


                • #9
                  Select the Selection of the Select of the Selection of the Select of the Selection of the Select of the Selection of the Select from Table video where true as a and cats as b where a.catid equals b.id as c grouped by c.id as d as e where e.badcatflag equals integer 0.

                  Ja, is doch einfach wartbar.

                  Kommentar


                  • #10
                    das ist sogar sehr einfach wartbar, wenn man das Prinzip verstanden hat.
                    Die SUM()-Zeile zB kann man einfach durch einen SELECT auf eine blacklist-cat-table ersetzen.

                    aber bitte, ich würde gern eine elegantere Lösung sehen

                    Kommentar


                    • #11
                      Eh? Watt? Wie? Ganz schön Hardcore, die Lösung.
                      Da wäre ich wohl besser dran, einfach die letzte Zeile in meiner ursprünglichen Lösung zu duplizieren (mit einer anderen Kategorie).

                      Kommentar


                      • #12
                        wenn das funktioniert...

                        Probier doch mal das aus: Leg dir eine table blacklistcats an mit den verbotenen cat_ids
                        und...
                        Code:
                        SELECT video.*
                        FROM videos AS video
                        WHERE 1=1
                        AND (SELECT cat_id FROM blacklistcats) NOT IN (SELECT cat_id FROM videos_cat_relation AS vcr WHERE video.id = vcr.video_id)

                        <strike>kA ob das funktioniert mit selects not in selects...</strike>
                        ^das ist Unsinn - anstelle des Selects not in selects sollte da ein sinnvoller join hin

                        Kommentar


                        • #13
                          Lustig ist das, aber eher nicht anzuraten:

                          PHP-Code:
                          select
                              videos
                          .video_id
                          from
                               videos
                          inner join
                              video_cats
                          on
                              video_cats
                          .video_id videos.video_id
                          where
                              1 
                          1
                          group by
                              video_cats
                          .video_id
                          having
                              group_concat
                          (cat_idnot regexp '(^(12|13)$)|(^(12|13),)|(,(12|13)$)|(,(12|13),)'
                          Ich suche mal gleich was Ordentliches für dich.

                          Kommentar


                          • #14
                            Zitat von Harry_X Beitrag anzeigen
                            ...
                            Man kann in MySQL also auch prüfen, ob ein Elemente eines "Arrays" in einem "Array" enthalten ist?
                            Also
                            Code:
                            ...WHERE ('x', 'y') NOT IN ('a','b','y')...

                            Kommentar


                            • #15
                              Ok, habe mich daran erinnert, dass wir das Problem auch mal hatten und mal nachgeschaut, wie ich das gelöst hatte.
                              Benchmarks geben dafür selbst bei großen Tabellen gute Resultate:

                              PHP-Code:
                              select
                                  videos
                              .*,
                              from
                                  videos
                              inner join
                                  videos_cat_relation
                              on
                                  videos_cat_relation
                              .video_id videos.video_id
                              group by
                                  videos_cat_relation
                              .video_id
                              having
                                  sum
                              (if(cat_id in(1213), 10)) = 0

                              Kommentar

                              Lädt...
                              X