在SQL中统计出现次数

4
我有一个具有以下结构的表格:
(table_name, column_name) 

对于表中的每一行,我需要查询表名中的列名,并对其中的值进行 COUNT(column_name) GROUP BY column_name
目前我执行的操作是:
SELECT * FROM this table 
/*and then*/ foreach row: do another query with: 
  SELECT column_name, COUNT(column_name) GROUP BY column_name

有没有一种方法可以在一个查询中完成这个操作?
类似于

SELECT column_name, COUNT(column_name) 
GROUP BY column_name 
FOREACH(SELECT table_name, column_name FROM my_initial_table)

我知道最后一个查询无效,这只是一个示例,说明我希望实现的目标(如果可能的话)。
LE:
告诉我在哪里查找的表有两个varchar列。
例如:
|++++++++++++++++++++++++++++++++
| table_name | column_name      |
|+++++++++++++++++++++++++++++++|
| logsa      | foo              |
|===============================|
| logsa      | bar              |
|===============================|
| testx      | baz              |
|===============================|

这告诉我现在需要查看表logsa的列foobar,以及表testx的列baz。每个表中的每一列都具有VARCHAR数据类型,我只需要计算相同的那些列。这就是我所做的事情。
SELECT column_name, COUNT(column_name) 
    GROUP BY column_name

2
有特定的数据库吗? - DOK
2
另外,你能提供表模式吗?因为现在不是很清楚你需要什么 - 这可能会有所帮助。 - Will A
4个回答

2

如果你在使用MySql,你不能直接使用参数化的列名。有一种间接的方法是使用存储过程和预处理语句。

以下是一些草率的初稿代码... 注意反引号 ` 和引号 ' 之间的区别。

  CREATE PROCEDURE CountTables()
  BEGIN
      DECLARE done TINYINT DEFAULT 0;
      DECLARE table_name varchar(30), colunn_name varchar(30);
      DECLARE cur1 CURSOR FOR SELECT
          table_name, column_name
       FROM ColumnTable;

      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
      CREATE TEMPORARY TABLE t1( table_name varchar(30), column_name varchar(30), count int);

      OPEN cur1;
      START TRANSACTION;

    read_loop: LOOP
        FETCH FROM cur1 INTO table_name, column_name;
        IF done THEN LEAVE read_loop; END IF;

        SET insert_sql = CONCAT(  "INSERT INTO `t1`(`table_name`, `column_name`, `count`) SELECT ",
                                   "'", table_name, "', '", column_name, "', count(`", column_name, "`)",
                                  " FROM `",    table_name, "`"  
                               );

        PREPARE insert_stmt FROM insert_sql;
        EXECUTE insert_stmt;
        DEALLOCATE PREPARE insert_stmt;

      END LOOP;
      COMMIT;
      SELECT * FROM t1 GROUP BY column_name;
      DROP TEMPORARY TABLE t1;

    END;

哦,别忘了调用这个过程:

CALL CountTables();

0
一个子查询应该能帮到你。这是一个例子(未经测试),在一些改进后应该能正常工作。为了我的示例,我将称你的表为Schema,在子查询中,我将给它取个别名ColumnCount,以使代码(希望)更易读。
SELECT Schema.table_name, Schema.column_name, 
  (SELECT COUNT(*) FROM Schema ColumnCount 
  WHERE Schema.column_name = ColumnCount.column_name) AS ColumnUsageCount
FROM Schema

0

如果只涉及一个表,就不需要进行子查询,只需执行以下操作。

SELECT max(table_name) as table_name, column_name, COUNT(*) as occurrence
FROM initial_table
GROUP BY column_name 
ORDER BY column_name

Max(table_name)可以替代不存在的Whatever(table_name)函数。在MySQL中,您还可以使用group_concat(table_name) as table_names。试一试!

ORDER BY是可选的(在MySQL中不需要),但如果您想按列名排序,它可能很方便。

如果您想列出组合table_name + column_name的唯一发生情况,请执行以下操作:

SELECT table_name, column_name, COUNT(*) as occurrence
FROM initial_table
GROUP BY table_name, column_name 
ORDER BY table_name, column_name

如果他不想要返回“table_name”列,那么这个方法是可行的 - 在这种情况下,必须将其添加到GROUP BY子句中,并且这将返回每个表中出现的次数,而不是整个数据集。 - Bork Blatt
@Bork,已修复答案以包括两个选项。 - Johan
我不需要在初始表上进行计数。初始表只是给了我一个需要循环遍历的表和列的列表,最终得到它们的出现次数。 - daniels
更好的做法是,如果相同的列名在多个表中使用,将仅返回一个行,其中包含按字母顺序排列的最后一张表,而不是每个表中每个出现的行。这样不会重复用户通过从表中执行“SELECT *”,然后执行单独的查询以获取列名的总使用计数所得到的结果。 - Bork Blatt

-1

使用PHP

$result=mysql_query("SELECT column_name FROM $table_name");
$row_count = mysql_num_rows($result);

我对mysql不是很熟悉,但我认为它差不多就是这样


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