【问题标题】:How to select data from multiple tables where table name is value from a column of another table?如何从多个表中选择数据,其中表名是另一个表的列的值?
【发布时间】:2016-03-18 01:55:01
【问题描述】:

我有一个表由表名组成,例如:

表A

    UID  TableName  CifKey  ...
    1     xxx       12345
    1     yyy       12345
    1     xxx       12345
    2     zzz       45678

如何从与表 A 中的TableName 列名称相同的表中选择数据?

例如:

SELECT A.a, B.b 
FROM TableA A 
JOIN ' + @TableName + ' B ON A.Cifkey = B.Cifkey 
WHERE A.uid = @uid AND A.cifkey = @cifkey

谢谢!

【问题讨论】:

  • 如果uid = 1Cifkey = 12345,TableName 是什么?
  • 表名将是 xxx 和 yyy,谢谢!
  • A表的主键是什么?
  • 您的表格信息细节有缺陷,当 uid=1 和 cifkey=12345 时,您无法将两个同名的表格传递给,我也没有看到任何原因

标签: sql sql-server


【解决方案1】:

动态 SQL 是要走的路:

DECLARE @uid    INT = 1,
        @cifkey INT = 12345

DECLARE @sql NVARCHAR(MAX) = ''

SELECT @sql = @sql +
'SELECT
    A.a, B.b -- Replace with correct column names
FROM TableA A
JOIN ' + QUOTENAME(TableName) + ' B
    ON A.Cifkey = B.Cifkey
WHERE
    A.uid = @uid 
    AND A.cifkey = @cifkey
UNION ALL
'
FROM (
    SELECT DISTINCT TableName FROM TableA WHERE UID = @uid AND cifkey = @cifkey
) t

IF @sql <> '' BEGIN
    -- Remove the last UNION ALL
    SELECT @sql = LEFT(@sql, LEN(@sql) - 11)

    PRINT @sql

    EXEC sp_executesql
        @sql,
        N'@uid INT, @cifkey INT',
        @uid,
        @cifkey
END

【讨论】:

  • 这就是我想要的解决方案!太感谢了!谢谢大家:)
  • 当动态 SQL 是唯一的解决方案时,您经常会遇到数据库建模问题
  • 一般情况下,但并非总是如此。动态 SQL 有它的用途,一个包罗万象的查询。
  • 非常正确。完全同意@Nick.McDermaid
【解决方案2】:

您将不得不使用动态查询 - 像这样

DECLARE @tablename VARCHAR(50)
DECLARE @uid INT = 1
DECLARE @cifkey INT = 12345
SELECT @tablename = TableName FROM TableA WHERE uid = @uid AND cifkey = @cifkey

DECLARE @query VARCHAR(500)

SELECT @query = 'select A.a, B.b from TableA A JOIN ' + @tablename + ' B 
ON A.Cifkey = B.Cifkey 
WHERE A.uid = ' + CONVERT(VARCHAR(20),@uid) + ' and A.cifkey = ' + CONVERT(VARCHAR(20), @cifkey)

EXEC(@query)

【讨论】:

  • 嗨,SELECT @tablename = TableName FROM TableA WHERE uid = @uid AND cifkey = @cifkey 这样我只能得到表 xxx,不能得到表 yyy。谢谢!
【解决方案3】:

如果你的连接有效,动态 sql 就是你想要完成任务的方式..

declare @tablename nvarchar(100)
select @tablename=tablename from yourtable where uid=@uid and cifkey=@cifkey

declare @sqlquery nvarchar(4000)
set @sqlquery='SELECT A.a, B.b FROM TableA A 
JOIN ' + @TableName + ' B 
ON A.Cifkey = B.Cifkey 
WHERE A.uid = @uid and A.cifkey = @cifkey';

exec sp_executesql @sqlquery,
N'@uid int,@cifkey int',
@uid=10,@cifkey=100

【讨论】:

  • 你好,但它会是多个表,例如@uid = 1@cifkey = 12345,那么我需要从表xxx和表yyy中选择数据。
  • 嗨,select @tablename=tablename from yourtable where uid=@uid and cifkey=@cifkey 这样我只能得到表 xxx,不能得到表 yyy。谢谢!
【解决方案4】:

简而言之,不,不是你问的那样。但是,您可以像 this answer 那样使用动态 SQL 来创建一系列 SELECT 语句,这些语句可以与 UNIONs 合并以产生您想要的结果,如下所示:

SELECT DISTINCT 'SELECT A.a, B.b FROM TableA A 
        JOIN ' + TableName + ' B 
        ON A.Cifkey = B.Cifkey 
        WHERE A.uid = @uid and A.cifkey = @cifkey
        UNION
        '
FROM TableA

只需将结果复制到 SQL 编辑器中,从最后一项中删除 UNION,然后运行整个程序即可获得结果。

【讨论】:

    【解决方案5】:

    我不得不说……这有点疯狂

    注意:我在 TableA 中添加了一个 ID 列作为主键。这是唯一标识行以区分具有相同 UID 和 Cifkey 的多行所必需的

    -- Create the table
    create table TableA
    (
        ID      int identity,
        UID     int,
        TableName   varchar(5),
        CifKey      int,
        a       int
    )
    
    create table xxx
    (
        CifKey      int,
        b       int
    )
    
    create table yyy
    (
        CifKey      int,
        b       int
    )
    
    create table zzz
    (
        CifKey      int,
        b       int
    )
    
    set nocount on
    
    -- Insert some sample data
    insert into TableA select 1, 'xxx', 12345, 1
    insert into TableA select 1, 'yyy', 12345, 2
    insert into TableA select 1, 'xxx', 12345, 3
    insert into TableA select 2, 'zzz', 45678, 4
    
    insert into xxx select 12345, 100
    insert into yyy select 12345, 200
    insert into zzz select 45678, 300
    
    -- the Dynamic SQL query
    declare @sql    nvarchar(max)
    
    select  @sql    = N'SELECT A.a, b = COALESCE('
    
    select  @sql    = @sql +
            + N'B' + convert(varchar(10), ID) + '.b,'
    from    TableA
    order by ID
    
    select  @sql    = left(@sql, LEN(@sql) - 1) + ')' + char(13)
    
    select  @sql    = @sql 
            + N'FROM TableA A'  + char(13)
    
    ; with cte as
    (
        select  *, rn = convert(varchar(10), ID)
        from    TableA
    )
    select  @sql    = @sql 
            + N'LEFT JOIN ' + quotename(TableName) + ' AS B' + rn + ' ' + char(13)
            + N'ON  A.CifKey    = B' + rn + '.CifKey' + char(13)
            + N'AND A.ID        = ' + rn + char(13)
    from    cte
    
    print   @sql 
    exec    sp_executesql @sql
    
    set nocount off
    
    -- clean up 
    drop table TableA
    drop table xxx
    drop table yyy
    drop table zzz
    
    -- The generated Query (print @sql)
    SELECT A.a, b = COALESCE(B1.b,B2.b,B3.b,B4.b)
    FROM TableA A
    LEFT JOIN [xxx] AS B1 
    ON  A.CifKey    = B1.CifKey
    AND A.ID        = 1
    LEFT JOIN [yyy] AS B2 
    ON  A.CifKey    = B2.CifKey
    AND A.ID        = 2
    LEFT JOIN [xxx] AS B3 
    ON  A.CifKey    = B3.CifKey
    AND A.ID        = 3
    LEFT JOIN [zzz] AS B4 
    ON  A.CifKey    = B4.CifKey
    AND A.ID        = 4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      相关资源
      最近更新 更多