选择MySQL表的前N列

15

在MySQL数据库表中,可以选择前N行,那么是否有办法选择前N列呢?
感谢您的回复,希望能提供一些使用PHP编写的代码。


虽然这样做可能有正当理由,但暗示着您的存储模型存在问题。 - Strawberry
@strawbery,存储模型没有问题,但我有很多不同的查询需求,这是有充分理由的。 - parsaeed
2
一个合理的原因就是在编码时从mysql提示符中浏览表格(这就是我来到这个页面的方式)。 - felwithe
@michael,回到2013年的时候,我可能会在意。但我可以向你保证,现在我已经不在意了。 - Strawberry
3个回答

17
请先查看Bill Karwin的回答。但如果您知道如何对列名进行排序,则可以使用动态查询来解决问题。
要从表中选择所有列名,可以使用以下查询:
SELECT `column_name` 
FROM   `information_schema`.`columns` 
WHERE  `table_schema`=DATABASE() 
       AND `table_name`='yourtablename';

(请查看此答案)。并利用GROUP_CONCAT函数:

GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name)
我们可以将所有列名放在一行中返回,并以逗号分隔:
`col1`, `col2`, `col3`, ...

(我还在列名周围添加了引号,请注意我们必须以某种方式对列名列表进行排序,否则无法保证返回的列名顺序。)

然后,我们可以使用SUBSTRING_INDEX函数来截取返回的字符串,以获取前两个列名为例:

SUBSTRING_INDEX(columns, ',', 2)

我们的最终查询,将'SELECT '、上述选择的列和' FROM Tab1'连接起来,并将结果字符串插入到@sql变量中的查询如下:

SELECT
  CONCAT(
    'SELECT ',
    SUBSTRING_INDEX(
      GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name),
      ',',
      2),
    ' FROM Tab1'
  )
FROM
  information_schema.columns 
WHERE
  table_schema=DATABASE() 
  AND table_name='Tab1'
INTO @sql;

它的值将会是类似于这样:

@sql = "SELECT `col1`, `col2` FROM Tab1"

然后您可以准备您的语句并执行:

PREPARE stmt FROM @sql;
EXECUTE stmt;
请查看这里的fiddle:here

很好的完整回答。非常感谢。我认为如果您在回答中添加更多信息并将此fiddle的表格视图添加到您的回答中,并在代码行上添加一些有用的注释,它将成为一个不错的维基回答。 - parsaeed
1
@parsaeed 谢谢!你说得对,我编辑并添加了更多信息到我的回答中,希望一切都清楚明白!谢谢。 - fthiella
干得好!现在就像是一个不错的学习课程。非常感谢fthiella。 - osyan
2
对于一般情况下,如果列不是按字母顺序排列,但仍希望获取前N列:将ORDER BY column_name更改为ORDER BY ordinal_position - Annabel

16

SQL需要你命名你想要的列,否则使用*通配符。

在关系理论中,没有“前N列”的概念,因为列没有隐含的顺序。当然,在任何具体的SQL实现中,它们必须有一些存储顺序,但是SQL语言不支持按表中的“位置”获取列,也没有获取一系列列的支持(除了*)。


话说,你当然可以使用 PHP 来人为地实现这一点,通过按某种排序约定来命名列。但是 SQL 不能做到这一点。 - Joost
1
感谢Bill提供的完整信息,它对我很有帮助,我投了赞成票。但是fthiella和Erik的答案更有帮助,因为他们向我和所有后来访问这个问题的人分享了代码。 - parsaeed
1
在关系理论中,没有“前N列”的概念,因为列没有隐含的顺序。是的,就是这样。 - BClaydon

1

你不能直接在MySQL中完成此操作,必须在服务器端完成。在PHP中,代码可能如下所示:

<?php
$mysqli->real_query("SELECT id, title, name FROM test ORDER BY id ASC");
$res = $mysqli->use_result();

$numberOfColumnsToShow = 2;

while ($row = $res->fetch_assoc()) {
    // Only select the first $numberOfColumnsToShow columns
    $rowWithSpecifiedNumberOfColumns = array_slice($row, 0, $numberOfColumnsToShow);

    // $rowWithSpecifiedNumberOfColumns only contains the first two columns (id, title)
}
?>

我应该尝试一下。我认为这可能会被接受为答案,但让我先试试看是否有更好的答案出现 :) 只有一个问题。你会用于大型数据库吗?这会导致速度问题吗? - parsaeed
1
@parsaeed 这取决于你的数据库有多大。事实是,MySQL需要返回所有列,包括你不会显示的列。它是否会成为性能问题还有待观察,为此你应该进行一些性能基准测试。 - Erik Schierboom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接