Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

SQL LIKE και SUBSTRING (ανάποδο)

Îåêßíçóå áðü ôï ìÝëïò Panos Kousidis. Τελευταία δημοσίευση από το μέλος Panos Kousidis στις 17-09-2015, 13:22. Υπάρχουν 14 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  15-09-2015, 13:29 77234

    SQL LIKE και SUBSTRING (ανάποδο)

    Καλησπέρα σε όλους,

    Θα ήθελα να ρωτήσω την κοινότητα ποιος είναι ο πιο σωστός τρόπος να εκτελέσω μια διαδικασία

    Έχω λοιπόν ένα datatable που τα values ενός column που με ενδιαφέρει είναι :

    ALPHA
    BETA
    GAMMA
    DELTA

    Έχω ένα string "BETA3987FF39" και θέλω μία μέθοδο που να κάνει match το string με το pattern της στήλης + '%', δηλαδή το ανάποδο από το κλασσικό like

    Υπάρχει κάποιος τρόπος να γίνει με method της vb όπως πχ table.Select  ή θα πρέπει να κάνω loop στα rows του πίνακα και να ελέγχω μία μία τις εγγραφές;

     

    Ευχαριστώ,
    Πάνος


    Panos
  •  15-09-2015, 14:52 77236 σε απάντηση της 77234

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Κάπου σ' έχασα στο: "δηλαδή το ανάποδο από το κλασικό like".

    Κατ' αρχήν, η σύγκριση που θέλεις να γίνεται; Στον server ή στον client; Αν πρόκειται για την δεύτερη περίπτωση, μήπως θα βόλευε να χρησιμοποιήσεις κάποιο datacolumn expression.

     

    [EDIT]

    To string "BETA3987FF39" υπάρχει σε κάποιον πίνακα της βάσης ή το εισάγει ο χρήστης;


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  15-09-2015, 15:08 77237 σε απάντηση της 77234

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Εννοεις ενα ισοδύναμο σε αυτό;

     where (field='B' OR field='BE' OR field='BET' OR field='BETA' OR field='BETA3' ...)

     

  •  15-09-2015, 15:54 77238 σε απάντηση της 77236

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Ναι ίσως δεν ήμουν πολύ σαφής, οπότε να το διευκρινήσω. Στη δική μου περίπτωση θέλω να γίνει στον client η σύγκριση, αλλά θα ήθελα να ξέρω εάν γίνεται κάπως και στον SQL σε αντίστοιχη περίπτωση

    Το table έχει μέσα στην ουσία τα patterns που θέλω να ταιριάξω με ένα value που δίνει ο χρήστης. Δηλαδή, δίνοντας ο χρήστης το string "BETA3987FF39" να μου επιστραφεί το row του Datatable ή του SQL Table που περιέχει το value "BETA". "Ανάποδο like" είπα γιατί στην περίπτωση που τα πράγματα ήταν ανάποδα, δηλαδή ο χρήστης έδινε το string "ΒΕΤΑ" και ο πίνακας είχε μέσα το "BETA3987FF39" τότε θα ήταν εύκολο, θα χρησιμοποιούσα το select ('col1 like ' & userinputstring & '%').

    Τώρα θέλω κάτι αντίστοιχο του 'userinputstring like concat(col1,'%')  ώστε στην ουσία το query να μεταφραστεί σε BETA3987FF39 like 'ALPHA%', BETA3987FF39 like 'BETA%', 'BETA3987FF39' like 'GAMMA%' κοκ και να μου επιστρέψει το row που περιέχει μέσα το "BETA"

     

     


    Panos
  •  15-09-2015, 17:10 77239 σε απάντηση της 77238

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Γιατι δεν "καθαριζεις" τη λεξη πριν κάνεις το query, δλδ να αφαιρεσείς το 3987FF39 (εφοσον δε σε ενδιαφέρει αυτο το κομματι)
  •  15-09-2015, 17:48 77240 σε απάντηση της 77239

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Επειδή δεν ήθελα να στηριχτώ σε κάτι μεταβλητό.

    Η προσωρινή λύση που έφτιαξα είναι με ένα RegEx να κάνει match από την αρχή του string μέχρι το πρώτο νούμερο που θα βρει, γιατί στην περίπτωσή μου ακολουθεί πάντα νούμερο μετά το "ALPHA", "BETA" και δουλεύει οκ.

    Αλλά ήθελα κάτι που να καλύψει και τις περιπτώσεις "BETAXJK232" όπου δε φαίνεται πιο είναι το "καθαρό" κομμάτι του string αλλά ταιριάζει στο row που έχει το BETA%

    Μάλλον δεν το γλυτώνω το loop ή τον κέρσορα στον SQL για τέτοιες περιπτώσεις...

     

    Ευχαριστώ


    Panos
  •  15-09-2015, 22:15 77241 σε απάντηση της 77240

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Μάλλον πρέπει να ξεκινήσεις ανάποδα και να φτιάξεις ένα TSQL Function που θα επιστρέφει ένα value ή ένα table, ανάλογα με το τι θέλεις. Δηλαδή, βάλε το input string "BETAXJK232" σ' ένα loop και κάνε διαδοχικά Select - Like αφαιρώντας έναν χαρακτήρα κάθε φορά από το τέλος, μέχρι να προκύψει αποτέλεσμα. Δηλ. Like "BETAXJK232%",  Like "BETAXJK23%", Like "BETAXJK2%", Like "BETAXJK%" κ.ο.κ. Δεν ξέρω μόνο τι θα συμβεί από performance. Αν φορτώνες τα patterns στον client και η σύγκριση γίνεται εκεί, πάλι μπορείς να χρησιμοποιήσεις αυτή την προσέγγιση μιας και το DataColumn expression, που σου ανέφερα παραπάνω, υποστηρίζει τον operator LIKE. Ίσως είναι καλύτερο να δοκιμάσεις και τις δύο προσεγγίσεις για να δεις ποια έχει μικρότερο overhead.

    PS: Γιατί να μπλέξεις με cursors?

    [EDIT]

    Αν πάλι το input string είναι πολύ μεγάλο, μπορείς να κάνεις πρώτα ένα Select Max(Len(patternString)) from YourPatternTable και να "κόψεις" πολλούς χαρακτήρες από το τέλος με την πρώτη δοκιμή.


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  15-09-2015, 22:42 77242 σε απάντηση της 77240

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Μήπως πρέπει να σκεφτείς το full text search?


     

     


    Antonios Chatzipavlis

  •  16-09-2015, 15:07 77244 σε απάντηση της 77241

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Χμμ ναι πολύ καλή μου φαίνεται η ιδέα αφαίρεσης χαρακτήρων από το τέλος

    Εσύ λες δηλαδή να χρησιμοποιήσω κάτι τέτοιο σε μια function (το LIKE πλέον δε θα χρειάζεται γιατί το string θα γίνει ακριβώς ίδιο):

    CREATE FUNCTION [dbo].[GetTblVal] ( @CheckVal VARCHAR(100) )
    RETURNS VARCHAR(100)
    AS
        BEGIN
            DECLARE @RetVal VARCHAR(100) ,
                @iLen INT = LEN(@CheckVal);

            WHILE @iLen > 0
                BEGIN
                    SET @CheckVal = SUBSTRING(@CheckVal, 1, @iLen);
                    SELECT  @RetVal = COL1 FROM TBL1 WHERE   COL1 = @CheckVal;
                    IF NOT @RetVal IS NULL BREAK;
                    SET @iLen -= 1;
                END;
            RETURN @RetVal;
        END;

    Παρά με κέρσορα κάτι τέτοιο

    CREATE FUNCTION [dbo].[GetTblVal] ( @CheckVal VARCHAR(100) )
    RETURNS VARCHAR(100)
    AS
        BEGIN
            DECLARE @TBLVAL VARCHAR(100);
            DECLARE C CURSOR FOR SELECT  COL1 FROM TBL1;
            OPEN C;
            FETCH NEXT FROM C INTO @TBLVAL;
            WHILE @@FETCH_STATUS = 0
                BEGIN
                    IF CHARINDEX(@TBLVAL, @CheckVal) > 0 BREAK;
                    FETCH NEXT FROM C INTO @TBLVAL;
                END;
            CLOSE C;
            DEALLOCATE C;
            RETURN @TBLVAL;
        END;

    Στην πρώτη περίπτωση θα γίνουν τόσα select από το table όσοι και οι χαρακτήρες που θα αφαιρεθούν, που μπορούν να μειωθούν αν δω το μήκος του μεγαλύτερου string στον πίνακα και ξεκινήσω από αυτό το νούμερο
    ενώ στην περίπτωση του cursor θα γίνει ένα select και loop μέσα στα αποτελέσματα μέχρι να βρεθεί το row, εκτός αν o cursor δε λειτουργεί έτσι και απλά θα ήθελα να λειτουργούσε έτσι.

    Πάντως όσον αφορά την υλοποίηση στον Client, το πρώτο που μου είχε έρθει είναι το αντίστοιχο του cursor όπου θα κάνω loop μέσα στα datarows, ελέγχοντας εάν το IndexOf αντίστοιχα με το CHARINDEX του SQL είναι > -1

    Με το full-text search δεν έχω ασχοληθεί ιδιαίτερα, μόνο ότι χρειάστηκε για το certification 70-461.. Από τα λίγα που διάβασα δε θυμάμαι να είδα κάτι που να μπορούσε να βοηθήσει σε αυτή την περίπτωση καθώς έπαιζε με replacement strings, συνώνυμα και γενικώς "ανώτερου επιπέδου" κατανόηση γλώσσας. Αλλά πως μπορείς να του πεις για ένα άγνωστο string που θα έρθει από το χρήστη και δεν υπάρχει σε κανένα "λεξικό" σου ότι αυτό μπορεί να αντικατασταθεί με κάτι άλλο (BETAXJK@4223 --> BETA)
    Εκτός αν το είδα τόσο πολύ επιφανειακά το θέμα και έχει κι άλλα κόλπα. Θα το παρακολουθήσω το βιντεάκι γιατί μου κίνησε το ενδιαφέρον, ευχαριστώ!

     


    Panos
  •  16-09-2015, 21:30 77245 σε απάντηση της 77244

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Γενικά οι cursors δεν έχουν καλή φήμη και τους αποφεύγω. Βεβαίως, τίποτα δεν είναι κακό όταν χρησιμοποιείται σωστά. Μπορείς να διαβάσεις τι έχει γράψει και ο Αντώνης για τη χρήση τους. Προφανώς, όλα εξαρτώνται από το πλήθος των εγγραφών του πίνακα των patterns, αν έχεις κάνει σωστή χρήση των indexes κ.λπ. Όλες τις προτεινόμενες λύσεις μπορείς να τις μετρήσεις μόνο εσύ που έχεις πρόσβαση στα δεδομένα.

    Έτσι όπως το βλέπω, η αφαίρεση χαρακτήρων από το τέλος του string είναι προτιμότερη. Φαντάσου πως έχεις δύο patterns (QWERTY, QWERTYIO) και σαν input QWERTYIO4898748239. Προφανώς θέλεις να σου "έρθειι" το δεύτερο. Επίσης, στο ίδιο select για το max length μπορείς να ζητήσεις και το min length των patterns. Έτσι αν κάποιο input δεν ταιριάζει με κάποιο pattern λόγω σφάλματος, θα "τρέξεις" ακόμα λιγότερα selects, μιας και θα είναι ανούσιο να ψάχνεις για strings με λιγότερους χαρακτήρες.


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  16-09-2015, 21:42 77246 σε απάντηση της 77244

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Αν και υποψιάζομαι πως θα γίνει η χρήση τους εντούτοις θα σου ήταν εύκολο να μας δείξεις πως θα τα χρησιμοποιήσεις αυτά με παραδείγματα;
    Antonios Chatzipavlis

  •  17-09-2015, 00:07 77247 σε απάντηση της 77244

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Σκέφτηκα λίγο για το πως θα μπορούσε να βελτιστοποιηθεί η διαδικασία αναζήτησης με χρήση cursors και κατέληξα περίπου σ' αυτό (να δούμε τι θα πει και ο Αντώνης).

    1) Βρες το index του checkVal που εμφανίζεται ο πρώτος αριθμός και "κόψε" το string σ' αυτό το σημείο, ώστε να υπάρχουν μόνο γράμματα. Έστω checkVal2 η νέα τιμή.

    2) Άνοιξε έναν cursor για Select patternName from PatternTable where left(patternName,1) = left(checkVal2,1) and len(patternName) <= len(checkVal2) order by patternName desc;

    Όλο αυτό για να ελαχιστοποίησεις το query space και DESC για να αποφύγεις κακοτοπιές τύπου (QWERTY, QWERTYIO) για τα patterns.

    3) Φέρε την πρώτη τιμή του result set (έστω patternVal)

    4) Κάνε σύγκριση του checkVal2 με το patternVal. Αν είναι ίσα, επέστρεψε το patternVal.

    5) Αν δεν είναι ίσα, αφαίρεσε ένα χαρακτήρα σπό το τέλος του checkVal2 και πήγαινε ξανά στο βήμα 4. Αν εξαντληθούν οι χαρακτήρες, πήγαινε στο 6

    6) Φέρε την επόμενη τιμή. Αν υπάρχει -> βήμα 4.(*)

    7) Τέλος

     

    (*) Μην ξεχάσεις ν' αποκαταστήσεις την αρχική τιμή του checkVal2, μετά το "κόψιμο" των χαρακτήρων από το τέλος., προκειμένου να προχωρήσεις στην επόμενη σύγκριση.

     

    [EDIT2]

    Ανοησία μου.  Το απλό charindex δουλεύει μια χαρά.


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  17-09-2015, 00:48 77248 σε απάντηση της 77247

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Νομίζω ότι αυτό είναι καλύτερο από functions & cursors
     

    declare @SARG_VALUES table(value nvarchar(100));

    insert into @SARG_VALUES values (N'ALPHA'),(N'BETA'),(N'GAMMA'),(N'DELTA')

    declare @searched_value nvarchar(100) = N'BETA3987FF39';

    declare @sarg_value nvarchar(100);

    select @sarg_value = value+'%' from @SARG_VALUES

    where CHARINDEX(value,@searched_value,1)>0;

    select * from T

    where col like @sarg_value

     

    Antonios Chatzipavlis

  •  17-09-2015, 01:08 77249 σε απάντηση της 77248

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Αυτή την ώρα η σύνδεσή μου πάει πιο αργά κι από χελώνα.

    @Αντώνης: Απλό σαν το αυγό του Κολόμβου.

     Select patternName from PatternTable where charindex(patternName, @checkValue)>0; AAAAGR Why didn't I see that?


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  17-09-2015, 13:22 77251 σε απάντηση της 77248

    Απ: SQL LIKE και SUBSTRING (ανάποδο)

    Κάτι τέτοιο έψαχνα Αντώνη, ευχαριστώ πολύ! Ήμουν κοντά με την υλοποίηση του cursor αλλά δε σκέφτηκα ότι δε χρειάζεται καν!

    Κάτι αντίστοιχο πιστεύω θα γίνεται και στο datatable στο vs, αλλά θα το βρω αυτό αφού κατάλαβα τη λογική...

    Ευχαριστώ κι εσάς Μάρκο και Νίκο για τις προτάσεις και το χρόνο σας!



    Panos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems