【问题标题】:Select top N with All related tables选择所有相关表的前 N ​​个
【发布时间】:2012-07-03 15:16:06
【问题描述】:

我有一个名为“用户”的表

Users 表有 UserId 作为主键,它是其他 15 个表的外键。

是否有一个查询模板可以一次性从用户和所有相关表中选择前 200 行?所以我不需要在查询中输入所有其他 15 个表。

Query 是否会动态地从相关表中查找和提取列?

它可以对表之间的所有关系使用内连接。

【问题讨论】:

  • 我们能举个例子吗? 1 位用户知道应该从相关表中获取哪些列
  • 我有像用户、用户图片、用户消息、用户地址等表......我会有一个查询,比如“从用户内部连接中选择前 200 个 * 相关表,其中用户 ID = 1”,但在“所有相关表”部分会动态出现。不手动输入。
  • 您使用的是什么数据库?这很可能需要不同数据库的系统表。

标签: sql foreign-keys relational-database


【解决方案1】:

我承认这非常丑陋,可能需要做更多的工作,但它会根据 PK/FK 关系生成基本查询。如果任何 FK 表可能缺少相应的 PK 记录,您可能应该将内连接更改为左连接。

declare @table varchar(50);
set @table = 'Users';

declare @pk_table varchar(50);
declare @fk_table varchar(50);
declare @pk_column varchar(50);
declare @fk_column varchar(50);
declare @curr_table varchar(50);
set @curr_table = '';

declare @sql varchar(8000);
set @sql = 'select top 200 * from ' + @table + char(10)
DECLARE table_cursor CURSOR FOR 
SELECT
    K_Table = FK.TABLE_NAME,
    FK_Column = CU.COLUMN_NAME,
    PK_Table = PK.TABLE_NAME,
    PK_Column = PT.COLUMN_NAME--,
    --Constraint_Name = C.CONSTRAINT_NAME
FROM
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
            SELECT
                i1.TABLE_NAME,
                i2.COLUMN_NAME
            FROM
                INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
            INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
                ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
            WHERE
                i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
           ) PT
    ON PT.TABLE_NAME = PK.TABLE_NAME
where PK.TABLE_NAME = @table   

OPEN table_cursor
FETCH NEXT FROM table_cursor INTO @fk_table, @fk_column, @pk_table, @pk_column

WHILE @@FETCH_STATUS = 0
BEGIN
    if @curr_table <> @fk_table
    begin
        -- create join
        set @sql = @sql + ' inner join ' + @fk_table + char(10)
        set @sql = @sql + ' on ' + @pk_table + '.' + @pk_column + ' = ' + @fk_table + '.' + @fk_column + char(10)
    end
    else
    begin
        -- create join on fields
        set @sql = @sql + ' and ' + @pk_table + '.' + @pk_column + ' = ' + @fk_table + '.' + @fk_column + char(10)
    end
FETCH NEXT FROM table_cursor INTO @fk_table, @fk_column, @pk_table, @pk_column
END

CLOSE table_cursor
DEALLOCATE table_cursor

print @sql

【讨论】:

    【解决方案2】:

    你可以这样做:

    select top 200 columns....
    from tablename
    inner join table1 ....
    inner join table2 ....
    ...
    inner join table15...
    

    您需要为所有表格创建inner join,然后选择top 200 结果。

    【讨论】:

    • 谢谢。但正如我所说,我希望查询会动态地从相关表中找到并带来列。
    • @Teomanshipahi shipahi 你这是什么意思?我在你的问题中看不到这一点
    • @Teomanshipahi 你没有在任何地方这么说,也许只是在你的脑海里:P
    【解决方案3】:

    This 是您正在寻找的。动态Where 声明。跳到Case statements 了解如何在查询中使用案例。

    【讨论】:

      【解决方案4】:

      有一种方法,但它有点复杂。 您可以从 information_schema 中选择所有表名和表列,并使用它们构建 SQL 查询。

      这样的事情应该可以帮助您入门:

      With TableNames
      AS
      (
      select * from INFORMATION_SCHEMA.TABLES where  table_name like 'User%'
      ),
      ColumnNames 
      AS
      (
      select * 
      from INFORMATION_SCHEMA.COLUMNS c
      join TableNames n
      on n.TABLE_NAME=c.TABLE_NAME
      )
      /* Construct SQL query */
      

      您可以执行“exec 'SELECT' + Columns + ' FROM ' + TableName + 'WHERE...'” 然后对每个表执行查询。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-14
        • 2017-08-29
        • 1970-01-01
        • 2021-01-01
        • 1970-01-01
        • 2011-03-22
        • 1970-01-01
        相关资源
        最近更新 更多