2016-01-10 5 views
2

Я пытаюсь получить количество повторяющихся данных, но мой запрос работает некорректно.MYSQL Количество повторяющихся записей с условием

Каждый пользователь должен иметь один dev_id но когда другой пользователь будет иметь такую ​​же dev_id я хочу знать, это

таблицу, например:

dev_id  user_id 
------------------ 
    111   1 
    111   1 
    222   2 
    111   2 
    333   3 

Если результат:

user_id  qu 
    ------------------ 
    1   1 
    2   1 
    3   0 

Это мой запрос

SELECT t1.user_id, 
    (SELECT Count(DISTINCT t2.dev_id) 
     FROM reports t2 
     WHERE t2.user_id != t1.user_id 
     AND t2.dev_id = t1.dev_id 
    ) AS qu 
FROM  reports t1 
GROUP BY t1.user_id 
+0

Не работает правильно как? Что оно делает? – GolezTrol

+0

Пожалуйста, уточните, что вы подразумеваете под «дублирующимися данными». –

+0

У каждого пользователя должен быть один dev_id, но когда у другого пользователя будет такой же dev_id, я хочу знать это. – Karpol

ответ

0

Хорошо. Пусть начнется с простого.

Прежде всего, необходимо получить комбинации идентификаторов уникальный user_id/Dev

select distinct dev_id,user_id from reports 

Результат будет

dev_id  user_id 
------------------ 
    111   1 
    222   2 
    111   2 
    333   3 

После этого вы должны получить количество различных user_id на dev_id

select dev_id,c from (
    SELECT 
    dev_id, 
    count(*)-1 AS c 
    FROM 
    (select distinct user_id,dev_id from reports) as fixed_reports 
    GROUP BY dev_id 
        ) as counts 

Результат такого запроса будет

dev_id  c 
----------------- 
    111   1 
    222   0 
    333   0 

Теперь вы должны показать пользователям, у которых есть такой dev_id. Для этого вы должны присоединиться к такому dev_id список с таблицей из step1 (которые показывают, какой из user_id, существует dev_id пара)

select distinct fixed_reports2.user_id,counts.c from (
    SELECT 
    dev_id, 
    count(*)-1 AS c 
    FROM 
    (select distinct user_id,dev_id from reports) as fixed_reports 
    GROUP BY dev_id 
              ) as counts 
     join 
    (select distinct user_id,dev_id from reports) as fixed_reports2 
     on fixed_reports2.dev_id=counts.dev_id 
    where counts.c>0 and counts.c is not null 

«Четкие» здесь нужно пропустить то же строку.

Результат должен быть для внутреннего запроса

dev_id  c 
----------------- 
    111   1 

Для всех запросов

user_id  c 
------------------ 
    1   1 
    2   1 

Если вы уверены, что вам нужно также строки с = 0, то вам нужно сделать «левое соединение» из fixed_reports2 и большой запрос, таким образом вы получите все строки и строки с c = null будут строками с 0 (может быть изменено оператором case/when)

+0

Я хочу получить информацию о том, имеет ли другой пользователь этот же dev_id. Тогда оба пользователя получают 1. К сожалению, этот запрос не работает – Karpol

+0

Хорошо, я изменил свой ответ. Посмотрите это сейчас и попробуйте по очереди задавать вопрос, почему он работает именно так. – arheops

1

Вы можете получить результаты, выполнив:

select r.user_id, count(*) - 1 
from reports r 
group by r.user_id; 

Является ли это расчет, что вы хотите?

-1

Попробуйте

SELECT 
    user_id, 
    SUM(qu) AS qu 
FROM (
    SELECT 
     user_id, 
     count(*)-1 AS qu 
    FROM 
     reports 
    GROUP BY user_id, dev_id 
) AS r 
GROUP BY user_id 

Нет необходимости делать присоединиться, если все данные вам нужно, в одной таблице.

Edit: изменили группу, чтобы dev_id вместо user_id

edit2: Я думаю, вам нужно как dev_id и user_id в группе по п.

Edit3: Добавлен подзапрос, чтобы получить желаемый результат. Это может быть немного громоздким, возможно, у кого-то есть способ улучшить это?

+0

Что бы вы ответили на вопрос с запросом, в котором предложение 'select' содержит столбцы, которые не находятся в разделе' group by'? (Примечание: я не являюсь downvoter.) –

+0

Зачем вам группировать dev_id, если запрос должен возвращать данные на user_id? – GolezTrol

+0

Он хочет, чтобы каждому пользователю был присвоен номер дубликата dev_id. Я понимаю, что теперь мой ответ не полностью решает вопрос. –

0

Ваш запрос нарушен и не будет работать во многих системах. Проблема состоит в том, что группа с user_id из 2 имеет два разных значения: dev_id. Если вы запустите «сломанный запрос» ниже, вы увидите, что min() и max() отличаются, но подзапрос видит только одно из тех значений, которое выбрано случайным образом. Последний запрос исправляется добавлением dev_id в группы, которые показывают, где «недостающая» строка попала в подсчеты.

SELECT -- broken query 
    t1.user_id, min(t1.dev_id), max(t1.dev_id), 
    (select distinct t1.dev_id from reports) as should_have_errored, 
    (SELECT Count(DISTINCT t2.dev_id) 
     FROM reports t2 
     WHERE t2.user_id != t1.user_id 
     AND t2.dev_id = t1.dev_id 
    ) AS qu 
FROM  reports t1 
GROUP BY t1.user_id; 

-- On SQL Server that query returns an error 
-- Msg 8120, Level 16, State 1, Line 7 
-- Column 'reports.dev_id' is invalid in the select list because it is 
-- not contained in either an aggregate function or the GROUP BY clause. 

SELECT -- query that duplicates your original query 
    t1.user_id, 
    (SELECT Count(DISTINCT t2.dev_id) 
     FROM reports t2 
     WHERE t2.user_id != t1.user_id 
     AND t2.dev_id = max(t1.dev_id) /* <-- see here */ 
    ) AS qu 
FROM  reports t1 
GROUP BY t1.user_id; 

SELECT t1.user_id, t1.dev_id, -- fixed query 
    (SELECT Count(DISTINCT t2.dev_id) 
     FROM reports t2 
     WHERE t2.user_id != t1.user_id 
     AND t2.dev_id = t1.dev_id 
    ) AS qu 
FROM  reports t1 
GROUP BY t1.user_id, t1.dev_id 

http://sqlfiddle.com/#!9/6576e3/20

Вот некоторые вопросы, которые могут быть полезны:

Какие dev_id s имеют несколько user_id s, связанные с ними?

select dev_id 
from reports 
group by dev_id 
having count(distinct user_id) > 1 

Какие другие user_id сек разделяют dev_id с этим user_id?

select user_id 
from reports r1 
where exists (
    select 1 
    from reports r2 
    where r2.dev_id = r1.dev_id and r2.user_id <> ? 
) 

Или действительно это просто эквивалентно внутреннему соединению, что также позволяет легко перечислить всех сразу. Обратите внимание, что каждая пара будет в списке дважды:

select r1.user_id, r1.dev_id, r2.user_id as common_user_id 
from 
    reports r1 inner join reports r2 
     on r2.dev_id = r1.dev_id 
where 
    r1.user_id <> r2.user_id 
order by 
    r1.user_id, r1.dev_id, r2.user_id 

А поскольку у вас есть повторяющиеся строки в таблице вы должны сделать это select distinct, чтобы получить уникальные строки.

0

Я думаю, что следующий запрос SQL должен решить вам проблему:

SELECT t1.user_id, t1.dev_id, count(t2.user_id) as qu 
FROM (Select Distinct * from reports) t1 
Left Join (Select Distinct * from reports) t2 
on t1.user_id != t2.user_id and t2.dev_id = t1.dev_id 
group by t1.user_Id, t1.dev_id 

SQL Fiddle Link

0
SELECT user_id, (COUNT(user_id) -1) as qu 
FROM reports 
GROUP BY user_id 

Это даст желаемый результат в вашем случае, однако вы можете улучшить его намного больше. Cheers ,,