我有一个名为( 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 查询来完成整个工作吗?
所有这些都可以通过 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)