2014-10-15 3 views
0

Этот запрос SQL Server работаетДополнительные столбцы в SELECT COUNT()

SELECT 
    dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
FROM 
    dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.SEM_CLIENT, dbo.SEM_AGENT, dbo.IDENTITY_MAP 
WHERE 
    sem_computer.COMPUTER_ID = [dbo].[V_SEM_COMPUTER].COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_CLIENT.COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID 
    and dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID 
    and dbo.SEM_AGENT.TIME_STAMP > DATEDIFF(second, '19700101', DATEADD(day, -1, GETDATE())) *  CAST(1000 as bigint) 
GROUP BY dbo.sem_computer.COMPUTER_ID 
HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1 
ORDER BY Duplicate_Hardware_IDs DESC; 

Но я хочу SELECT дополнительные колонки (чтобы показать, какие компьютеры имеют дублирующие COMPUTER_ID)

SELECT 
    dbo.sem_computer.COMPUTER_NAME 
, [IP_ADDR1_TEXT] 
, dbo.SEM_AGENT.AGENT_VERSION 
, dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
FROM 
    dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.SEM_CLIENT, dbo.SEM_AGENT, dbo.IDENTITY_MAP 
WHERE 
    sem_computer.COMPUTER_ID = [dbo].[V_SEM_COMPUTER].COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_CLIENT.COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID 
    and dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID 
    and dbo.SEM_AGENT.TIME_STAMP > DATEDIFF(second, '19700101', DATEADD(day, -1, GETDATE())) *  CAST(1000 as bigint) 
GROUP BY dbo.sem_computer.COMPUTER_ID 
HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1 
ORDER BY Duplicate_Hardware_IDs DESC; 

Я получаю ошибку

Столбец «dbo.sem_computer.COMPUTER_NAME» недействителен в списке выбора, потому что он не содержится либо в агрегатной функции, либо в предложении GROUP BY.

Как исправить?

UPDATE: когда я исполню

SELECT 
    dbo.sem_computer.COMPUTER_NAME 
, [IP_ADDR1_TEXT] 
, dbo.SEM_AGENT.AGENT_VERSION 
, dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
FROM 
    dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.SEM_CLIENT, dbo.SEM_AGENT, dbo.IDENTITY_MAP 
WHERE 
    sem_computer.COMPUTER_ID = [dbo].[V_SEM_COMPUTER].COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_CLIENT.COMPUTER_ID 
    and sem_computer.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID 
    and dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID 
    and dbo.SEM_AGENT.TIME_STAMP > DATEDIFF(second, '19700101', DATEADD(day, -1, GETDATE())) *  CAST(1000 as bigint) 
GROUP BY dbo.sem_computer.COMPUTER_NAME,[IP_ADDR1_TEXT], dbo.SEM_AGENT.AGENT_VERSION, dbo.sem_computer.COMPUTER_ID 
HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1 
ORDER BY Duplicate_Hardware_IDs DESC; 

это приводит к

COMPUTER_NAME IP_ADDR1_TEXT AGENT_VERSION COMPUTER_ID   Duplicate_Hardware_IDs 
ABC    10.10.10.10  12.1    56604FEE0AF    3 

Но я ищу

COMPUTER_NAME IP_ADDR1_TEXT AGENT_VERSION COMPUTER_ID   Duplicate_Hardware_IDs 
ABC    10.10.10.10  12.1    56604FEE0AF    3 
123    10.10.10.15  12.2    56604FEE0AF    3 
XYZ    10.10.10.25  12.2    56604FEE0AF    3 

UPDATE 2:

Я включил FROM и WHERE

+0

Добавить COMPUTER_NAME в группу по – NMK

+0

Попробуйте мой [ответ] (http://stackoverflow.com/a/26387167/2246380), если вы не хотите группировать по столбцам, которые могут уменьшить строки в результате, который является что случилось с вами? – Ram

+1

На основе вашего обновления: хотите ли вы видеть дубликаты, рассчитанные для каждого COMPUTER_NAME, или вы хотите, чтобы общее количество дубликатов с таким же номером появлялось для каждого COMPUTER_NAME? –

ответ

3
;WITH CTE AS 
(
    SELECT dbo.sem_computer.COMPUTER_NAME, 
      [IP_ADDR1_TEXT], 
      dbo.SEM_AGENT.AGENT_VERSION, 
      dbo.sem_computer.COMPUTER_ID, 
      N = COUNT(*) OVER(PARTITION BY dbo.sem_computer.COMPUTER_ID) 
    FROM 
    ... 
    WHERE 
    ... 
) 
SELECT * 
FROM CTE 
WHERE N > 1 
ORDER BY N DESC 
+0

Двойной псевдоним для' COUNT (*) 'с' N = 'и' as Duplicate_Hardware_IDs', кроме этого это предпочтительный ответ imo. –

+0

@GoatCO Упс, вы совершенно правы, извините за это – Lamak

+0

@Lamark он просто повторяет поле с ABC три раза. Можете ли вы обновить это решение? – Glowie

2

Просто включите столбцы в вашем Select список в Group By список

SELECT 
    dbo.sem_computer.COMPUTER_NAME 
, [IP_ADDR1_TEXT] 
, dbo.SEM_AGENT.AGENT_VERSION 
, dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
FROM 
... 
WHERE 
... 
GROUP BY 
    dbo.sem_computer.COMPUTER_ID, 
    dbo.sem_computer.COMPUTER_NAME, 
    ... 
HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1 
ORDER BY Duplicate_Hardware_IDs DESC;` 
1

Любой столбец, который находится в операторе отбора, но не в какой-либо агрегатной функции (MIN, MAX, SUM, COUNT, AVG), должны войти в предложение GROUP BY.

SELECT 
     dbo.sem_computer.COMPUTER_NAME 
     ,[IP_ADDR1_TEXT] 
     ,dbo.SEM_AGENT.AGENT_VERSION 
     ,dbo.sem_computer.COMPUTER_ID 
     ,COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
    FROM 
    ... 
    WHERE 
    ... 
    GROUP BY dbo.sem_computer.COMPUTER_NAME 
      ,[IP_ADDR1_TEXT] 
      ,dbo.SEM_AGENT.AGENT_VERSION 
      ,dbo.sem_computer.COMPUTER_ID 
    HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1 
    ORDER BY Duplicate_Hardware_IDs DESC; 
0

Вы можете добавить столбцы в предложении GROUP BY, как другие упомянутые или, если вы не хотите, чтобы сделать группу, с тобою столбцами, то попробуйте следующий

SELECT 
    dbo.sem_computer.COMPUTER_NAME, 
    [IP_ADDR1_TEXT], 
    dbo.SEM_AGENT.AGENT_VERSION, 
    dbo.sem_computer.COMPUTER_ID, Duplicate_Hardware_IDs 
FROM dbo.sem_computer c 
INNER JOIN 
dbo.SEM_AGENT ON //add the join conditions 
INNER JOIN 
(SELECT 
    dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
FROM 
... 
WHERE 
... 
GROUP BY dbo.sem_computer.COMPUTER_ID 
HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1) temp 
ON c.COMPUTER_ID=temp.COMPUTER_ID 
ORDER BY Duplicate_Hardware_IDs DESC; 
0

У вас есть добавить все не агрегатных полей в группе по статье: GROUP BY dbo.sem_computer.COMPUTER_NAME,[IP_ADDR1_TEXT] ,dbo.SEM_AGENT.AGENT_VERSION, dbo.sem_computer.COMPUTER_ID

SELECt dbo.sem_computer.COMPUTER_NAME,IP_ADDR1_TEXT,dbo.SEM_AGENT.AGENT_VERSION,dbo.sem_computer.COMPUTER_ID, COUNT(dbo.sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs FROM ... WHERE ...GROUP BY dbo.sem_computer.COMPUTER_NAME,IP_ADDR1_TEXT,dbo.SEM_AGENT.AGENT_VERSION, dbo.sem_computer.COMPUTER_ID HAVING COUNT(dbo.sem_computer.COMPUTER_ID) > 1ORDER BY Duplicate_Hardware_IDs DESc 
0

Трудно сказать по вашему запросу, поскольку вы не показываете, как вы связываете SEM_AGENT с запросом.

Одним из вариантов является добавление поля в группу - просто добавьте запятую и имя поля.
Вы также можете использовать агрегатную функцию, такую ​​как LAST(), в которой вы возвращаете поле в запросе. Вы также можете использовать подвыбор, чтобы вернуть поле. Хотя я не уверен в этом.

0

Вы можете решить эту проблему, присоединившись к вашим двум запросам. Что-то вроде следующего должно работать.

;WITH Duplicates AS (
    SELECT 
     sem_computer.COMPUTER_ID, 
     COUNT(sem_computer.COMPUTER_ID) as Duplicate_Hardware_IDs 
    FROM 
     sem_computer 
    WHERE 
     ... 
    GROUP BY sem_computer.COMPUTER_ID 
) 
SELECT 
    sem_computer.COMPUTER_NAME, 
    sem_computer.[IP_ADDR1_TEXT], 
    SEM_AGENT.AGENT_VERSION, 
    sem_computer.COMPUTER_ID 
FROM 
     sem_computer 
    INNER JOIN 
     Duplicates 
      ON sem_computer.COMPUTER_ID = Duplicates.COMPUTER_ID 
    INNER JOIN 
     SEM_AGENT 
      ON SEM_AGENT.COMPUTER_ID = sem_computer.COMPUTER_ID 
WHERE 
    Duplicates.Duplicate_Hardware_IDs > 1 
ORDER BY Duplicate_Hardware_IDs DESC; 

Сначала найдите дубликаты, а затем СОЕДИНИТЕСЬ на них и верните дополнительную информацию. Вам также нужно подключиться к таблице SEM_AGENT.

Смежные вопросы