Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как исключить повторы?  [new]
Glaciuse
Member

Откуда:
Сообщений: 3
Доброго времени соток, начал изучать SQL и пытаясь прорешать некоторые примеры, столкнулся со следующей проблемой:
Есть следующая таблица:

permitId touristId
10 1
14 1
15 2
28 2
15 2
10 3
12 4
14 5
10 5

Нужно выбрать тех touristId, у которых идентичны левые части, т.е. из этой таблицы это будут touristId = 1 и tourist = 5.
Как это реализовать?

Данную таблицу получаю следующим запросом:
select permit_tourist.permitId, tourist.touristId
from permit_tourist, tourist 
where permit_tourist.touristId = tourist.touristId
order by tourist.touristId


Заранее благодарен!
9 май 12, 20:06    [12527258]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
У этих туристов левые части одинаковые или нет?
(15, 2),
(28, 2),
(15, 2),

(15, 6),
(28, 6),

Если нет, то можно попробовать как то так:
DECLARE @A AS TABLE (permitId int, touristId int)
INSERT INTO @A 
VALUES (10, 1),(14, 1),(15, 2),(28, 2),(15, 2),(10, 3),(12, 4),(14, 5),(10, 5)

;WITH CTE
AS(SELECT *, COUNT(*) OVER (PARTITION BY touristId) PermitByTouristCount FROM @A)

SELECT 
  A1.touristId, A2.touristId
FROM 
  CTE A1
  INNER JOIN CTE A2 ON A1.touristId < A2.touristId
                  AND A1.permitId = A2.permitId
                  AND A1.PermitByTouristCount = A2.PermitByTouristCount
GROUP BY A1.touristId, A2.touristId, A1.PermitByTouristCount
HAVING COUNT(*) = A1.PermitByTouristCount

Если да, то удалите сначала дубликаты DISTINCT-ом или GROUP BY
10 май 12, 01:14    [12527884]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Или вообще вот так:
DECLARE @A AS TABLE (permitId int, touristId int)
INSERT INTO @A 
VALUES (10, 1),(14, 1),(15, 2),(28, 2),(15, 2),(10, 3),(12, 4),(14, 5),(10, 5),(10, 6),(14, 6)

;WITH CTE
AS(
  SELECT
    touristId,
    PermitGroupID = 
      DENSE_RANK() OVER 
        (ORDER BY (SELECT permitId 
                   FROM @A A2 
                   WHERE A2.touristId = A1.touristId 
                   ORDER BY permitId 
                   FOR XML AUTO)
        )
  FROM @A A1
  GROUP BY touristId
)

SELECT PermitGroupID, touristId
FROM CTE
WHERE PermitGroupID IN 
  (SELECT PermitGroupID
  FROM CTE 
  GROUP BY PermitGroupID
  HAVING COUNT(*) > 1)
ORDER BY PermitGroupID
10 май 12, 02:56    [12527964]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
aleks2
Guest
DECLARE @A AS TABLE (permitId int, touristId int)
INSERT INTO @A 
VALUES (10, 1),(14, 1),(15, 2),(28, 2),(15, 2),(10, 3),(12, 4),(14, 5),(10, 5)

;with
pairs as (
  select DISTINCT A1.touristId touristId1, A2.touristId touristId2 from @A A1 inner join @A A2 on A1.permitId = A2.permitId and A1.touristId < A2.touristId
)
select * 
from 
pairs P 
WHERE 
not exists(select * 
             from 
               (select * from @A where touristId = p.touristId1) A1 
               left outer join 
               (select * from @A where touristId = p.touristId2) A2 
               on A1.permitId = A2.permitId 
               where A2.touristId is null
           )
and
not exists(select * 
             from 
               (select * from @A where touristId = p.touristId1) A1 
               right outer join 
               (select * from @A where touristId = p.touristId2) A2 
               on A1.permitId = A2.permitId 
               where A1.touristId is null
           )


можно и так... но там OR
;with
pairs as (
  select DISTINCT A1.touristId touristId1, A2.touristId touristId2 from @A A1 inner join @A A2 on A1.permitId = A2.permitId and A1.touristId < A2.touristId
)
select * 
from 
pairs P 
WHERE 
not exists(select * 
             from 
               (select * from @A where touristId = p.touristId1) A1 
               full outer join 
               (select * from @A where touristId = p.touristId2) A2 
               on A1.permitId = A2.permitId 
               where A2.touristId is null or A1.touristId is null
           )
10 май 12, 05:45    [12527998]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
ALOTE
Member

Откуда:
Сообщений: 1748
Может я что то не понял, но по-моему, это делает так. Не буду вдаваться в Ваш запрос, просто представлю его как таблицу. Назовем TBL.
select touristid
from TBL
group by touristid
having count(touristid)>1
10 май 12, 23:07    [12533262]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
ALOTE
Member

Откуда:
Сообщений: 1748
А да, действительно не понял. Пардон.
10 май 12, 23:18    [12533292]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
какой-то дядя
Guest
печенью чувствую, что правильно, но доказать не смогу :)
declare @t table(permitId int, touristId int)

insert into @t
select 10, 1 union all
select 14, 1 union all
select 15, 2 union all
select 28, 2 union all
select 15, 2 union all
select 10, 3 union all
select 12, 4 union all
select 14, 5 union all
select 10, 5

;with cte as
(select touristId, 
avg(permitId) as avg_, 
varp(permitId) as varp_,
count(permitId) as count_--,
--min(permitId) as min_, 
--max(permitId) as max_,  
--sum(permitId) as sum_, 
--stdev(permitId) as stdev_, 
--stdevp(permitId) as stdevp_,
--var(permitId) as var_
from @t
group by touristId)

select t1.touristId
from cte t1 inner join cte t2
  on t1.touristId<>t2.touristId and t1.avg_=t2.avg_ and t1.varp_=t2.varp_ and t1.count_=t2.count_

(9 row(s) affected)
touristId
-----------
5
1

(2 row(s) affected)
10 май 12, 23:57    [12533404]     Ответить | Цитировать Сообщить модератору
 Re: Как исключить повторы?  [new]
ALOTE
Member

Откуда:
Сообщений: 1748
Вот наколдовал что то, ибо задача понравилась. Но за совсем точный результат не ручаюсь - спать охота.
select distinct a.touristId from(
select distinct TBL.permitId,table_1.touristId from TBL join TBL as a on a.touristId<>TBL.touristId
and a.permitId=TBL.permitId) a
join (
select distinct TBL.permitId,TBL.touristId from TBL join TBL as a on a.touristId<>TBL.touristId
and a.permitId=TBL.permitId) b on b.permitId<>a.permitId and a.touristId=b.touristId
11 май 12, 00:14    [12533470]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить