如何对动态表列表执行查询?

1 mysql php select

我有一个名为( conntrack )的数据库,其中包含未知数量的表。我有一个静态表“tabidx”,其中有一列“日期”。

下表是静态的,其名称为 tabidx,提供对其他表的引用:

 tabidx (table):
 +------------+
 |    date    |
 +------------+
 | 2015-04-25 |
 | 2015-04-26 |
 | 2015-04-27 |
 | 2015-04-28 |
 | 2015-04-29 |
 +------------+
Run Code Online (Sandbox Code Playgroud)

以下是“tabidx”“date”中引用的表的示例:

2015-04-25 (table):                             
+---------------------------------------------+    
| time      | username | srcip      | scport  |    
+---------------------------------------------+    
| 19:20:00  | L001000  | 10.10.10.1 |  1304   |   
| 19:20:00  | L001001  | 10.10.10.2 |  1640   |    
| 19:20:01  | L001002  | 10.10.10.3 |  2001   |    
+---------------------------------------------+ 

2015-04-26 (table):                             
+---------------------------------------------+    
| time      | username | srcip      | scport  |    
+---------------------------------------------+    
| 19:21:00  | L001000  | 10.10.10.1 |  1304   |   
| 19:21:00  | L001001  | 10.10.10.2 |  1640   |    
| 19:21:01  | L001002  | 10.10.10.3 |  2001   |    
+---------------------------------------------+ 
Run Code Online (Sandbox Code Playgroud)

我想向经理列出 tabidx 中存在的可用表,并计算所有表中我们有多少用户(如果在 tabidx 中引用了这些用户)。因此,如果经理要求:

$_GET['fromdate'] = '2015-05-25'  
$_GET['todate'] = date(); //till today date 2015-04-30
$_GET['username'];
$_GET['srcport'];
$_GET['srcip'];
Run Code Online (Sandbox Code Playgroud)

我希望输出根据上面的要求匹配 mysql 行。例如:

OUTPUT: [available tables WHERE username=L00100]
+-------------------------------------------+    
| Date and Time | username | srcip | scport |     
+-------------------------------------------+    
|   2015-04-25  | L001000  |   %   |   %    |   
|   2015-04-26  | L001000  |   %   |   %    |    
|   2015-04-27  | L001000  |   %   |   %    |    
+-------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

我如何列出或选择 tabidx 中找到的所有表格?我不知道如何在 mysql 中使用准备好的语句。

我知道第一步应该列出可用的表格。如果有人想要请求具有特定用户(例如“L002000”)的可用表,那么我们根本不应该列出这些表,因为我们的动态表没有此用户名。

$db = new dB();

$_GET['fromdate'] = ( isset($_GET['fromdate']) && isValideDate($_GET['fromdate']) ) ?       $_GET['fromdate'] : $todayDate;
$_GET['todate'] = ( isset($_GET['todate']) && isValideDate($_GET['todate']) ) ?  $_GET['todate'] : $todayDate;
$sql_fromdate = " date >= '{$_GET['fromdate']}' AND";
$sql_todate = " date >= '{$_GET['todate']}'";

$result = $db -> query("SELECT date FROM tabidx WHERE $sql_fromdate $sql_todate");
$_GET['username'] = ( isset($_GET['username']) && $_GET['username'] !='' ) ?                           ....$_GET['username'] : '';


