有没有办法按列名搜索所有 SQL 表?
Is there a way to search all SQL tables by column name?
在 this 答案中,您可以按列名在所有 table 中搜索列。
假设我有一个这样的列列表:
DECLARE @columnNames TABLE (Id varchar(30))
INSERT INTO @columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
我想找到至少包含这三列的所有 table。是否可以用下面的代码做一个 foreach 循环,或者有更简单的方法吗?
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name @xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName'
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME LIKE '@xColumnName'
ORDER BY
TableName, ColumnName;
table 必须在列表中列出所有 3 个列,如果我可以过滤掉没有特定列或列列表的 table,那就太好了
这应该可以实现您的初始目标。
SELECT
[TableName]
FROM (
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name @xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName',
ROW_NUMBER() OVER(PARTITION BY TABLE_NAME ORDER BY COLUMN_NAME) rn
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME IN ('xColumn1Name', 'xColumn2Name', 'xColumn3Name')
) a
WHERE rn >= 3
为了简短说明,此查询将查看信息模式以查找 table 中的任何这些列。 ROW_NUMBER() 然后基本上按 table 对列进行分组。如果有 3 个或更多结果 (rn),则所有 3 列都在那里。
因为它是一个子 select,如果需要,您还可以过滤特定列的外部 select。
这是一道关系除法题。作为 Joe Celko writes,有几种方法可以解决这个问题。常见的解决方法如下:
DECLARE @columnNames TABLE (Id varchar(30))
INSERT INTO @columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
select t.name
from sys.tables t
join sys.columns c on c.object_id = t.object_id
join @columnNames cn on cn.Id = c.name
group by t.object_id, t.name
having count(*) >=
(select count(*) from @columnNames);
这意味着:给我所有表格,其中与列表@columnName 匹配的列数与该列表中的数字相同或更多,换句话说,tehre 是每个列的匹配项。
您可以使用 INTERSECT 组合不同的结果集。这将给出所有结果集中的记录,因此在本例中,表具有所有三列。
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn1Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
在 this 答案中,您可以按列名在所有 table 中搜索列。
假设我有一个这样的列列表:
DECLARE @columnNames TABLE (Id varchar(30))
INSERT INTO @columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
我想找到至少包含这三列的所有 table。是否可以用下面的代码做一个 foreach 循环,或者有更简单的方法吗?
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name @xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName'
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME LIKE '@xColumnName'
ORDER BY
TableName, ColumnName;
table 必须在列表中列出所有 3 个列,如果我可以过滤掉没有特定列或列列表的 table,那就太好了
这应该可以实现您的初始目标。
SELECT
[TableName]
FROM (
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name @xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName',
ROW_NUMBER() OVER(PARTITION BY TABLE_NAME ORDER BY COLUMN_NAME) rn
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME IN ('xColumn1Name', 'xColumn2Name', 'xColumn3Name')
) a
WHERE rn >= 3
为了简短说明,此查询将查看信息模式以查找 table 中的任何这些列。 ROW_NUMBER() 然后基本上按 table 对列进行分组。如果有 3 个或更多结果 (rn),则所有 3 列都在那里。
因为它是一个子 select,如果需要,您还可以过滤特定列的外部 select。
这是一道关系除法题。作为 Joe Celko writes,有几种方法可以解决这个问题。常见的解决方法如下:
DECLARE @columnNames TABLE (Id varchar(30))
INSERT INTO @columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
select t.name
from sys.tables t
join sys.columns c on c.object_id = t.object_id
join @columnNames cn on cn.Id = c.name
group by t.object_id, t.name
having count(*) >=
(select count(*) from @columnNames);
这意味着:给我所有表格,其中与列表@columnName 匹配的列数与该列表中的数字相同或更多,换句话说,tehre 是每个列的匹配项。
您可以使用 INTERSECT 组合不同的结果集。这将给出所有结果集中的记录,因此在本例中,表具有所有三列。
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn1Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'