2009-12-03 14 views
6

Mam 10 tabel, które łączę, aby utworzyć widok. Wybieram tylko identyfikator z każdej tabeli, ale w widoku każdy identyfikator może być wyświetlany więcej niż raz, jednak kombinacja wszystkich identyfikatorów będzie zawsze unikalna. Czy istnieje sposób na utworzenie w tym widoku innej kolumny, która będzie unikalnym identyfikatorem?Czy można utworzyć unikatowy identyfikator w widoku serwera SQL, który pozostanie taki sam za każdym razem, gdy zostanie wywołany widok?

Chciałbym móc przechowywać unikatowy identyfikator i używać go do odpytywania w widoku, aby uzyskać wszystkie inne identyfikatory.

Odpowiedz

1

Nie można tego zrobić w widoku. Można utworzyć tabelę tymczasową, w której przechowywane są wszystkie te informacje i utworzyć klucz lub unikalny identyfikator dla każdego wiersza.

+1

+ 1'ed. Ale jeśli chce, aby ta informacja się utrzymywała, nie byłaby to tymczasowa tabela, to byłby prawdziwy stół. –

+0

@ Mark ty masz rację :). – JonH

1

Myślę, że możesz to zrobić, używając ROW_NUMBER(), przynajmniej jeśli możesz zagwarantować zamówienie widoku. Na przykład:

SELECT 
    ROW_NUMBER() OVER (ORDER BY col1, col2, col3) as UniqueId 
FROM <lotsa joins> 

Dopóki kolejność pozostaje taka sama, a tylko pola są dodawane na końcu, id będzie wyjątkowy.

+0

Nie gwarantuje to, że numery są takie same za każdym razem. Jeśli mam (1, 1, 1) i (3, 3, 3), będą odpowiednio 1 i 2. Jeśli następnie dodaję (2, 2, 2), wówczas wiersz (3, 3, 3) stanie się teraz 3, a nie 2. –

+0

@ TOM H: Właśnie dlatego wstawiam "jeśli możesz zagwarantować zamówienie" na początku moja odpowiedź :) – Andomar

+0

Zagwarantowanie zamówienia nie jest jednak możliwe. Nie tylko kolejność wierszy powoduje, że nie można dodawać nowych wierszy, a wierszy nie można zmienić. Innymi słowy, dane musiałyby być całkowicie statyczne, z wyjątkiem dodawania wierszy do samego końca w kolejności. –

0

Fakt, że próbujesz to zrobić, wskazuje na znacznie większe problemy w projektowaniu bazy danych i/lub architekturze aplikacji.

Ponieważ masz 10 tabel i mam zamiar zgadnąć, że projektanci DB po prostu spłatali ID ID INTELIGENTNOŚĆ wszystkim tabelom, które skończysz mając około (2^31)^10 możliwych wierszy w stół.

Jedynym typem danych, jaki mogę sobie wyobrazić, który mógłby pokryć tę liczbę, byłoby przetłumaczenie wszystkich liczb całkowitych na łańcuchy z dopełnieniem zerowym i umieszczenie ich razem jako dużego CHARa.

Domyślam się, że twoim prawdziwym problemem nie jest otrzymanie tego identyfikatora dla widoku, ale inne rzeczy, które próbujesz zrobić, o co należy zadać. Tylko przeczucie.

+0

Tak, całkowicie się z tym zgadzam, niestety jest to coś, z czym utknąłem, szukając najlepszego sposobu, aby to osiągnąć. Jest to baza danych pojazdów, więc istnieje ponad 50 stołów, z których każdy zawiera własne identyfikatory, które można połączyć z kolejnymi. Po prostu próbuję zebrać podstawowe informacje/identyfikatory w celu uruchomienia innych zapytań z: VehicleID, BedID, BodyStyleID, BrakeID, DriveTypeID, EngineConfigID, etc ... naprawdę niezbyt ładnych. – Brendo

0

Jedną z możliwości byłoby wywołanie funkcji z widoku, która oblicza kod skrótu dla wszystkich kolumn ID. Jeśli użyjesz przyzwoitego algorytmu mieszania kryptograficznego, szanse na zderzenie są niewielkie (prawdopodobnie bardziej prawdopodobne, że dysk dostarczy złe dane). Nawet łatwiej, można oczywiście po prostu połączyć różne identyfikatory w jeden, o wiele większy identyfikator, być może jako kolumnę binarną lub varbinary.

Przechowywanie tego identyfikatora i możliwość odpytywania na jego temat będzie nieco więcej pracy. Nie mogę wymyślić sposobu, aby obliczyć i zapisać go z widoku. Prawdopodobnie będziesz potrzebował procedury składowanej, aby ją najpierw utworzyć; szczegóły zależą w dużym stopniu od specyfiki Twojej aplikacji.

4

Miałem podobny problem, gdy potrzebowałem ustalić hierarchię dla wielu tabel. Jeśli używasz liczby całkowitej jako id w każdej z tabel, możesz po prostu przekonwertować identyfikatory każdej tabeli na varchar i poprzedzić je inną literą dla każdej tabeli. Na przykład

CREATE VIEW LocationHierarchy as

SELECT 'C' + CONVERT(VARCHAR,[Id]) as Id 
     ,[Name] 
     ,'S' + CONVERT(VARCHAR,[State]) as parent 
    FROM [City] 
    UNION 
    SELECT 'S' + CONVERT(VARCHAR,[Id]) as Id 
     ,[Name] 
     ,'C' + CONVERT(VARCHAR,[Suburb]) as parent 
    FROM [Suburb] 

etc

Skuteczność tego rozwiązania będzie zależał od tego, jak duży jest Twój zbiór danych.

+6

@tamago Jest nadal przydatny dla użytkowników takich jak ja, którzy badają podobny temat i szukają odpowiedzi. –

1

Tak, ostatnio miałem ten sam wymóg.

Podczas tworzenia widoku zachowaj instrukcję select jako TEMP_TABLE, a następnie użyj funkcji Row_number() na tej TEMP_TABLE.

Oto przykład:

CREATE VIEW VIEW_NM 
AS 
SELECT Row_number() OVER(ORDER BY column_nm DESC) AS 'RowNumber' FROM 
(SELECT COL1,COL2 FROM TABLE1 
UNION 
SELECT COL1,COL2 FROM TABLE2 
) AS TEMP_TABLE;