首页 > 解决方案 > mysql - 在同一查询中使用 UNION ALL 和 count() 进行多项选择

问题描述

我有一个像这样形成的数据库表:

ID | pairname | timeframe | value1 | value2 | value3

我有大约 290 个配对名称和 4 个时间范围,每个时间范围我将有 250 行。

表如下所示:

1 | appusd | 1h | 12319 | 129312 | 11111 | 11111
2 | appusd | 1h | 12444 | 123912 | 11221 | 111231
3 | appusd | 4h | 12312 | 123123 | 11111 | 12321
4 | gttusd | 1h | 12342 | 123123 | 11111 | 12321
5 | gttusd | 4h | 12342 | 123123 | 11111 | 12321

我运行一个 PHP 脚本,它将首先用值填充数据库,然后每小时检查一次值是否处于当前状态。

在 PHP 中,我首先循环以从另一个表中获取我需要的所有对名称。在这个循环内部,我循环通过 4 个不同的时间范围来创建这个 SELECT:

(
SELECT value1, timeframe
FROM db1
WHERE pairname = 'blabla'
AND timeframe = '1h'
ORDER BY value1 DESC
LIMIT 2
)
UNION ALL (

SELECT value1, timeframe
FROM db1
WHERE pairname = 'blabla'
AND timeframe = '4h'
ORDER BY value1 DESC
LIMIT 2
)
UNION ALL (

SELECT value1, timeframe
FROM db1
WHERE pairname = 'blabla'
AND timeframe = '8h'
ORDER BY value1 DESC
LIMIT 2
)
UNION ALL (

SELECT value1, timeframe
FROM db1
WHERE pairname = 'blabla'
AND timeframe = '2h'
ORDER BY value1 DESC
LIMIT 2
)

它工作得很好。但是因为我有 290 个循环之外的查询,所以需要一些时间。(所有其他脚本部分大约需要 9 秒,没关系。)

现在我不仅想要每个配对名称/时间范围的最后 2 个条目,而且还要计算我有多少条目,我需要计算每个配对名称/时间范围的每一行。

(
SELECT COUNT( * ) AS rawnr
FROM db1
WHERE pairname = 'blabla'
AND timeframe = '1h'
)
UNION ALL (
...
)

现在我还有 290 个查询。脚本时间加倍。它越来越慢。如果我的 SELECT 中有这个 UNION ALL,是否可以同时计数()和选择?

我已经尝试过了,但它不起作用,可能是因为同一选择中的“限制 2”?我还尝试将所有 count() 合并到一个新的选择中,但这也不起作用,因为 UNION 想要相同数量的列。

我的解决方案适用于大约 17 秒的脚本时间。在此之后,我必须检查每个结果是否是最新的,从另一台服务器中提取新数据,然后删除/添加新条目。这肯定会超过我的脚本时间,我必须找到一个解决方案来在一定数量的pairname/timeframe 编辑之后刷新脚本。(如果您知道如何在某个时间点重新加载 php 脚本,那也可以!)

编辑以查看其他表和脚本:pairname 由 2 个名称组合而成。第一个可以是“app”,第二个可以是“usd”。

第一个表的名称形成如下:

nameID | name | active | value1 | value2 | value3

第二个表包含可以配对的名称。

pairID | nameID1 | nameID2 | active | somevalue

我首先检查哪些“名称”是活动的,然后是哪些对是“活动的”。在此之后,我结合名称得到:“appusd”。我在第三个表中使用的这个pairname,在那里我将所有数据保存到这个pairnames。我使用“pairname”作为自己的原始数据的原因是,我填写的数据来自一个需要这个“pairname”的 API,因此我以后可以更好地处理数据。

问题是,我不想要所有的名字,而不是所有的pairname-combinations。所有这些的脚本时间为 0,7 秒。所以没关系。

$tradeagainst = array("ABC","USD");
$timeframearr = array("1h","2h","4h","8h");
$tradeagainstsql = "";
$namepairarr = array();
$insert = "";
$ticker = array();
    $tabelle = "names";
    $tabelle2 = "namepairs";    
    $sqlsc = "SELECT NameID, shortname, nametyp
        FROM ".$tabelle."
        ORDER BY shortname ASC";
    $resultsc = mysqli_query($conn, $sqlsc);
    $nameshortnamearr = array();
    $nameIDarr = array();
    while($rowc = mysqli_fetch_assoc($resultsc)){
        $nameshortnamearr []= $rowc["shortname"];
        $nameIDarr []= $rowc["NameID"];
            if(in_array($rowc["shortname"],$tradeagainst)){
        if($tradeagainstsql == ""){
            $tradeagainstsql .= " AND (".$tabelle2.".tradenameID = '".$rowc["NameID"]."'";
        }else{
            $tradeagainstsql .= " OR ".$tabelle2.".tradenameID = '".$rowc["NameID"]."'";
        }
            }
    }
    if($tradeagainstsql != ""){
        $tradeagainstsql .= ") ";
    }
    $sqls = "SELECT ".$tabelle.".*, GROUP_CONCAT(".$tabelle2.".tradenameID) as trID
        FROM ".$tabelle."
        LEFT JOIN ".$tabelle2." ON ".$tabelle.".NameID = ".$tabelle2.".NameID
        WHERE ".$tabelle.".active != '1'
        AND ".$tabelle2.".active != '1'
        ".$tradeagainstsql."
        GROUP BY ".$tabelle.".NameID
        ORDER BY ".$tabelle.".shortname";
    $results = mysqli_query($conn, $sqls);
    if (mysqli_num_rows($results) > 0) {
    while($row = mysqli_fetch_assoc($results)) {
        $nameID = $row["NameID"];
        $shortname = $row["shortname"];
        $active = $row["active"];
        $nametyp = $row["nametyp"];
        $namepairsarr = explode(",",$row["trID"]);
        foreach($namepairsarr as $trnameID){
                    $ct++;
                    $namepair = $shortname.$nameshortnamearr[array_search($trnameID, $nameIDarr)];
                    $namepairarr []= $namepair;
        }
        }
    }

这是我做的第一部分,以获取 $namepairarr。它也是动态的,能够设置,$tradeagainst, $timeframearr;

第二部分是这个:

$tabelle3 = "namepairdata";
$updatearray = array();
foreach($namepairarr as $namepair){
    $sqlnp = "";
    $sqlnpcount = "";
    foreach($timeframearr as $timeframe){
    if($sqlnp == ""){
        $sqlnp .= "(SELECT value1, timeframe
        FROM ".$tabelle3." 
        WHERE pair = '".$namepair."' AND timeframe = '".$timeframe."' ORDER BY value1 DESC LIMIT 2)";
        $sqlnpcount .= "(SELECT count(*) AS rawcount
        FROM ".$tabelle3." 
        WHERE pair = '".$namepair."' AND timeframe = '".$timeframe."')";    
    }else{
        $sqlnp .= " UNION ALL (SELECT value1, timeframe
        FROM ".$tabelle3." 
        WHERE pair = '".$namepair."' AND timeframe = '".$timeframe."' ORDER BY value1 DESC LIMIT 2)";
        $sqlnpcount .= " UNION ALL (SELECT count(*) AS rawcount
        FROM ".$tabelle3." 
        WHERE pair = '".$namepair."' AND timeframe = '".$timeframe."')";    
    }
    }

    $resultnp = mysqli_query($conn, $sqlnp);
    $resultnpc = mysqli_query($conn, $sqlnpcount);
    $rowsvalue1 = array();
    $rowstimeframe = array();
    $rowscount = array();
    while($rowkl = mysqli_fetch_assoc($resultnp)){
    $rowsvalue1 []= $rowkl['value1'];
    $rowstimeframe []= $rowkl['timeframe'];
    }
    while($rowklc = mysqli_fetch_assoc($resultnpc)){
    $rowscount []= $rowklc['rawcount'];
    }
    $rc = 0;
    foreach($timeframearr as $timeframe){
    $value11 = "";
    $value12 = "";
    $timeframecount = $rowscount[$rc]; $rc++;
    for($ints = 0; $ints < count($rowstimeframe); $ints++){
        if($timeframe == $rowstimeframe[$ints]){
            if($value11 == ""){
            $value11 = $rowsvalue1[$ints];
            }else{
            $value12 = $rowsvalue1[$ints];
            }
        }
    }
    $updatearray []= array($namepair,$timeframe,$value11,$value12,$timeframecount);
    }

最后我得到了一个数组 $updatearray,我将不得不对它做点什么。

标签: phpmysqlcountunion

解决方案


推荐阅读