SELECT DISTINCT *
FROM
(SELECT dbtables.[name] as 'back_end_name',
CASE
WHEN dbtables.[name] LIKE '_Result%' AND CAST(RIGHT(dbtables.[name], LEN(dbtables.[name]) - 7) AS int) = CalculationID
THEN Calculation.Name
WHEN dbtables.[name] LIKE '_History%'
THEN
CASE
WHEN LEN(dbtables.[name]) = 9 AND CAST(RIGHT(dbtables.[name], 1) AS int) = HistoryID
THEN HistoryMap.TableName
WHEN LEN(dbtables.[name]) = 10 AND CAST(RIGHT(dbtables.[name], 2) AS int) = HistoryID
THEN HistoryMap.TableName
WHEN LEN(dbtables.[name]) = 11 AND CAST(RIGHT(dbtables.[name], 3) AS int) = HistoryID
THEN HistoryMap.TableName
ELSE 'N/A'
END
ELSE 'N/A'
END AS front_end_name,
indexstats.avg_fragmentation_in_percent,
indexstats.page_count,
indexstats.record_count
FROM Calculation, HistoryMap, sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'Sampled') AS indexstats
INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent >= 30) tmp
WHERE front_end_name NOT LIKE '%N/A%'
我有以下查询有效,但是当我只需要1个实例时,“ front_end_name”中的某些数据重复,因此我在最后添加了“ GROUP BY front_end_name”,但它返回错误“ Column'tmp.back_end_name” '在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中”。为什么现在要谈论back_end_name?
当我在第一个WHERE子句之后添加GROUP BY时,在所附查询的末尾,它说front_end_name是无效的列名。
此外,我想订购indexstats.avg_fragmentation_in_percent。显然,我不能在查询的最后执行此操作,因为indexstats对于包含在封闭查询中是本地的。当我尝试在所附查询的末尾执行此操作时,它告诉我“除非已指定TOP,OFFSET或FOR XML,否则ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效。 。”
关于如何将GROUP BY front_end_name和ORDER BY indexstats.avg_fragmentation_in_percent添加到现有查询的任何提示?对于SQL还是很新的,所以我正在学习。我正在努力避免多次编写案例声明。
谢谢!
答案 0 :(得分:0)
不要简单地在任何地方添加GROUP BY
来删除重复项。这主要用于聚合目的。退后一步,考虑一下您的需求。
首先,问问自己:当 front_end_name 重复时,其他列(back_end_name
,avg_fragmentation_in_percent
,{{1} },page_count
)重复吗?由于您的外部查询使用record_count
,因此它们可能不会重复。
现在,考虑一下您的数据。如何为每个重复的DISTINCT
处理非重复列?可能是由于联接表front_end_name
,Calculation
,HistoryMap
等的粒度所致,根据您计算出的<,表可以具有一对多或多对多关系strong> front_end_name 。
使用CTE保存原始的 基本 结果,请考虑汇总其他列以避免重复的名称
sys.tables
或者,如果您知道重复的原因,则汇总WITH base AS (
SELECT dbtables.[name] AS back_end_name,
CASE
WHEN dbtables.[name] LIKE '_Result%' AND CAST(RIGHT(dbtables.[name], LEN(dbtables.[name]) - 7) AS int) = CalculationID
THEN Calculation.Name
WHEN dbtables.[name] LIKE '_History%'
THEN
CASE
WHEN LEN(dbtables.[name]) = 9 AND CAST(RIGHT(dbtables.[name], 1) AS int) = HistoryID
THEN HistoryMap.TableName
WHEN LEN(dbtables.[name]) = 10 AND CAST(RIGHT(dbtables.[name], 2) AS int) = HistoryID
THEN HistoryMap.TableName
WHEN LEN(dbtables.[name]) = 11 AND CAST(RIGHT(dbtables.[name], 3) AS int) = HistoryID
THEN HistoryMap.TableName
ELSE 'N/A'
END
ELSE 'N/A'
END AS front_end_name,
indexstats.avg_fragmentation_in_percent,
indexstats.page_count,
indexstats.record_count
FROM Calculation, HistoryMap, sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'Sampled') AS indexstats
INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent >= 30
)
SELECT back_end_name,
front_end_name,
AVG(avg_fragmentation_in_percent) AS avg_page_count, -- ADJUST AGG FUNCTION TO NEEDS
SUM(page_count) AS sum_page_count, -- ADJUST AGG FUNCTION TO NEEDS
SUM(record_count) AS sum_record_count -- ADJUST AGG FUNCTION TO NEEDS
FROM base
GROUP BY back_end_name, -- GROUP BY REQUIRES ALL NON-AGG COLUMNS PRESENT IN CLAUSE
front_end_name
ORDER BY AVG(avg_fragmentation_in_percent)
:
front_end_name