Просмотр нескольких таблиц.Нужно убрать "двойники", определенные 1 таблицей - PullRequest
2 голосов
/ 06 апреля 2011

Хорошо, вот с чем я застрял.

View schema Полный размер

SELECT     dbo.InstellingGegevens.INST_SUBTYPE, dbo.InstellingGegevens.INST_BRON, dbo.InstellingGegevens.INST_INSTELLINGSNUMMER, 
                      dbo.InstellingGegevens.INST_NAAM, dbo.InstellingGegevens.INST_KORTENAAM, dbo.InstellingGegevens.INST_VESTIGINGSNAAM, 
                      dbo.InstellingGegevens.INST_ROEPNAAM, dbo.InstellingGegevens.INST_STATUUT, dbo.InstellingGegevens.ONDERWIJSNIVEAU_REF, 
                      dbo.InstellingGegevens.ONDERWIJSSOORT_REF, dbo.InstellingGegevens.DATUM_TOT, dbo.InstellingGegevens.DATUM_VAN, 
                      dbo.InstellingGegevens.VERBOND_REF, dbo.InstellingGegevens.VSKO_LID, dbo.InstellingGegevens.NET_REF, dbo.Instellingen.Inst_ID, dbo.Instellingen.INST_TYPE, 
                      dbo.Instellingen.INST_REF, dbo.Instellingen.INST_LOC_REF, dbo.Instellingen.INST_LOCNR, dbo.Instellingen.Opt_KalStandaard, dbo.InstellingTelecom.INST_TEL, 
                      dbo.InstellingTelecom.INST_FAX, dbo.InstellingTelecom.INST_EMAIL, dbo.InstellingTelecom.INST_WEB, dbo.InstellingAdressen.SOORT, 
                      dbo.InstellingAdressen.STRAAT, dbo.InstellingAdressen.POSTCODE, dbo.InstellingAdressen.GEMEENTE, dbo.InstellingAdressen.GEM_REF, 
                      dbo.InstellingAdressen.FUSIEGEM_REF, dbo.InstellingAdressen.FUSIEGEM, dbo.InstellingAdressen.ALFA_G, dbo.InstellingAdressen.PROVINCIE, 
                      dbo.InstellingAdressen.BISDOM, dbo.InstellingAdressen.ARRONDISSEMENT, dbo.InstellingAdressen.GEWEST, dbo.InstellingLogin.Inst_Gebruikersnaam, 
                      dbo.InstellingLogin.Inst_Concode, dbo.InstellingLogin.Inst_DirCode, dbo.InstellingLogin.DOSSNR, dbo.InstellingLogin.Instelling_ID, 
                      dbo.InstellingContPersDirecteurs.AANSPREKING, dbo.InstellingContPersDirecteurs.CONTACTPERSOON, dbo.InstellingContPersDirecteurs.FUNCTIE
FROM         dbo.InstellingGegevens RIGHT OUTER JOIN
                      dbo.Instellingen ON dbo.InstellingGegevens.INST_TYPE = dbo.Instellingen.INST_TYPE AND dbo.InstellingGegevens.INST_REF = dbo.Instellingen.INST_REF AND 
                      dbo.InstellingGegevens.INST_LOC_REF = dbo.Instellingen.INST_LOC_REF AND 
                      dbo.InstellingGegevens.INST_LOCNR = dbo.Instellingen.INST_LOCNR LEFT OUTER JOIN
                      dbo.InstellingTelecom ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingTelecom.INST_TYPE AND 
                      dbo.InstellingGegevens.INST_REF = dbo.InstellingTelecom.INST_REF AND 
                      dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingTelecom.INST_LOC_REF LEFT OUTER JOIN
                      dbo.InstellingAdressen ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingAdressen.INST_TYPE AND 
                      dbo.InstellingGegevens.INST_REF = dbo.InstellingAdressen.INST_REF AND 
                      dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingAdressen.INST_LOC_REF LEFT OUTER JOIN
                      dbo.InstellingLogin ON dbo.InstellingLogin.Inst_InstellingIKONType = dbo.Instellingen.INST_TYPE AND 
                      dbo.InstellingLogin.Inst_InstellingIKON_REF = dbo.Instellingen.INST_REF AND dbo.InstellingLogin.Inst_Loc_REF = dbo.Instellingen.INST_LOC_REF AND 
                      dbo.InstellingLogin.Inst_Loc_Nr = dbo.Instellingen.INST_LOCNR LEFT OUTER JOIN
                      dbo.InstellingContPersDirecteurs ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingContPersDirecteurs.INST_TYPE AND 
                      dbo.InstellingGegevens.INST_REF = dbo.InstellingContPersDirecteurs.INST_REF AND 
                      dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingContPersDirecteurs.INST_LOC_REF
WHERE     (NOT (dbo.InstellingLogin.Inst_InstellingIKON_REF IS NULL))

Так вот в чем проблема:

PK должен быть ключом 1 varchar 3 int. для каждой клавиши должна быть по 1 строке в каждой из таблиц, которые вы видите на рисунке. «родителем» этих ключей является таблица Instellingen. Эта таблица генерируется с distinct select из InstellingenLogin

реальная проблема заключается в том, что в InstellingenLogin имеется около 10 двойных чисел (около 5 тыс. Записей), и из-за этого некоторые строки возвращают двойное представление, только разные столбцы InstellingLogin.

я хочу, чтобы в InstellingLogin было 2 или более строк с одним и тем же ключом, будет отображаться только 1 (первый, ... не имеет значения, какой из них будет делать только 1).

Короче

это означает, что для каждой записи в Instellingen я хочу 1 запись в этом представлении.

есть ли способ сделать это?

Ответы [ 4 ]

1 голос
/ 06 апреля 2011

Или вы можете заменить таблицу IntellingLogin в запросе производной таблицей, такой как:

(SELECT RN = row_number() over
(partition by INST_LOC_REF,
INST_LOCNR, INST_REF, INST_TYPE order
by Datum_tot) , *  From
InstellingLogin) A

и добавить в условие соединения: A.RN = 1

1 голос
/ 06 апреля 2011

Я немного запутался, но я думаю, что ответ ниже должен проиллюстрировать, как добиться того, что вам нужно:

SELECT * FROM Instellingen as i
CROSS APPLY
(   
    SELECT TOP (1) * FROM InstellingLogin as il
    WHERE i.INST_LOC_REF = il.Inst_Loc_REF 
    and i.INST_LOCNR=il.Inst_Loc_Nr 
    and i.INST_REF=il.Inst_InstellingIKON_REF 
    and i.INST_TYPE=il.Inst_InstellingIKONType
    order by il.Datum_tot
) la

Это в основном объединит Instellingen и InstellingenLogin, но только на первой найденной записи

1 голос
/ 06 апреля 2011

Вы можете использовать DENSE_RANK для произвольного выбора строки.В основном создайте CTE, который ранжирует instellinglogin, а затем выберите только тот, который имеет ранг 1. Хитрость заключается в том, что у вас есть левое соединение с instellinglogin, поэтому вам нужно выполнить внутреннее соединение внутри левого соединения, как показано ниже.Также я сохранил условие Join как столбцы для раздела.Это может быть неправильно.

LEFT OUTER JOIN (dbo.instellinglogin 
                            INNER JOIN unique_login 
                              ON dbo.instellinglogin.inst_instellingikontype = 
                                      unique_login .inst_instellingikontype 
                                 AND dbo.instellinglogin.inst_instellingikon_ref = 
                                     unique_login.inst_instellingikon_ref 
                                 AND dbo.instellinglogin.inst_loc_ref = 
                                     unique_login.inst_loc_ref 
                                 AND dbo.instellinglogin.inst_loc_nr = 
                                     unique_login.inst_loc_nr 
                                 AND unique_login.therank = 1 ) 
             ON dbo.instellinglogin.inst_instellingikontype = 
                dbo.instellingen.inst_type 
                AND dbo.instellinglogin.inst_instellingikon_ref = 
                    dbo.instellingen.inst_ref 
                AND dbo.instellinglogin.inst_loc_ref = dbo.instellingen.inst_loc_ref 
                AND dbo.instellinglogin.inst_loc_nr = dbo.instellingen.inst_locnr 

Вот полный SQL ниже

WITH unique_login 
     AS (SELECT instellinglogin.inst_instellingikontype, 
                instellinglogin.inst_instellingikon_ref, 
                instellinglogin.inst_loc_ref, 
                instellinglogin.inst_loc_nr, 
                Dense_rank() OVER (ORDER BY 
                instellinglogin.inst_instellingikontype, 
                instellinglogin.inst_instellingikon_ref, 
                instellinglogin.inst_loc_ref, 
                instellinglogin.inst_loc_nr) AS therank) 
