"select" jak zbiór wartości dla "where in"

0

Witam,

chciałbym prosić o pomoc w przygotowaniu pewnego zapytania.

Mam tabele towarów. Każdy towar ma swoje *id *oraz pole towary_powiazane, w któym po przecinku wymienione są *id *innych towarów lub nic (pole typu varchar). Chciałbym uzyskać listę towarów powiązanych z towarem o *id *równym np 50. Napisałem następujące zapytanie:

select id, nazwa from towary where id in (select powiazane from towary where id = 50)

niestety próba wykonania kończy się błędem:
Conversion failed when converting the varchar value '1, 2, 3, 4, 5' to data type int.
gdy pole zawiera jakąś wartość, lub:
DataSet: Field 'powiazane' not found.
gdy jest puste.

Jeśli chodzi o pierwszy przypadek to kombinowałem z CAST i CONVERT ale ciągle miałem błąd składni.

Nie proszę o napisanie zapytania za mnie, ale o informację jak ten temat ugryźć.
Proszę o wyrozumiałość dopiero poznaje SQL'a.

pozdrawiam

1

Należy wywalic tą tabelę w kosmos i zrobić od nowa, tym razem z głową i z normalnym powiązaniem n:m.

0

No dobra rozumiem, ale tak czysto akademicko dało by się to rozwiązać bez zmian w bazie?

0

Musiałbyś napisać funkcję tabelaryczną, np. dla MSSQL:

CREATE FUNCTION dbo.funkcja_powiazane (@id_nadrzednego int)
RETURNS @powiazane_tab TABLE (id int)
AS
BEGIN
    DECLARE @powiazane varchar(100), 
    SELECT @powiazane=REPLACE(ISNULL(powiazane, ''), ' ', '') FROM towary WHERE id=@id_nadrzednego
    IF @powiazane=''
    RETURN
    
    WHILE LEN(@powiazane)>0 
    BEGIN
        IF CHARINDEX(',', @powiazane)=0 
        BEGIN
            INSERT INTO @powiazane_tab(id) SELECT CONVERT(INT, @powiazane)
            SELECT @powiazane=''
        END
        ELSE
        BEGIN
            INSERT INTO @powiazane_tab(id) SELECT CONVERT(INT, SUBSTRING(@powiazane, 1, CHARINDEX(',', @powiazane)-1))
            SELECT @powiazane=SUBSTRING(@powiazane, CHARINDEX(',', @powiazane)+1, LEN(@powiazane)-CHARINDEX(',', @powiazane))
        END
    END
    RETURN
END
GO

a później wykorzystać to w zapytaniu:

SELECT id, nazwa FROM towary WHERE id IN (SELECT id FROM dbo.funkcja_powiazane(50))

Oczywiście w funkcji musiałbyś dodatkowo sprawdzać przed konwersją czy wartość jest liczbą.

0

Dało by się. Najpierw należało by napisać funkcję split, która skonwertuje przy okazji otrzymaną tablicę na rekordy > http://www.techrepublic.com/article/oracle-tip-create-functions-to-join-and-split-strings-in-sql/ oczywiście intow.

1 użytkowników online, w tym zalogowanych: 0, gości: 1