|
Îåêßíçóå áðü ôï ìÝëïò neoklis. Τελευταία δημοσίευση από το μέλος spaceman στις 15-12-2010, 16:24. Υπάρχουν 27 απαντήσεις.
-
13-12-2010, 14:06
|
-
neoklis
-
-
-
Μέλος από τις 18-06-2007
-
-
Δημοσιεύσεις 192
-
-
|
Παιδιά καλησπέρα,
Σε έναν πίνακα που έχει γίνει imported από txt file έχει διπλοεγγραφές (id,Descr). Η βάση είναι σε SQL 2008.
π.χ.
ID Description
1032381 Το καινούριο μου αυτοκίνητο
1032381 είναι ένα ηλεκτρικό αυτοκίνητο
Αυτό που θέλω, ειναι να κάνω insert into σε κενό πίνακα, με κλειδί το ID και να έχω όλο το description σε μια γραμμή. Πιθανόν εκτος από διπλοεγγραφές να έχω και περισσότερες.. Πρώτη φορά αντιμετωπίζω κάτι τέτοιο και η αλήθεια είναι ότι αν και φαινομενικά έιναι εύκολο, έχω κολλήσει..
ID Description
1032381 Το καινούριο μου αυτοκίνητο είναι ένα ηλεκτρικό αυτοκίνητο
Dionisis
|
|
-
13-12-2010, 14:32
|
-
cap
-
-
-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Απ: Boήθεια με Insert into
Μια πρόχειρη λύση περιλαμβάνει τη δημιουργία μιας UDF που "ενώνει" όλα τα strings από records με το ίδιο id σε ένα: (myTable είναι το όνομα του table, και id, description τα ονόματα των πεδίων). Υποθέτω οτι το id είναι int. CREATE FUNCTION fn_concatit (@id int) returns nvarchar(max)
as
BEGIN
declare @val nvarchar(max)
select @val = coalesce (@val,'') + description + ' '
from myTable
where id=@id
return left(@val, len(@val)-1)
END
Και μετά το τρέχεις κάπως έτσι:
select
id
, dbo.fn_concatit(id) as mydescription
from myTable
group by id Στη function προσθέτω και ένα space ανάμεσα στα strings και απλώς στην επιστροφή "τρώω" το τελευταίο space.
Αυτό θα σου δώσει ένα result set που μπορείς να το κάνεις insert σε ένα καινούριο πίνακα.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
13-12-2010, 14:32
|
-
spaceman
-
-
-
Μέλος από τις 06-06-2006
-
-
Δημοσιεύσεις 65
-
-
|
Απ: Boήθεια με Insert into
DECLARE @t TABLE (id SMALLINT, Descr_txt NVARCHAR(200) COLLATE database_default, order_fld TINYINT)
INSERT INTO @t(id, Descr_txt, order_fld)
VALUES (1, 'This is', 1), (1, 'a test for', 2), (1, 'id 1', 3),
(2, 'This is', 1), (2, 'for', 2), (2, 'id 2', 3),
(3, 'And', 1), (3, 'another for', 2), (3, 'id 3', 3)
SELECT distinct_ids.id, (SELECT t.Descr_txt AS 'data()' FROM @t AS t WHERE t.id = distinct_ids.id ORDER BY t.order_fld FOR XML PATH('')) AS concat_columns
FROM (SELECT DISTINCT id FROM @t) AS distinct_ids --HTH--
|
|
-
13-12-2010, 14:33
|
|
Απ: Boήθεια με Insert into
Μια πολύ γρήγορη λύση για το πρόβλημα σου όπως το λες είναι η παρακατώ μιας και θα το χρησιμοποιήσεις απαξ
create table Original ( ID int ,Description nvarchar(max) ) go create table NewOriginal ( ID int ,Description nvarchar(max) ) go
INSERT INTO Original values ( 1, 'Antonis' ) INSERT INTO Original values ( 1, 'Chatzipavlis' ) INSERT INTO Original values ( 2, 'dot' ) INSERT INTO Original values ( 2, 'Net' ) INSERT INTO Original values ( 2, 'Zone' ) INSERT INTO Original values ( 2, '.gr' ) go
select * from Original go
DECLARE tcursor CURSOR READ_ONLY FOR select id,description from original
DECLARE @lid int , @id int , @desc nvarchar(max), @newdesc nvarchar(max) OPEN tcursor
FETCH NEXT FROM tcursor INTO @id, @desc set @lid = @id set @newdesc='' WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN if @lid <> @id begin insert into NewOriginal values ( @lid , @newdesc) set @lid = @id set @newdesc=@desc end else begin set @newdesc = @newdesc + @desc end END FETCH NEXT FROM tcursor INTO @id, @desc END insert into NewOriginal values ( @lid , @newdesc)
CLOSE tcursor DEALLOCATE tcursor GO
select * from NewOriginal go
Antonios Chatzipavlis
|
|
-
13-12-2010, 14:39
|
-
13-12-2010, 14:43
|
-
neoklis
-
-
-
Μέλος από τις 18-06-2007
-
-
Δημοσιεύσεις 192
-
-
|
Απ: Boήθεια με Insert into
Δεν με πνίξατε..... με ξελιγώσατε...
Καλύτερα όμως έτσι, καθώς θα έχω την δυνατότητα να δω περισσότερες από μία λύσεις..
Ευχαριστώ
Dionisis
|
|
-
13-12-2010, 14:50
|
-
spaceman
-
-
-
Μέλος από τις 06-06-2006
-
-
Δημοσιεύσεις 65
-
-
|
Απ: Boήθεια με Insert into
cap: Στη function προσθέτω και ένα space ανάμεσα στα strings και απλώς στην επιστροφή "τρώω" το τελευταίο space.
SELECT LEN('test'), LEN('test '), LEFT('test ', LEN('test ')-1) --HTH--
|
|
-
13-12-2010, 15:04
|
-
13-12-2010, 15:07
|
-
cap
-
-
-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Απ: Boήθεια με Insert into
Η εναλλακτικά (πείτε μου όμως αν δεν είναι ενδεδειγμένη η χρήση της datalength εδώ): Ο λόγος που αβίαστα χρησιμοποίησα τη len είναι από κεκτημένη ταχύτητα, απλά χρησιμοποιούσα το ίδιο function για να φτιάχνω delimited strings οπου εκεί το len έδινε το σωστό μήκος. Τώρα με το space, την πατήσαμε :)
return left(@val, datalength(@val)-1)
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
13-12-2010, 15:11
|
-
spaceman
-
-
-
Μέλος από τις 06-06-2006
-
-
Δημοσιεύσεις 65
-
-
|
Απ: Boήθεια με Insert into
cap: return rtrim(@val)
VALUES(1032381, N'Το καινούριο μου αυτοκίνητο'), (1032381, N'είναι ένα ηλεκτρικό αυτοκίνητο ') select
id
, dbo.fn_concatit(id) as mydescription
from myTable
group by id 1032381, 'Το καινούριο μου αυτοκίνητο είναι ένα ηλεκτρικό αυτοκίνητο' --HTH--
|
|
-
13-12-2010, 15:17
|
-
cap
-
-
-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Απ: Boήθεια με Insert into
Spaceman, γι'αυτό έγραψα αμέσως από κάτω την datalength. Αν και θα έπρεπε να σε ευχαριστήσω που υποδεικνύεις αυτά τα flaws (και θα το κάνω - ευχαριστώ), αισθάνομαι λιγάκι σαν το παιδάκι που το διορθώνει ο δάσκαλος - χώρια που όσοι διαβάζουν ίσως δεν αντιλαμβάνονται αμέσως γιατί γράφεις αυτό που γράφεις. Θα ήταν ίσως λίγο πιό χρήσιμο για τους υπόλοιπους φίλους ένα σχόλιο του στυλ "ξέρεις, η rtrim θα σου σβήσει όλα τα trailing spaces οπότε αν έχεις πολλά και τα θέλεις θα έχεις πρόβλημα", ή "η len δεν λαμβάνει υπόψη της τα trailing spaces οπότε το value που θα πάρεις θα αποχωριστεί τον τελευταίο του πραγματικό χαρακτήρα".
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
13-12-2010, 15:23
|
-
spaceman
-
-
-
Μέλος από τις 06-06-2006
-
-
Δημοσιεύσεις 65
-
-
|
Απ: Boήθεια με Insert into
CREATE FUNCTION dbo.fn_concatit (@id int) returns nvarchar(max)
as
BEGIN
declare @val nvarchar(max)
select @val = ISNULL(@val, N'') + N' ' +description
from dbo.myTable
where id=@id
--there should be an order by here
return STUFF(@val, 1, 1, N'')
END
--HTH--
|
|
-
13-12-2010, 15:25
|
|
Απ: Boήθεια με Insert into
H λύση που προτείνει ο spaceman είναι νομίζω η αρτιότερη απλά πρέπει να ξέρεις άριστη t-sql για να την καταλάβεις η δικιά μου είναι η πεπατημενη λύση που παίζει παντού με το αντίστοιχο performance penalty. Θα σου πρότεινα να χρησιμοποιήσεις την λύση του spaceman ακόμα και αν δεν την πολυκαταλαβαίνεις στην περίπτωση που αυτό που θέλεις να κάνεις τώρα θα το επαναλαμβάνεις συχνά. Αν πάλι όχι τότε έχεις 3 τρόπους για να κάνεις το ίδιο πράγμα τονίζοντας πάλι ότι του spaceman είναι η βέλτιστη.
Antonios Chatzipavlis
|
|
-
13-12-2010, 15:42
|
-
cap
-
-
-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Απ: Boήθεια με Insert into
Για εκπαιδευτικούς λόγους, ας δούμε τι είχα κάνει λάθος εγώ και τι διορθώθηκε από την έκδοση του spaceman:
Δική μου udf: CREATE FUNCTION fn_concatit (@id int) returns nvarchar(max)
as
BEGIN
declare @val nvarchar(max)
select @val = coalesce (@val,'') + description + ' '
from myTable
where id=@id
return left(@val, len(@val)-1)
END Διορθωμένη από spaceman: CREATE FUNCTION dbo.fn_concatit (@id int) returns nvarchar(max)
as
BEGIN
declare @val nvarchar(max)
select @val = ISNULL(@val, N'') + N' ' +description
from dbo.myTable
where id=@id
--there should be an order by here
return STUFF(@val, 1, 1, N'')
END
Το πρώτο λάθος στη δική μου έκδοση ήταν οτι δεν είχε γίνει create στο dbo schema, κάτι το οποίο μπορεί μεν να είναι implied σε ορισμένες περιπτώσεις, αλλά το σωστότερο είναι να δηλώνεται. Το δεύτερο λάθος ήταν ότι δεν χρησιμοποίησα unicode strings στο concatenation (Ν), ενώ στην ουσία επιστρέφω nvarchar. Η χρήση της isnull έναντι της coalesce στο συγκεκριμένο σενάριο δεν ξέρω πού υπερτερεί, ας βοηθήσουν οι υπόλοιποι. Το order by φαντάζομαι οτι είναι για performance reasons; Αν οχι, θα ήθελα να γνωρίζω και εγώ γιατί πρέπει να έχουμε order by. Τελος, το return value από εμένα δεν ήταν σωστό ούτε με τη χρήση της rtrim (μπορεί να έχουμε trailing spaces που να τα χρειαζόμαστε) ούτε με τη χρήση της len (δεν μετράει spaces). Οπότε, αυτό που έκανε ο spaceman είναι να προσθέτει το κάθε space ΠΡΙΝ και όχι μετά, έτσι ωστε το τελικό του string να έχει ένα leading space, το οποίο κόβει με τη βοήθεια της stuff. Αυτό ήταν και το πιό σημαντικό σφάλμα.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
13-12-2010, 15:52
|
-
neoklis
-
-
-
Μέλος από τις 18-06-2007
-
-
Δημοσιεύσεις 192
-
-
|
Απ: Boήθεια με Insert into
Επειδή έιναι κάτι που θα επαναλαμβάνετε θα χρησιμοποίησω function. Μέχρι να δω τα νέα ποστ είχα ήδη παίξει με την λύση που μου πρότεινε ο cap. Σε κάποιες περιπτώσεις το description ήταν null και χτύπαγε error στο return. Και ενώ πειραματιζόμουν για να το διορθώσω, είδα τα νεότερα post. Δοκίμασα α)return rtrim(@val) β)return left(@val, datalength(@val)-1) και στις 2 περιπτώσεις παίζει μια χαρά.
Θα δοκιμάσω και του spaceman...
Dionisis
|
|
Σελίδα 1 από 2 (28 εγγραφές)
1
|
|
|