SELECT dbo.instellinggegevens.inst_subtype, 
       dbo.instellinggegevens.inst_bron, 
       dbo.instellinggegevens.inst_instellingsnummer, 
       dbo.instellinggegevens.inst_naam, 
       dbo.instellinggegevens.inst_kortenaam, 
       dbo.instellinggegevens.inst_vestigingsnaam, 
       dbo.instellinggegevens.inst_roepnaam, 
       dbo.instellinggegevens.inst_statuut, 
       dbo.instellinggegevens.onderwijsniveau_ref, 
       dbo.instellinggegevens.onderwijssoort_ref, 
       dbo.instellinggegevens.datum_tot, 
       dbo.instellinggegevens.datum_van, 
       dbo.instellinggegevens.verbond_ref, 
       dbo.instellinggegevens.vsko_lid, 
       dbo.instellinggegevens.net_ref, 
       dbo.instellingen.inst_id, 
       dbo.instellingen.inst_type, 
       dbo.instellingen.inst_ref, 
       dbo.instellingen.inst_loc_ref, 
       dbo.instellingen.inst_locnr, 
       dbo.instellingen.opt_kalstandaard, 
       dbo.instellingtelecom.inst_tel, 
       dbo.instellingtelecom.inst_fax, 
       dbo.instellingtelecom.inst_email, 
       dbo.instellingtelecom.inst_web, 
       dbo.instellingadressen.soort, 
       dbo.instellingadressen.straat, 
       dbo.instellingadressen.postcode, 
       dbo.instellingadressen.gemeente, 
       dbo.instellingadressen.gem_ref, 
       dbo.instellingadressen.fusiegem_ref, 
       dbo.instellingadressen.fusiegem, 
       dbo.instellingadressen.alfa_g, 
       dbo.instellingadressen.provincie, 
       dbo.instellingadressen.bisdom, 
       dbo.instellingadressen.arrondissement, 
       dbo.instellingadressen.gewest, 
       dbo.instellinglogin.inst_gebruikersnaam, 
       dbo.instellinglogin.inst_concode, 
       dbo.instellinglogin.inst_dircode, 
       dbo.instellinglogin.dossnr, 
       dbo.instellinglogin.instelling_id, 
       dbo.instellingcontpersdirecteurs.aanspreking, 
       dbo.instellingcontpersdirecteurs.contactpersoon, 
       dbo.instellingcontpersdirecteurs.functie 
FROM   dbo.instellinggegevens 
       RIGHT OUTER JOIN dbo.instellingen 
         ON dbo.instellinggegevens.inst_type = dbo.instellingen.inst_type 
            AND dbo.instellinggegevens.inst_ref = dbo.instellingen.inst_ref 
            AND dbo.instellinggegevens.inst_loc_ref = 
                dbo.instellingen.inst_loc_ref 
            AND dbo.instellinggegevens.inst_locnr = dbo.instellingen.inst_locnr 
       LEFT OUTER JOIN dbo.instellingtelecom 
         ON dbo.instellinggegevens.inst_type = dbo.instellingtelecom.inst_type 
            AND dbo.instellinggegevens.inst_ref = dbo.instellingtelecom.inst_ref 
            AND dbo.instellinggegevens.inst_loc_ref = 
                dbo.instellingtelecom.inst_loc_ref 
       LEFT OUTER JOIN dbo.instellingadressen 
         ON dbo.instellinggegevens.inst_type = dbo.instellingadressen.inst_type 
            AND dbo.instellinggegevens.inst_ref = 
                dbo.instellingadressen.inst_ref 
            AND dbo.instellinggegevens.inst_loc_ref = 
                dbo.instellingadressen.inst_loc_ref 
       LEFT OUTER JOIN (dbo.instellinglogin 
                        INNER JOIN unique_login 
                          ON dbo.instellinglogin.inst_instellingikontype = 
                                  unique_login .inst_instellingikontype 
                             AND dbo.instellinglogin.inst_instellingikon_ref = 
                                 unique_login.inst_instellingikon_ref 
                             AND dbo.instellinglogin.inst_loc_ref = 
                                 unique_login.inst_loc_ref 
                             AND dbo.instellinglogin.inst_loc_nr = 
                                 unique_login.inst_loc_nr 
                             AND unique_login.therank = 1 ) 
         ON dbo.instellinglogin.inst_instellingikontype = 
            dbo.instellingen.inst_type 
            AND dbo.instellinglogin.inst_instellingikon_ref = 
                dbo.instellingen.inst_ref 
            AND dbo.instellinglogin.inst_loc_ref = dbo.instellingen.inst_loc_ref 
            AND dbo.instellinglogin.inst_loc_nr = dbo.instellingen.inst_locnr 
       LEFT OUTER JOIN dbo.instellingcontpersdirecteurs 
         ON dbo.instellinggegevens.inst_type = 
            dbo.instellingcontpersdirecteurs.inst_type 
            AND dbo.instellinggegevens.inst_ref = 
                dbo.instellingcontpersdirecteurs.inst_ref 
            AND dbo.instellinggegevens.inst_loc_ref = 
                dbo.instellingcontpersdirecteurs.inst_loc_ref 
