Seite 1 von 1

Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Fr, 30. Jun 2017 13:00
von UliTs
Ein kniffliges Filterproblem:

Ich habe eine Tabelle der Art
ListenId,ListenPosId,LfdNr,MaschinenSchritt
Der Inhalt könnte z.B. wie folgt aussehen:
  • ListenId=1,ListenPosId=1,LfdNr=1,MaschinenSchritt='Bohren'
    ListenId=1,ListenPosId=2,LfdNr=2,MaschinenSchritt='Fräsen'
    ListenId=1,ListenPosId=3,LfdNr=3,MaschinenSchritt='Schleifen'
    ListenId=2,ListenPosId=4,LfdNr=1,MaschinenSchritt='Bohren'
    ListenId=2,ListenPosId=5,LfdNr=2,MaschinenSchritt='Schleifen'
    ListenId=2,ListenPosId=6,LfdNr=3,MaschinenSchritt='Fräsen'
Jetzt möchte ich nach allen Listen filtern, die eine bestimmte Reihenfolge der Maschinenschritte enthalten.
Z.B. ich suche nach der Reihenfolge "Schleifen,Fräsen". Dann müßte als Ergebnis {ListenId=2} herauskommen.
Wie mache ich das am geschicktesten mit einem SQL-Statement?

Uli

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Fr, 30. Jun 2017 14:22
von nightcrawler
Das fragst Du nicht wirklich - oder?
Erst mal die Tabelle mit den Daten

Code: Alles auswählen

create table uli (listenid integer, listenposid integer, lfdnr integer, maschinenschritt cichar(30));
insert into uli values
  (1,1,1,'Bohren'),
  (1,2,2,'Fräsen'),
  (1,3,3,'Schleifen'),
  (2,4,1,'Bohren'),
  (2,5,2,'Schleifen'),
  (2,6,3,'Fräsen');
Dann die Tabelle mit sich selbst verknüpfen ... so, dass der Arbeitsschritt in U1 und der Folgeschritt in u2 ist:

Code: Alles auswählen

select u2.* from uli u1, uli u2
where (u1.listenid=u2.listenid)
  and (u1.lfdnr=u2.lfdnr-1)
Jetzt noch einschränken, so dass nur Schleifen/Fräsen gilt:

Code: Alles auswählen

select u2.* from uli u1, uli u2
where (u1.listenid=u2.listenid)
  and (u1.lfdnr=u2.lfdnr-1)
  and u1.maschinenschritt like 'Schleifen'
  and u2.maschinenschritt like 'Fräsen'
je nachdem, ob Du u1.* oder u2.* wählst, bekommst Du den ersten oder den zweiten Arbeitsgang als Ergebnis.

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Fr, 30. Jun 2017 14:46
von brandelh
wenn du mit dem Text arbeitest, bist du aber von der Sprache abhängig.

Ich würde einen Zwischenschritt einlegen und eine "Arbeitsschritt-ID" einführen, hier im Beispiel als Variable mit eigenem Namen.

idBohren = "AS001"
idSchleifen = "AS002"
idFräsen = "AS004" etc.

dann in der Tabelle welche Arbeitsschritte zu erledigen sind, diese als String hinterlegen ... z.B. in Memofeld:

Arbeit := idSchleifen + "," + idFräsen ...

Suche nach "Schleifen,Fräsen":

cSuche := idSchleifen + "," + idFräsen "

Dann suchen wo cSuche in Arbeit vorkommt, egal ob DBF, FOX oder SQL Server die Logik funktioniert immer.
Die Trennzeichen kann man auch weg lassen, wenn die ID wie hier eindeutig startet.

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Mo, 03. Jul 2017 8:46
von UliTs
Danke für die Tipps.
Habe gerade keine Zeit, sie mir genauer anzuschauen.
Joachim, ich meine, Dein Vorschlag funktioniert so nicht, es sei denn, man setzt voraus, dass es keine Lücken in LfdNr gibt.
Hubert: bei Dir wird die Reihenfolge der Schritte nicht berücksichtigt. Außerdem könnten andere Schritte dazwischen liegen.

Uli

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Mo, 03. Jul 2017 10:22
von brandelh
Uli, du solltest mal genau lesen, was ich geschrieben habe !

Mein Vorschlag legt jeden Schritt in der richtigen Reihenfolge in dem ID Feld ab (Textbezeichnung ist dafür egal) - dieses wird aus deiner Liste gebildet:

Beispiel:
idBohren = "AS001"
idSchleifen = "AS002"
idFräsen = "AS004" etc.

1: "AS003,AS002,AS001,AS004,AS008"
2: "AS003,AS002,AS004,AS008"

Suche nach "AS002,AS004" // Schleifen Fräsen, nix dazwischen, in dieser Reihenfolge, aber egal was davor oder danach kommt.

Ergebnis NUR Zeile 2, da in Zeile 1 ein AS001 dazwischen liegt. Laut deiner Beschreibung schloss ich, dass es egal ist ob davor und danach andere Sachen kommen.

Falls du gemeint hast, dass er hier beide Zeilen finden soll, da beide Tätigkeiten vorkommen, war deine Beschreibung falsch ;-)

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Di, 04. Jul 2017 16:26
von UliTs
brandelh hat geschrieben: Mo, 03. Jul 2017 10:22 Uli, du solltest mal genau lesen, was ich geschrieben habe !
...
Hubert, du solltest mal genau lesen, was ich geschrieben habe: "Habe gerade keine Zeit, sie mir genauer anzuschauen." ;-)

Uli

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Di, 04. Jul 2017 16:34
von UliTs
Hubert,

gute Idee für eine Lösung. Das kann man auch als Sql-Script lösen.
Man könnte eine temporäre Tabelle erstellen, die je Eintrag die von Dir vorgeschlagene Zeichenfolge der zugehörigen Liste enthält. Dabei könnte man schon nach Listen filtern, die die gesuchten Einträge beinhaltet. Das kann aber auch so zu lange dauern...
Mal sehen, wenn mir nichts anderes einfällt, werde ich das so ausprobieren.

Uli

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Di, 04. Jul 2017 19:52
von nightcrawler
Hi Uli,
UliTs hat geschrieben: Mo, 03. Jul 2017 8:46 Joachim, ich meine, Dein Vorschlag funktioniert so nicht, es sei denn, man setzt voraus, dass es keine Lücken in LfdNr gibt.
Hubert: bei Dir wird die Reihenfolge der Schritte nicht berücksichtigt. Außerdem könnten andere Schritte dazwischen liegen.
Das stand nicht in der SPEC ;)

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Mi, 05. Jul 2017 3:20
von UliTs
nightcrawler hat geschrieben: Di, 04. Jul 2017 19:52 Hi Uli,
UliTs hat geschrieben: Mo, 03. Jul 2017 8:46 Joachim, ich meine, Dein Vorschlag funktioniert so nicht, es sei denn, man setzt voraus, dass es keine Lücken in LfdNr gibt.
Hubert: bei Dir wird die Reihenfolge der Schritte nicht berücksichtigt. Außerdem könnten andere Schritte dazwischen liegen.
Das stand nicht in der SPEC ;)
Sehr wohl ;-) . Lediglich das Beispiel enthielt auch nur 2 aufeinanderfolgende Listeneinträge 8) .

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Mi, 05. Jul 2017 12:56
von brandelh
UliTs hat geschrieben: Di, 04. Jul 2017 16:34 Hubert,
gute Idee für eine Lösung. Das kann man auch als Sql-Script lösen.
Man könnte eine temporäre Tabelle erstellen, die je Eintrag die von Dir vorgeschlagene Zeichenfolge der zugehörigen Liste enthält.
genau SQL - SELECT auf die Listen, die grundsätzlich diese beiden Elemente haben ...
daraus dann ein String Array und das mit ASORT() durchsuchen cSuch $ cArbeitsliste ...