if($result)
{
    // Loop through the available tables that are included in table 'tabidx' 

    while( $b_row = $result -> fetch_assoc() )
    {
        $table_name = $db_row['date'];

        // Query the table and count the number of rows according to the requested $_GET Method

        $result2 = $b -> query("SELECT count(*) FROM $table_name WHERE username LIKE '{$_GET['username']}%'");
        $num_row = $result2 -> fetch_row();

        // Check if the number of rows are greater than zero
        // then show the row of $result to the user

        if($num_row[0] > 0)
        {
            echo '<tr>';
            echo '<td>$table_name</td>';
            echo "<td>{$_GET['username']}</td>";
            echo '<td></td>';
            echo '<td></td>';
            echo '</tr>';
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我已经成功地制定了一个临时解决方案,但我知道这个解决方案非常糟糕,而且我不是创建这个结构的人。一年内我们的餐桌数量可能会达到 360 张。

我们可以使用一个 mysql 查询来完成整个工作吗?

Rol*_*DBA 6

所有这些都可以通过 INFORMATION_SCHEMA 数据库来完成

表名位于 INFORMATION_SCHEMA 中

SELECT table_name FROM information_schema.tables
WHERE table_schema='conntrack';
Run Code Online (Sandbox Code Playgroud)

tabidx然后,您可以将存在的表与该表对齐

SELECT B.table_name FROM (SELECT date FROM tabidx) A
INNER JOIN (SELECT table_name FROM information_schema.tables
WHERE table_schema='conntrack') B ON A.date = B.table_name;
Run Code Online (Sandbox Code Playgroud)

使用这些表名,对所有表设置一个长查询conntrack

提出的查询

SET @fromdate = '2015-04-25';
SET @todate = CURRENT_DATE();
SET @given_username='L001000';
SELECT
    GROUP_CONCAT(qry SEPARATOR ' UNION ')
    INTO @sql
FROM
(
    SELECT CONCAT('SELECT ',QUOTE(table_name),' as "Date and Time"',
    ',username,''%'' srcip,''%'' scport FROM `',table_name,
    '` WHERE username=',QUOTE(@given_username)) qry
    FROM
    (
        SELECT BB.table_name FROM
        (
            SELECT date FROM tabidx
            WHERE date>=@fromdate AND date<=@todate
        ) AA
        INNER JOIN
        (
            SELECT table_name FROM information_schema.tables
            WHERE table_schema='conntrack'
        ) BB ON AA.date = BB.table_name
    ) A
) B;
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
Run Code Online (Sandbox Code Playgroud)

样本数据(来自您的问题)

DROP DATABASE IF EXISTS conntrack_sample;
CREATE DATABASE conntrack_sample;
USE conntrack_s
CREATE TABLE tabidx (date date, PRIMARY KEY (date));
INSERT INTO tabidx VALUES 
('2015-04-25'),('2015-04-26'),('2015-04-27'),
('2015-04-28'),('2015-04-29');
SELECT * FROM tabidx;
CREATE TABLE `0000-00-00`
(
    time time,username CHAR(7),
    srcip CHAR(15),scport INT,
    PRIMARY KEY (username,time)
);
CREATE TABLE `2015-04-25` LIKE `0000-00-00`;
CREATE TABLE `2015-04-26` LIKE `0000-00-00`;
CREATE TABLE `2015-04-27` LIKE `0000-00-00`;
CREATE TABLE `2015-04-28` LIKE `0000-00-00`;
CREATE TABLE `2015-04-29` LIKE `0000-00-00`;
INSERT INTO `2015-04-25` VALUES
('19:20:00','L001000','10.10.10.1',1304),
('19:20:00','L001001','10.10.10.2',1640),
('19:20:01','L001002','10.10.10.3',2001);
INSERT INTO `2015-04-26` VALUES
('19:21:00','L001000','10.10.10.1',1304),
('19:21:00','L001001','10.10.10.2',1640),
('19:21:01','L001002','10.10.10.3',2001);
Run Code Online (Sandbox Code Playgroud)

样本数据已加载

mysql> DROP DATABASE IF EXISTS conntrack_sample;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE DATABASE conntrack_sample;
Query OK, 1 row affected (0.00 sec)

mysql> USE conntrack_sample
Database changed
mysql> CREATE TABLE tabidx (date date, PRIMARY KEY (date));
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO tabidx VALUES
    -> ('2015-04-25'),('2015-04-26'),('2015-04-27'),
    -> ('2015-04-28'),('2015-04-29');
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM tabidx;
+------------+
| date       |
+------------+
| 2015-04-25 |
| 2015-04-26 |
| 2015-04-27 |
| 2015-04-28 |
| 2015-04-29 |
+------------+
5 rows in set (0.00 sec)

mysql> CREATE TABLE `0000-00-00`
    -> (
    ->     time time,username CHAR(7),
    ->     srcip CHAR(15),scport INT,
    ->     PRIMARY KEY (username,time)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> CREATE TABLE `2015-04-25` LIKE `0000-00-00`;
Query OK, 0 rows affected (0.05 sec)

mysql> CREATE TABLE `2015-04-26` LIKE `0000-00-00`;
Query OK, 0 rows affected (0.02 sec)

mysql> CREATE TABLE `2015-04-27` LIKE `0000-00-00`;
Query OK, 0 rows affected (0.02 sec)

mysql> CREATE TABLE `2015-04-28` LIKE `0000-00-00`;
Query OK, 0 rows affected (0.05 sec)

mysql> CREATE TABLE `2015-04-29` LIKE `0000-00-00`;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO `2015-04-25` VALUES
    -> ('19:20:00','L001000','10.10.10.1',1304),
    -> ('19:20:00','L001001','10.10.10.2',1640),
    -> ('19:20:01','L001002','10.10.10.3',2001);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> INSERT INTO `2015-04-26` VALUES
    -> ('19:21:00','L001000','10.10.10.1',1304),
    -> ('19:21:00','L001001','10.10.10.2',1640),
    -> ('19:21:01','L001002','10.10.10.3',2001);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql>
Run Code Online (Sandbox Code Playgroud)

已执行建议的查询

mysql> SET @fromdate = '2015-04-25';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @todate = CURRENT_DATE();
Query OK, 0 rows affected (0.02 sec)

mysql> SET @given_username='L001000';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT
    ->     GROUP_CONCAT(qry SEPARATOR ' UNION ')
    ->     INTO @sql
    -> FROM
    -> (
    ->     SELECT CONCAT('SELECT ',QUOTE(table_name),' as "Date and Time"',
    ->     ',username,''%'' srcip,''%'' scport FROM `',table_name,
    ->     '` WHERE username=',QUOTE(@given_username)) qry
    ->     FROM
    ->     (
    ->         SELECT BB.table_name FROM
    ->         (
    ->             SELECT date FROM tabidx
    ->             WHERE date>=@fromdate AND date<=@todate
    ->         ) AA
    ->         INNER JOIN
    ->         (
    ->             SELECT table_name FROM information_schema.tables
    ->             WHERE table_schema='conntrack_sample'
    ->         ) BB ON AA.date = BB.table_name
    ->     ) A
    -> ) B;
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql>
Run Code Online (Sandbox Code Playgroud)

建议的查询输出

mysql> PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

+---------------+----------+-------+--------+
| Date and Time | username | srcip | scport |
+---------------+----------+-------+--------+
| 2015-04-25    | L001000  | %     | %      |
| 2015-04-26    | L001000  | %     | %      |
+---------------+----------+-------+--------+
2 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql>
Run Code Online (Sandbox Code Playgroud)

试一试 !!!

注意:这是@sql 的内容

mysql> SELECT @sql\G
*************************** 1. row ***************************
@sql: SELECT '2015-04-25' as "Date and Time",username,'%' srcip,'%' scport FROM `2015-04-25` WHERE username='L001000' UNION SELECT '2015-04-26' as "Date and Time",username,'%' srcip,'%' scport FROM `2015-04-26` WHERE username='L001000' UNION SELECT '2015-04-27' as "Date and Time",username,'%' srcip,'%' scport FROM `2015-04-27` WHERE username='L001000' UNION SELECT '2015-04-28' as "Date and Time",username,'%' srcip,'%' scport FROM `2015-04-28` WHERE username='L001000' UNION SELECT '2015-04-29' as "Date and Time",username,'%' srcip,'%' scport FROM `2015-04-29` WHERE username='L001000'
1 row in set (0.00 sec)

mysql>
Run Code Online (Sandbox Code Playgroud)