2014-02-22 112 views
0

下面的查询给我一个错误:是否可以在MySQL中做这样的子查询?

select 
    case 
    when exists (select username from table_name) 
     then concat('_username_', table_name) 
    else table_name 
    end 
from information_schema.tables 
where table_schema = 'test' 

我基本上要返回_username_(the table name)如果表中包含一个名为“用户名”栏。

我知道还有另一种方法可以通过选择information_schema.columns来做到这一点,但我已经像上面那样做了(如果可能的话)。

编辑:我想我的查询获取数据库测试中的所有表。如果表有列用户名,那么我希望它返回_username_(followed by table name),否则返回表名

+0

更改您希望能够从查询中完成的问题。 – Layke

+0

@Strawberry为什么复制?这里提出的问题与您提供的链接中提出的问题不同。 –

回答

2

是的。 LEFT JOIN到columns

select 
    case when column_name is null then t.table_name 
     else concat('_username_', t.table_name) end 
from information_schema.tables t 
left join information_schema.columns c on c.table_name = t.table_name 
    and c.table_schema = t.table_schema 
    and column_name = 'user-name' 
where t.table_schema = 'test' 

这里的要点是:

  • 所有在列的条件必须是参加子句中,所以左联接是允许的。注意,在一个连接条件中“非关键”条件是可以的 - 这个功夫是值得记住的,因为这是你可以使用非关键条件的左连接的唯一方式(如果你把它们放在where子句中它变成一个内部联接)
  • 由于表内的列名是唯一的,因此将会有一行或无行加入。如果没有加入,加入的列将是空的 - 那正是在case

被测试的最后,顺便说一句,这将是更好的命名列没有破折号,即usernameuser-name,否则你每次使用它都必须逃脱它。

+0

我不明白'LEFT JOIN'的原因。是否有一个表的列名被标记为NULL的情况? –

+0

谢谢,正是我所需要的。我相信如果“AND column_name ='username'”列名没有用户名 – Jason

+0

@AlbertoSolano否 - 列名永远不为空,但如果列不存在*连接行*将会有每列中都为空。看到注释添加到回答 – Bohemian

1

如果不加入表INFORMATION_SCHEMA.COLUMNS,则无法知道每个表的列。 试试这个问题:

SELECT 
CASE 
WHEN C.COLUMN_NAME = 'username' THEN CONCAT('_username_',C.TABLE_NAME) ELSE C.COLUMN_NAME END 
FROM INFORMATION_SCHEMA.TABLES T 
JOIN INFORMATION_SCHEMA.COLUMNS C ON T.TABLE_NAME = C.TABLE_NAME AND T.TABLE_SCHEMA = C.TABLE_SCHEMA 
WHERE T.TABLE_SCHEMA = 'test'; 
+0

-1这实际上会为每个表中的每个*列*赋予一行,但是OP希望每个表*有一行*。 – Bohemian

+0

@波希米亚在哪里写'每桌一行'?他只是写道:'我想让我的查询获得数据库测试中的所有表格。'然后'我希望它返回_username_(后跟表名)否则返回表名'。 –

+0

很明显,他希望每张表有一行,否则列名肯定会出现在输出 – Bohemian