Wenn das zu langsam ist, würde ich einfach einen Job erstellen, der eine tatsächliche tabelle anlegt (regelmäßig und/oder per trigger das aktuell hält) und darauf mit SELECT zugreifen sooft man es lesen will.

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Mi, 05. Jul 2017 22:53
von AUGE_OHR
Frage : liegen die Daten schon als Datenbank (DBF, SQL-Table) vor ?
UliTs hat geschrieben: Fr, 30. Jun 2017 13:00Z.B. ich suche nach der Reihenfolge "Schleifen,Fräsen". Dann müßte als Ergebnis {ListenId=2} herauskommen.
hm ... die Reihenfolge der "MaschinenSchritt(e)" ist also wichtig

ich muss jeden Auftrag = ListenId untersuchen ob :
a.) ob gesuchte Begriffe enthalten sind
b.) ob die Reihenfolge stimmt.

zu b.) die Frage ist wie man ein den "nächsten" Datensatz / Row unter SQL bekommt.

man könnte versuchen "row_number" (PostgreSQL) oder "rowid" (mySQL) in die SQL-Query einzubauen.
man nimmt das Resultset und navigiert da mit einem o:Skip()

---
eine DBF / Array Lösung könnte so aussehen

Code: Alles auswählen

Index on StrZero(ListenId,10)+StrZero(LfdNr,10)+MaschinenSchritt TO MyIndex
aSeek := {"Schleifen,Fräsen"}

GO BOTTOM
// höchste Auftragsnummer
nLast := FIELD->ListenId

FOR i := 1 TO nLast 
   // ob gesuchte Begriffe enthalten sind
   aResult := Seek_multi(i,aSeek) 
   // gleiche Anzahl
   IF LEN(aResult) = LEN(aSeek)
      // Reihenfolge prüfen
      IF Check_Position(aResult)
         // Treffer
      ENDIF 
   ENDIF
NEXT

Re: Suchen Nach Listen mit Positionen in bestimmter Reihenfolge

Verfasst: Do, 06. Jul 2017 21:16
von nightcrawler
UliTs hat geschrieben: Mi, 05. Jul 2017 3:20 Sehr wohl ;-) . Lediglich das Beispiel enthielt auch nur 2 aufeinanderfolgende Listeneinträge 8) .
Also flux noch ein paar Datensätze ohne direkte Folge

Code: Alles auswählen

insert into uli values
  (3,7,1,'Bohren'),
  (3,10,3,'Fräsen'),
  (3,12,5,'Schleifen'),
  (4,15,1,'Bohren'),
  (4,18,4,'Schleifen'),
  (4,23,6,'Fräsen');
Da die phys. Reihenfolge nicht mit der logischen Reihenfolge zusammenhängt, kannst Du weder rownum(), noch Rowid oder ähnliches nehmen. Es bleibt nur noch ein Script bzw gleich eine Stored Procedure:

Code: Alles auswählen

CREATE PROCEDURE FindeSchritt(schritt1 CICHAR(255), schritt2 CICHAR(255), RID CHAR(18) OUTPUT)
BEGIN
DECLARE @tab CURSOR AS SELECT rowid, listenid, listenposid, lfdnr, maschinenschritt from uli ORDER BY 1,2,3;
DECLARE @listenid INTEGER;
DECLARE @maschinenschritt STRING;
OPEN @tab;
@listenid=-1;
@maschinenschritt='';
WHILE FETCH @tab DO
  IF @listenid<>@tab.listenid THEN 
    //Listenbeginn
    @listenid=@tab.listenid;
    @maschinenschritt='';
  END IF;
  IF @maschinenschritt=_schritt1 AND @tab.maschinenschritt=_schritt2 THEN
    INSERT INTO __output(RID) VALUES (@tab.ROWID);
  END IF;
  @maschinenschritt=@tab.maschinenschritt;
END WHILE;
CLOSE @tab;
END;
Anwendung

Code: Alles auswählen

SELECT * FROM uli WHERE Rowid in 
(SELECT * FROM (EXECUTE PROCEDURE FindeSchritt('Schleifen', 'Fräsen')) a)