2016-12-22 21 views
5

Mam tabeli tak:Jak dodać kolumny, które liczą odrębna osoba dowolne miasto

Person City workingdate 
A Newyork 10.11.2015 
A Newyork 11.11.2015 
A Newyork 12.11.2015 
B Newyork 10.11.2015 
B Newyork 15.11.2015 
B Newyork 16.11.2015 
B Newyork 18.11.2015 

chcę mieć kolumny, które liczą odrębne osoby w mieście:

Person City workingdate countdistinctpersonincity 
A Newyork 10.11.2015    1 
A Newyork 11.11.2015    0 
A Newyork 12.11.2015    0 
B Newyork 10.11.2015    1 
B Newyork 15.11.2015    0 
B Newyork 16.11.2015    0 
B Newyork 18.11.2015    0 

można proszę pomóż mi jak to zrobić?

CREATE TABLE Persons 
(Person varchar(25), 
City varchar(255), 
workingdate varchar(10)); 

insert into Persons 
values ('A', 'Newyork','10.11.2015'), 
('A', 'Newyork','11.11.2015'), 
('A', 'Newyork','12.11.2015'), 
('B', 'Newyork','10.11.2015'), 
('B', 'Newyork','15.11.2015'), 
('B', 'Newyork','16.11.2015'), 
('B', 'Newyork','18.11.2015'); 
+0

jaka jest twoja wersja serwera SQL? – TheGameiswar

Odpowiedz

2
SELECT p.*, p2.* 
FROM #Persons p 
    CROSS APPLY 
     (SELECT COUNT (DISTINCT p1.Person) as countdistinctpersonincity 
     FROM 
      #Persons p1 
     WHERE 
      p1.Person <> p.Person 
      AND p1.City = p.City 
      AND p1.workingdate = p.workingdate) p2; 

kod testowy

CREATE TABLE #Persons 
(Person varchar(25), 
City varchar(255), 
workingdate varchar(10)) 
insert into #Persons 
values ('A', 'Newyork','10.11.2015'), 
('A', 'Newyork','11.11.2015'), 
('A', 'Newyork','12.11.2015'), 
('B', 'Newyork','10.11.2015'), 
('B', 'Newyork','15.11.2015'), 
('B', 'Newyork','16.11.2015'), 
('B', 'Newyork','18.11.2015'); 

SELECT p.*, p2.* 
FROM #Persons p 
    CROSS APPLY 
     (SELECT COUNT (DISTINCT p1.Person) as countdistinctpersonincity 
     FROM 
      #Persons p1 
     WHERE 
      p1.Person <> p.Person 
      AND p1.City = p.City 
      AND p1.workingdate = p.workingdate) p2; 

DROP TABLE #Persons; 

Rezultat jest taki:

Person City  workingdate countdistinctpersonincity 
A  Newyork 10.11.2015 1 
A  Newyork 11.11.2015 0 
A  Newyork 12.11.2015 0 
B  Newyork 10.11.2015 1 
B  Newyork 15.11.2015 0 
B  Newyork 16.11.2015 0 
B  Newyork 18.11.2015 0 
4

Jeden wariant:

SELECT * 
     ,IIF(ROW_NUMBER() OVER(PARTITION BY City, Person ORDER BY workingdate) = 1, 1, 0) 
FROM Persons 

enter image description here


Dla SQL Server przed rokiem 2012, można użyć:

SELECT P.* 
     ,CASE WHEN DS.[City] IS NULL THEN 0 ELSE 1 END 
FROM Persons P 
LEFT JOIN 
(
    SELECT City 
      ,Person 
      ,MIN(workingdate) AS workingdate 
    FROM Persons 
    GROUP BY City 
      ,Person 
) DS 
    ON P.City = DS.[City] 
    AND P.[Person] = DS.[Person] 
    AND P.[workingdate] = DS.[workingdate] 
2

Wierzę, że ta kwerenda będzie dać wynik . Chodzi o to, aby sprawdzić, czy poprzedni wpis klasyfikowane przez osoby i daty jest inny, więc oznacza to, że dotarliśmy do nowej osoby:

select case 
     when Person != lag(Person, 1, 'XXXXXX') over (order by Person, workingdate) then 1 
     else 0 
     end 
    from table; 

Aby zobaczyć jak to działa Oto przykład:

CREATE TABLE #Persons (
    Person varchar(25), 
    City varchar(255), 
    workingdate varchar(10) 
) 

insert into #Persons 
values ('A', 'Newyork','10.11.2015'), 
     ('A', 'Newyork','11.11.2015'), 
     ('A', 'Newyork','12.11.2015'), 
     ('B', 'Newyork','10.11.2015'), 
     ('B', 'Newyork','15.11.2015'), 
     ('B', 'Newyork','16.11.2015'), 
     ('B', 'Newyork','18.11.2015') 

select p.Person, p.City, p.workingdate, 
     case 
     when p.Person != lag(p.Person, 1, 'XXXXXX') over (order by p.Person, p.workingdate) then 1 
     else 0 
     end 
from #Persons p 

wynikiem jest:

Person City  workingdate COLUMN1 
A  Newyork 10.11.2015 1 
A  Newyork 11.11.2015 0 
A  Newyork 12.11.2015 0 
B  Newyork 10.11.2015 1 
B  Newyork 15.11.2015 0 
B  Newyork 16.11.2015 0 
B  Newyork 18.11.2015 0