2008-10-22 13 views
15

Dziękuję milionom za odpowiedź wszystkich. Niestety, żadne z rozwiązań nie działa na moim końcu i domyślam się, że podany przeze mnie przykład jest pomieszany.SQL: W jaki sposób WYBRAĆ tylko wiersze o unikalnej wartości w niektórych kolumnach?

Pozwól mi spróbować ponownie.

Moja tabela wygląda następująco:

contract project activity 
row1 1000 8000 10 
row2 1000 8000 20 
row3 1000 8001 10 
row4 2000 9000 49 
row5 2000 9001 49 
row6 3000 9000 79 
row7 3000 9000 78 

Zasadniczo, zapytanie szukam wróci „2000,49” za „zamówienia, aktywność”, ponieważ umowa tylko # 2000 ma jeden i tylko jeden , unikalna wartość aktywności.

Ponownie, dzięki milion z góry, boroatel

+0

Co to jest PK dla tego stołu? –

Odpowiedz

13

Aktualizacja do korzystania z nowo dostarczone dane:

Rozwiązania wykorzystujące oryginalne dane można znaleźć na końcu tej odpowiedzi.

Korzystanie z nowych danych:

DECLARE @T TABLE([contract] INT, project INT, activity INT) 
INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 

SELECT DISTINCT [contract], activity FROM @T AS A WHERE 
    (SELECT COUNT(DISTINCT activity) 
    FROM @T AS B WHERE B.[contract] = A.[contract]) = 1 

Powroty: 2000, 49

Rozwiązania z użyciem oryginalnych danych

UWAGA: następujące rozwiązania wykorzystują dane uprzednio podane w pytanie i może nie mieć sensu dla obecnego pytania. Pozostawiłem je załączone tylko dla kompletności.

SELECT Col1, Count(col1) AS count FROM table 
GROUP BY col1 
HAVING count > 1 

To powinno Ci wyświetlić listę wszystkich wartości w col1, które nie są odrębne. Możesz umieścić to w tabeli var lub temp table i dołączyć do niego.

Oto przykład z użyciem sub-zapytanie:

DECLARE @t TABLE(col1 VARCHAR(1), col2 VARCHAR(1), col3 VARCHAR(1)) 

INSERT INTO @t VALUES('A', 'B', 'C'); 
INSERT INTO @t VALUES('D', 'E', 'F'); 
INSERT INTO @t VALUES('A', 'J', 'K'); 
INSERT INTO @t VALUES('G', 'H', 'H'); 

SELECT * FROM @t 

SELECT col1, col2 FROM @t WHERE col1 NOT IN 
    (SELECT col1 FROM @t AS t GROUP BY col1 HAVING COUNT(col1) > 1) 

Powrócisz:

D E 
G H 

a inny sposób, że użytkownicy tabeli temp i dołączenia:

DECLARE @t TABLE(col1 VARCHAR(1), col2 VARCHAR(1), col3 VARCHAR(1)) 

INSERT INTO @t VALUES('A', 'B', 'C'); 
INSERT INTO @t VALUES('D', 'E', 'F'); 
INSERT INTO @t VALUES('A', 'J', 'K'); 
INSERT INTO @t VALUES('G', 'H', 'H'); 

SELECT * FROM @t 

DROP TABLE #temp_table 
SELECT col1 INTO #temp_table 
    FROM @t AS t GROUP BY col1 HAVING COUNT(col1) = 1 

SELECT t.col1, t.col2 FROM @t AS t 
    INNER JOIN #temp_table AS tt ON t.col1 = tt.col1 

też zwraca:

D E 
G H 
+0

Nie jestem pewien, jak wyglądało pierwotne pytanie, kiedy odpowiedziałeś na to pytanie, ale biorąc pod uwagę to, co jest teraz, nie trafia ono w cel i jest niezwykle trudne do odwzorowania celu.Podejrzewam, że tak jest, ponieważ miałeś mniej informacji do pracy, niż teraz. –

+1

Tak, osoba pytająca zmieniła pytanie i użyła innego zestawu danych. Powyższe odpowiedzi były kompletne z podanym zestawem danych. Zaktualizowałem odpowiedź, aby to odzwierciedlić i dodałem rozwiązanie, korzystając z nowego zestawu danych. – vfilby

7

dla MySQL:

SELECT contract, activity 
FROM table 
GROUP BY contract 
HAVING COUNT(DISTINCT activity) = 1 
+0

To również nie działa, nie możesz mieć kolumn na liście wyboru, które nie należą do grupy GROUP BY ani agregatu. Będziesz musiał użyć tej samej zasady, ale w sub-zapytaniu lub dołączyć. – vfilby

+0

faktycznie przetestowałem mój kod w MySQL i działa – mrm

+0

* pracował (z pierwszym przykładem danych) – mrm

2

Modified!

SELECT distinct contract, activity from @t a 
WHERE (SELECT COUNT(DISTINCT activity) FROM @t b WHERE b.contract = a.contract) = 1 

A oto jeszcze jeden - krótszy/odkurzacz bez podzapytanie