WHERE  ( NOT ( dbo.instellinglogin.inst_instellingikon_ref IS NULL ) ) 
1 голос
/ 06 апреля 2011

Вам нужно обернуть InstellingenLogin в какой-то агрегат, чтобы удалить дубликаты, а затем присоединиться к результату - вы можете сделать это с помощью подзапроса. Вы можете сделать GROUP BY с MIN() или MAX(), чтобы выбрать значение, или вы можете сделать ROW_NUMBER() OVER (ORDER BY some_criteria PARTIION BY your_key) и выбрать первый ряд.

Кроме того, я рекомендую использовать псевдонимы на ваших таблицах - это делает их более читабельными

WITH UniqueLogins AS (
    -- How to pick Inst_Gebruikersnaam, Inst_Concode, Inst_DirCode, DOSSNR, Instelling_ID, InstellingIKONType, Inst_Loc_REF, Inst_Loc_Nr, Inst_InstellingIKON_REF
    SELECT key columns, MIN(non key column), MIN(non key column), MIN(non key column)
    FROM dbo.InstellingLogin
    GROUP BY key columns
)
SELECT     G.INST_SUBTYPE, G.INST_BRON, G.INST_INSTELLINGSNUMMER, 
                  G.INST_NAAM, G.INST_KORTENAAM, G.INST_VESTIGINGSNAAM, 
                  G.INST_ROEPNAAM, G.INST_STATUUT, G.ONDERWIJSNIVEAU_REF, 
                  G.ONDERWIJSSOORT_REF, G.DATUM_TOT, G.DATUM_VAN, 
                  G.VERBOND_REF, G.VSKO_LID, G.NET_REF, I.Inst_ID, I.INST_TYPE, 
                  I.INST_REF, I.INST_LOC_REF, I.INST_LOCNR, I.Opt_KalStandaard, T.INST_TEL, 
                  T.INST_FAX, T.INST_EMAIL, T.INST_WEB, A.SOORT, 
                  A.STRAAT, A.POSTCODE, A.GEMEENTE, A.GEM_REF, 
                  A.FUSIEGEM_REF, A.FUSIEGEM, A.ALFA_G, A.PROVINCIE, 
                  A.BISDOM, A.ARRONDISSEMENT, A.GEWEST, UniqueLogins.Inst_Gebruikersnaam, 
                  UniqueLogins.Inst_Concode, UniqueLogins.Inst_DirCode, UniqueLogins.DOSSNR, UniqueLogins.Instelling_ID, 
                  CPD.AANSPREKING, CPD.CONTACTPERSOON, CPD.FUNCTIE
FROM         dbo.InstellingGegevens AS G RIGHT OUTER JOIN
                  dbo.Instellingen AS I ON G.INST_TYPE = I.INST_TYPE AND G.INST_REF = I.INST_REF AND 
                  G.INST_LOC_REF = I.INST_LOC_REF AND 
                  G.INST_LOCNR = I.INST_LOCNR LEFT OUTER JOIN
                  dbo.InstellingTelecom AS T ON G.INST_TYPE = T.INST_TYPE AND 
                  G.INST_REF = T.INST_REF AND 
                  G.INST_LOC_REF = T.INST_LOC_REF LEFT OUTER JOIN
                  dbo.InstellingAdressen AS A ON G.INST_TYPE = A.INST_TYPE AND 
                  G.INST_REF = A.INST_REF AND 
                  G.INST_LOC_REF = A.INST_LOC_REF LEFT OUTER JOIN
                  UniqueLogins ON UniqueLogins.Inst_InstellingIKONType = I.INST_TYPE AND 
                  UniqueLogins.Inst_InstellingIKON_REF = I.INST_REF AND UniqueLogins.Inst_Loc_REF = I.INST_LOC_REF AND 
                  UniqueLogins.Inst_Loc_Nr = I.INST_LOCNR LEFT OUTER JOIN
                  dbo.InstellingContPersDirecteurs AS CPD ON G.INST_TYPE = CPD.INST_TYPE AND 
                  G.INST_REF = CPD.INST_REF AND 
                  G.INST_LOC_REF = CPD.INST_LOC_REF
WHERE     (NOT (UniqueLogins.Inst_InstellingIKON_REF IS NULL))
...