2016-10-20 3 views
1

ich SQL-Server 2014. Ich habe eine Tabelle wie folgt aus:Wie finde ich alle Unternehmen, die Niederlassung in allen Städten eines anderen Unternehmens haben

CREATE Table Comp 
(
    ID int identity(1,1), 
    City varchar(50), 
    Name varchar(50) 
) 

Ich habe diese Aufzeichnung in meinem Tisch

INSERT INTO Comp 
values 
    ('Montreal','ABC'), 
    ('QuebecCity','ABC'), 
    ('Mont-tremblant','ABC'), 
    ('Saint-donant','ABC'), 
    ('Saint-savaure','ABC'), 

    ('Montreal','QQQ'), 
    ('QuebecCity','QQQ'), 
    ('Mont-tremblant','QQQ'), 
    ('Saint-donant','QQQ'), 
    ('Saint-savaure','QQQ'), 

    ('Montreal','www'), 
    ('QuebecCity','www'), 
    ('Mont-tremblant','www'), 

    ('Montreal','dd'), 
    ('QuebecCity','dd'), 
    ('Mont-tremblant','dd'), 
    ('Saint-donant','dd'), 
    ('Saint-savaure','dd'), 
    ('trois rivieres','dd'), 
    ('perce','dd'), 

    ('City1','SSS'), 
    ('City2','SSS'), 
    ('City3','SSS'), 
    ('City4','SSS'), 
    ('Saint-savaure','SSS'), 
    ('City6','SSS'), 
    ('City7','dd') 

Wie kann ich nur den Namen des Unternehmens abfragen, die die in allen der hat zitiert zitiert in anderen Unternehmen

Zum Beispiel, wenn mein Master-Gesellschaft ist ‚ABC‘, sollte es ‚QQQ‘ abfragen und ‚dd‘

+0

Sollten nicht die Master-Unternehmen auch abfragen 'www'? – Rodolfo

+0

Ja, in unserer Anfrage können wir jede Firma als Master-Firma haben. Es wird als Bedingung an unsere Abfrage gesendet –

+0

Ich meine in Ihrem Beispiel, wo Master-Firma ist "ABC", und Ihre Datensätze sind wie Sie angegeben, sollte es nicht zurückgeben "QQQ", "dd". UND ** 'www' **? – Rodolfo

Antwort

2

ist hier ein Weg

SELECT NAME 
FROM comp c1 
WHERE City IN (SELECT city 
       FROM comp 
       WHERE NAME = 'ABC') 
     AND NAME <> 'ABC' 
GROUP BY NAME 
HAVING Count(DISTINCT City) = (SELECT Count(DISTINCT city) 
           FROM comp 
           WHERE NAME = 'ABC') 

Wenn Sie nicht city für jede name duplizieren haben dann einen besseren Ansatz

SELECT c1.NAME 
FROM comp c1 
     JOIN (SELECT city, 
        Count(1)OVER() AS cnt 
      FROM comp 
      WHERE NAME = 'ABC') c2 
     ON c1.City = c2.City 
WHERE c1.NAME <> 'ABC' 
GROUP BY c1.NAME 
HAVING Count(c1.city) = Max(cnt) 
+0

Ich habe Ihre erste Abfrage mit meiner Abfrage in meiner Antwort bestätigt, und ich habe festgestellt, dass Ihre Abfrage 100 mal schneller als meine ist. Vielen Dank –

1

Alternativ

declare @selectedcompany nvarchar(10) = 'abc' 

select distinct name 
from comp rsDistinct 
where not exists 
(
    select city from comp where name = @selectedcompany 
    except 
    select city from comp where name = rsDistinct.name 
) 
and name != 'ABC' 
+0

Sie müssen den Ort Ihrer Auswahl innerhalb Ihrer Where-Klausel ändern und diesen Teil auch hinzufügen: Und rsDistinct.name <> 'ABC' –

+0

Sie haben Recht! Fest. – Bert

0

Während dieser Zeit Ich habe diese Abfrage auch geschrieben:

SELECT 
    DISTINCT 
    S.name 
FROM Comp AS S 
WHERE NOT EXISTS 
    ( 
     (
      SELECT 
       city 
      FROM Comp 
      WHERE name = 'ABC' 
     ) 
     EXCEPT 
     ( SELECT 
      T.city 
      FROM Comp AS T 
      WHERE T.name = S.Name 
     ) 
    ) 
    AND S.name <> 'ABC' 
0

Meine Lösung ist Abfrage 1 unten.

Ich habe auch Ihre Abfrage (Query 2) getestet und versucht, wer von beiden, um herauszufinden, effizienter ist, basierend auf ‚Actual Execution Plan‘ und das Ergebnis ist, wie unter:

Abfrage 1: Abfragekosten (relativ zu Charge): 25%

select Name, COUNT(*) as cities 
from (select city from Comp where name = 'ABC') m 
join (select name, city from Comp where Name <> 'ABC') c on m.city = c.city 
group by Name 
having COUNT(*) = (select COUNT(*) from Comp where Name = 'ABC') 

Abfrage 2: Abfragekosten (im Vergleich zu Charge): 75%

SELECT DISTINCT S.name 
FROM Comp AS S 
WHERE NOT EXISTS 
( 
    (SELECT city FROM Comp WHERE name = 'ABC') 
    EXCEPT 
    (SELECT T.city FROM Comp AS T WHERE T.name = S.Name 
    ) 
) 
AND S.name <> 'ABC' 

HINWEIS: auf späteren AUSWERT Ich fand die Lösung von @Prdp effizienter.

Für doppelte Stadt Szenario

select Name 
from (select city from Comp where name = 'ABC') m 
join (select name, city from Comp where Name <> 'ABC') c on m.city = c.city 
group by Name 
having COUNT_BIG(DISTINCT c.City) = (select COUNT_BIG(DISTINCT City) from Comp where Name = 'ABC') 
+0

Ich habe diesen Befehl etwa 14 Mal für mehr als 3.000.000 in Comp-Tabelle: INSERT INTO Comp (Stadt, Name) Ort wählen, Name Von Comp \t; danach hat Ihre Abfrage diesen Fehler: Msg 8115, Ebene 16, Status 2, Zeile 1 Arithmetischer Überlauffehler beim Konvertieren des Ausdrucks in den Datentyp int. –

+0

Wenn Sie Count durch count_big ersetzen, wird das Problem behoben, aber das Ergebnis wird null sein. –

+0

Wenn wir City für eine Stadt duplizieren, funktioniert es nicht. –

Verwandte Themen