select contract, max(activity) from @t 
group by contract 
having count(distinct activity) = 1 
+0

Podczas testowania w produkcie IBM Informix Dynamic Server 11.50 nie tworzy żadnych danych. Problem polega na tym, że kontrakt 2000 ma dwa wiersze projektu z tym samym kodem aktywności, więc COUNT (*) zwraca 2, a nie 1. –

+0

@ Jonathan: pytanie dotyczy Microsoft SQL Server, więc implementacja SQL serwera Informix jest zupełnie nieistotna tutaj. –

+0

To prawda, że ​​IDS nie ma bezpośredniego znaczenia, ale jest poprawną implementacją SQL i powyższy SQL działa, ale nie daje prawidłowej odpowiedzi. –

2

Spróbuj tego:

select 
     contract, 
     max (activity) 
from 
     mytable 
group by 
     contract 
having 
     count (activity) = 1 
+0

W przypadku testowania w produkcie IBM Informix Dynamic Server 11.50 nie tworzy to żadnych danych, a nie wierszy o wartości 2000,49. Problem polega na tym, że kontrakt 2000 ma dwa wiersze projektu z tym samym kodem aktywności, więc liczba (aktywność) = 2, a nie 1 według potrzeb. –

+0

To nie działa w SQL Server 2005. Problem polega na tym, że istnieją dwa wiersze dla 2000,49. Musisz liczyć tylko różne działania. – vfilby

+0

W świetle tych komentarzy zobacz odpowiedź Jetsona. –

1

Zakładając tabela danych jest nazywany ProjectInfo:

SELECT DISTINCT Contract, Activity 
    FROM ProjectInfo 
    WHERE Contract = (SELECT Contract 
          FROM (SELECT DISTINCT Contract, Activity 
            FROM ProjectInfo) AS ContractActivities 
          GROUP BY Contract 
          HAVING COUNT(*) = 1); 

Najbardziej wewnętrzna kwerenda identyfikuje th e umów i działań. Następny poziom zapytania (środkowy) identyfikuje umowy, w których jest tylko jedno działanie. Najbardziej zewnętrzna kwerenda pobiera następnie umowę i działanie z tabeli ProjectInfo dla umów, które mają jedno działanie.

Testowane przy użyciu produktu IBM Informix Dynamic Server 11.50 - powinno również działać w innym miejscu.

1

Oto kolejna opcja korzystania serwery SQL liczyć odrębny:

DECLARE @T TABLE([contract] INT, project INT, activity INT) 
INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 



SELECT DISTINCT [contract], activity FROM @T AS A WHERE 
    (SELECT COUNT(DISTINCT activity) 
    FROM @T AS B WHERE B.[contract] = A.[contract]) = 1 
1
SELECT DISTINCT Contract, Activity 
FROM Contract WHERE Contract IN (
SELECT Contract 
FROM Contract 
GROUP BY Contract 
HAVING COUNT(DISTINCT Activity) = 1) 
+0

Testowany przy użyciu MS SQL 2005 – Hapkido

2

Wykorzystując "dynamiczna tabela" zdolności w SQL Server (odpytywanie na zapytania nawiasie-otoczeniu), można powrócić 2000, 49 w/następujące. Jeśli platforma nie oferuje odpowiednika rozszerzenia ANSI "tabela dynamiczna", zawsze można użyć tabeli tymczasowej w dwóch krokach/instrukcji, wstawiając wyniki w tabeli dynamicznej do tabeli tymczasowej, a następnie wykonanie kolejnego wyboru na tabeli temp.

DECLARE @T TABLE(
    [contract] INT, 
    project INT, 
    activity INT 
) 

INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 

SELECT 
    [contract], 
    [Activity] = max (activity) 
FROM 
    (
    SELECT 
     [contract], 
     [Activity] 
    FROM 
     @T 
    GROUP BY 
     [contract], 
     [Activity] 
    ) t 
GROUP BY 
    [contract] 
HAVING count (*) = 1 
1

Niestety nie używasz PostgreSQL ...

SELECT DISTINCT ON zamówienia, aktywność * OD thetable ORDER BY zamówienia, aktywność

http://www.postgresql.org/docs/8.3/static/sql-select.html#SQL-DISTINCT

Oh wait. Chcesz tylko wartości z dokładnie jeden ...

SELECT kontrakt, działalność, count () OD thetable GROUP BY zamówienia, aktywność HAVING count () = 1

3

jestem fanem NOT EXISTS

SELECT DISTINCT contract, activity FROM table t1 
WHERE NOT EXISTS (
    SELECT * FROM table t2 
    WHERE t2.contract = t1.contract AND t2.activity != t1.activity 
) 
0

Niestety stary słup wiem, ale miałem ten sam problem, nie mógł dostać żadnej z powyższych pracować dla mnie, jednak ja zdobione.

ten pracował mi..

SELECT DISTINCT [Kolumna] Jak UniqueValues ​​ Z [dB] [dbo] [Tabela]

0

SELECT DISTINCT COL1, Col2 z grupy stołowymi COL1 HAVING COUNT (DISTINCT Col1) = 1

Powiązane problemy