Sql 基于列名确定索引
是否有任何方法将列名与索引中的列名相匹配 例如,让我们假设index1使用列名称、年龄、地址,index2使用(在同一个表中)名称、年龄 如果我将name、age和表名传递给存储的proc,我应该编写什么查询来返回index2而不是index1 我遇到了许多关于如何使用索引和表名列出列的示例,如: 但是仍然无法为我的使用编写sql查询 任何帮助都将不胜感激 多谢各位 (这是针对Microsoft sql server 2008-2012的) 这是我写的,它没有正常工作,因此问题Sql 基于列名确定索引,sql,sql-server,indexing,Sql,Sql Server,Indexing,是否有任何方法将列名与索引中的列名相匹配 例如,让我们假设index1使用列名称、年龄、地址,index2使用(在同一个表中)名称、年龄 如果我将name、age和表名传递给存储的proc,我应该编写什么查询来返回index2而不是index1 我遇到了许多关于如何使用索引和表名列出列的示例,如: 但是仍然无法为我的使用编写sql查询 任何帮助都将不胜感激 多谢各位 (这是针对Microsoft sql server 2008-2012的) 这是我写的,它没有正常工作,因此问题 select
select index1.name,sys.tables.name, Stuff((SELECT ',' + sys.columns.name AS [text()]
FROM
(
select sys.columns.name
from sys.columns
inner join sys.index_columns On sys.index_columns.index_column_id=sys.columns.column_id
inner join sys.indexes on sys.indexes.index_id=sys.index_columns.index_id
where sys.indexes.index_id=index1.index_id
) x
For XML PATH (''), type ).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'') As coLName
from sys.indexes as index1
inner join sys.tables on sys.tables.object_id=index1.object_id
inner join sys.index_columns On index1.index_id=sys.index_columns.index_id AND sys.index_columns.object_id = sys.tables.object_id
inner join sys.columns on sys.columns.column_id=sys.index_columns.column_id And sys.columns.object_id=sys.tables.object_id
where sys.tables.name=TABLE_NAME
您可以使用以下命令尝试此查询: 在第二个场景中,无论顺序如何,都要指定列和空间
DECLARE @searchIndex nvarchar(100) = ' age, name' ,
@tableName nvarchar (100) = 'your_tableName'
;WITH ParsSearchIndex AS
(
SELECT SUBSTRING(@searchIndex , 0 , CHARINDEX ( ',' , @searchIndex )) AS val ,
CAST(STUFF (@searchIndex + ',' , 1, CHARINDEX( ',', @searchIndex), '') AS nvarchar (100 )) AS stval
UNION ALL
SELECT LTRIM(SUBSTRING (stval , 0, CHARINDEX( ',', stval))),
CAST(STUFF (stval , 1, CHARINDEX( ',' , stval ), '' ) AS nvarchar(100 ))
FROM ParsSearchIndex
WHERE stval != ''
), max_ParsSearchIndex AS
(
SELECT val, COUNT(*) OVER() AS cnt
FROM ParsSearchIndex
WHERE val != ''
), cte AS
(
SELECT i.name AS index_name, c.name , ic .is_included_column,
MAX(ic .index_column_id) OVER( PARTITION BY i. index_id) AS maxIndex_column_id
FROM sys.indexes i LEFT JOIN sys. index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
LEFT JOIN sys. columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.object_id = OBJECT_ID(@tableName )
), cte2 AS
(
SELECT c2.index_name , COUNT (*) AS cnt, c2. maxIndex_column_id,
STUFF((SELECT ',' + c .name
FROM cte c
WHERE c .index_name = c2 .index_name
FOR XML PATH , TYPE ).value( '.[1]', 'nvarchar(max)'), 1 , 1, '') [columns]
FROM cte c2
WHERE c2.is_included_column != 1 AND EXISTS (
SELECT 1
FROM max_ParsSearchIndex p
WHERE c2 .name = p .val AND p .cnt = c2.maxIndex_column_id
)
GROUP BY c2 .index_name, c2. maxIndex_column_id
)
SELECT index_name, [columns]
FROM cte2
WHERE cnt = maxIndex_column_id
您可以使用以下命令尝试此查询: 在第二个场景中,无论顺序如何,都要指定列和空间
DECLARE @searchIndex nvarchar(100) = ' age, name' ,
@tableName nvarchar (100) = 'your_tableName'
;WITH ParsSearchIndex AS
(
SELECT SUBSTRING(@searchIndex , 0 , CHARINDEX ( ',' , @searchIndex )) AS val ,
CAST(STUFF (@searchIndex + ',' , 1, CHARINDEX( ',', @searchIndex), '') AS nvarchar (100 )) AS stval
UNION ALL
SELECT LTRIM(SUBSTRING (stval , 0, CHARINDEX( ',', stval))),
CAST(STUFF (stval , 1, CHARINDEX( ',' , stval ), '' ) AS nvarchar(100 ))
FROM ParsSearchIndex
WHERE stval != ''
), max_ParsSearchIndex AS
(
SELECT val, COUNT(*) OVER() AS cnt
FROM ParsSearchIndex
WHERE val != ''
), cte AS
(
SELECT i.name AS index_name, c.name , ic .is_included_column,
MAX(ic .index_column_id) OVER( PARTITION BY i. index_id) AS maxIndex_column_id
FROM sys.indexes i LEFT JOIN sys. index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
LEFT JOIN sys. columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.object_id = OBJECT_ID(@tableName )
), cte2 AS
(
SELECT c2.index_name , COUNT (*) AS cnt, c2. maxIndex_column_id,
STUFF((SELECT ',' + c .name
FROM cte c
WHERE c .index_name = c2 .index_name
FOR XML PATH , TYPE ).value( '.[1]', 'nvarchar(max)'), 1 , 1, '') [columns]
FROM cte c2
WHERE c2.is_included_column != 1 AND EXISTS (
SELECT 1
FROM max_ParsSearchIndex p
WHERE c2 .name = p .val AND p .cnt = c2.maxIndex_column_id
)
GROUP BY c2 .index_name, c2. maxIndex_column_id
)
SELECT index_name, [columns]
FROM cte2
WHERE cnt = maxIndex_column_id
这对我有用
DECLARE @searchIndex nvarchar(100) = 'age,name',
@schemeName nvarchar(100) = 'dbo',
@tableName nvarchar(100) = 'tableName'
SELECT
name
FROM (SELECT
indexes.name,
(SELECT
c1.name + ','
FROM sys.schemas s1
INNER JOIN sys.tables t1
ON s1.schema_id = t1.schema_id
AND tables.object_id = t1.object_id
INNER JOIN sys.columns c1
ON t1.object_id = c1.object_id
INNER JOIN sys.indexes i1
ON t1.object_id = i1.object_id
AND indexes.index_id = i1.index_id
INNER JOIN sys.index_columns ic1
ON t1.object_id = ic1.object_id
AND i1.index_id = ic1.index_id
AND c1.column_id = ic1.column_id
WHERE schemas.schema_id = s1.schema_id
ORDER BY c1.name
FOR xml PATH (''))
AS colName
FROM sys.schemas
INNER JOIN sys.tables
ON schemas.schema_id = tables.schema_id
AND tables.name = @tableName
INNER JOIN sys.indexes
ON tables.object_id = indexes.object_id
WHERE schemas.name = @schemeName) A
WHERE A.colName = @searchIndex + ','
这对我有用
DECLARE @searchIndex nvarchar(100) = 'age,name',
@schemeName nvarchar(100) = 'dbo',
@tableName nvarchar(100) = 'tableName'
SELECT
name
FROM (SELECT
indexes.name,
(SELECT
c1.name + ','
FROM sys.schemas s1
INNER JOIN sys.tables t1
ON s1.schema_id = t1.schema_id
AND tables.object_id = t1.object_id
INNER JOIN sys.columns c1
ON t1.object_id = c1.object_id
INNER JOIN sys.indexes i1
ON t1.object_id = i1.object_id
AND indexes.index_id = i1.index_id
INNER JOIN sys.index_columns ic1
ON t1.object_id = ic1.object_id
AND i1.index_id = ic1.index_id
AND c1.column_id = ic1.column_id
WHERE schemas.schema_id = s1.schema_id
ORDER BY c1.name
FOR xml PATH (''))
AS colName
FROM sys.schemas
INNER JOIN sys.tables
ON schemas.schema_id = tables.schema_id
AND tables.name = @tableName
INNER JOIN sys.indexes
ON tables.object_id = indexes.object_id
WHERE schemas.name = @schemeName) A
WHERE A.colName = @searchIndex + ','
您使用哪种RDBMS?这是什么SQL产品?与键不同,in-SQL索引几乎完全是特定于实现的,因此您必须知道您使用的是哪种类型的SQL才能编写类似的内容。对不起,这是针对Microsoft SQL server 2008-2012的,您使用的是哪种RDBMS?这是用于什么SQL产品?与键不同,in-SQL索引几乎完全是特定于实现的,因此您必须知道您使用的SQL类型才能编写类似的内容。抱歉,这是针对Microsoft SQL server 2008-2012的。谢谢,这完成了任务。我指定列名的顺序是否重要(例如,如果我指定了年龄,命名此项不返回任何内容。我想我必须按字母顺序指定列。很抱歉,您的第二个解决方案不适用于无序列,即年龄、名称。我试着通过你的第二个查询,在cte2中,它没有带来所有的索引,cnt不等于maxIndex_column_Id。我本来会粘贴一个屏幕截图,但网站阻止我这样做。如果我能提供更多信息,请告诉我。我的问题是,我的索引中包含了非键列,而我只是在查询时指定了键列,我必须添加一个额外的条件ic.key_ordinal=0以确保sql只查询键列,并且它现在工作正常。谢谢谢谢,这就完成了。我指定列名的顺序有关系吗?例如,如果我指定了年龄,命名这个将不返回任何内容。我想我必须按字母顺序指定列。很抱歉,您的第二个解决方案不适用于无序列,即年龄、名称。我试着通过你的第二个查询,在cte2中,它没有带来所有的索引,cnt不等于maxIndex_column_Id。我本来会粘贴一个屏幕截图,但网站阻止我这样做。如果我能提供更多信息,请告诉我。我的问题是,我的索引中包含了非键列,而我只是在查询时指定了键列,我必须添加一个额外的条件ic.key_ordinal=0以确保sql只查询键列,并且它现在工作正常。谢谢,我指定列名的顺序有关系吗?因为这对年龄、名称不返回任何结果。此查询按ic1.index\u column\u id对结果进行排序。因此排序很重要。这假设age、name和name、age是您可以查找的两个不同索引。是的,我想我将按字母顺序指定列名,因为上面的查询按字母顺序返回列名。再次感谢。如果列的顺序不重要,只需将顺序改为c1.name,并确保列在@searchIndex中按字母顺序排列。我指定列名的顺序是否重要,因为这不会返回任何年龄,名称此查询按ic1.index\u column\u id对结果进行排序。因此排序很重要。这假设age、name和name、age是您可以查找的两个不同索引。是的,我想我将按字母顺序指定列名,因为上面的查询按字母顺序返回列名。再次感谢。如果列的顺序不重要,只需将顺序改为c1.name,并确保列在@searchIndex中按字母顺序排列即可。