1
SELECT *, COUNT(*) AS conteggio FROM (
(SELECT uno, ruota, data FROM table WHERE ruota = 'BA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
 (SELECT due, ruota, data FROM table WHERE ruota = 'BA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
(SELECT tre, ruota, data FROM table WHERE ruota = 'BA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
 (SELECT quattro, ruota, data FROM table WHERE ruota = 'BA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
(SELECT cinque, ruota, data FROM table WHERE ruota = 'BA'  
           ORDER BY data DESC LIMIT 540)
) t
GROUP BY uno
ORDER BY conteggio DESC LIMIT 20
-------------------------------------------------
SELECT *, COUNT(*) AS conteggio FROM (
(SELECT uno, ruota, data FROM table WHERE ruota = 'CA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
 (SELECT due, ruota, data FROM table WHERE ruota = 'CA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
(SELECT tre, ruota, data FROM table WHERE ruota = 'CA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
 (SELECT quattro, ruota, data FROM table WHERE ruota = 'CA'  
           ORDER BY data DESC LIMIT 540)
 UNION ALL
(SELECT cinque, ruota, data FROM table WHERE ruota = 'CA'  
           ORDER BY data DESC LIMIT 540)
) t
GROUP BY uno
ORDER BY conteggio DESC LIMIT 20

有没有办法只使用一个查询而不是上面的两个查询?
唯一的区别是WHERE ruota = 'VARIABLE'

4

3 回答 3

3
  1. 规范化您的数据:

    CREATE TABLE newtable (
      col INT,
      INDEX (ruota, val),
      FOREIGN KEY(ruota, data) REFERENCES `table` (ruota, data)
    ) SELECT 1, uno val, ruota, data FROM `table` UNION ALL
      SELECT 2, due,     ruota, data FROM `table` UNION ALL
      SELECT 3, tre,     ruota, data FROM `table` UNION ALL
      SELECT 4, quattro, ruota, data FROM `table` UNION ALL
      SELECT 5, cinque,  ruota, data FROM `table`;
    
    ALTER TABLE `table`
      DROP COLUMN uno,
      DROP COLUMN due,
      DROP COLUMN tre,
      DROP COLUMN quattro,
      DROP COLUMN cinque;
    
  2. 简化您现有的查询:

    SELECT   val, ruota, LEAST(COUNT(*), 540) conteggio
    FROM     newtable
    WHERE    ruota = ?
    GROUP BY val
    ORDER BY conteggio DESC
    LIMIT    20;
    
  3. 组合查询:

    SELECT   val, ruota, LEAST(COUNT(*), 540) conteggio
    FROM     newtable
    WHERE    ruota IN ('BA', 'CA')
    GROUP BY ruota, val
    ORDER BY conteggio DESC
    LIMIT    20;
    
于 2012-08-29T10:33:38.263 回答
3

当你写

WHERE ruota = 'CA' ORDER BY data DESC LIMIT 540

您在问“给我卡利亚里的最后 540 次提取”。将这些与来自巴里的那些相加,您将获得 1080 行。

如果你问,

WHERE ruota IN ('CA','BA') ORDER BY data DESC LIMIT 540

你只会得到 540 行,所以你必须首先将限制提高到 1080

完成了,您确定您的存档完整吗?如果不是,或者两个轮子的提取次数不同,则使用 (CA+BA) 获得的 1080 行与使用 (CA)+(BA) 获得的行数不同。

此外,您不需要分组的提取日期。所以你可以查询:

SELECT ruota, numero, COUNT(*) AS conteggio FROM (
    (SELECT uno AS numero, ruota FROM estrazioni WHERE ruota IN ('CA','BA')
         ORDER BY data DESC LIMIT 1080)
UNION ALL
    (SELECT due AS numero, ruota FROM estrazioni WHERE ruota IN ('CA','BA')
         ORDER BY data DESC LIMIT 1080)
... ) AS preliminare
GROUP BY ruota, numero;

如果您只对数字频率感兴趣,则不需要轮子,因此:

SELECT numero, COUNT(*) AS conteggio FROM (
    (SELECT uno AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
         ORDER BY data DESC LIMIT 1080)
UNION ALL
    (SELECT due AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
         ORDER BY data DESC LIMIT 1080)
... ) AS preliminare
GROUP BY numero;

最后,您可以通过对子选择进行分组并对部分计数求和来进行实验,以防它可能更快:

SELECT ruota, numero, SUM(conteggio) AS conteggio FROM (
    SELECT ruota, numero, count(numero) AS conteggio FROM (
        SELECT ruota, uno AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
            ORDER BY data DESC LIMIT 1080 ) AS primo GROUP BY ruota, numero
    UNION ALL SELECT ruota, numero, count(numero) AS conteggio FROM (
        SELECT ruota, due AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
            ORDER BY data DESC LIMIT 1080 ) AS secondo GROUP BY ruota, numero
    UNION ALL SELECT ruota, numero, count(numero) AS conteggio FROM (
        SELECT ruota, tre AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
            ORDER BY data DESC LIMIT 1080 ) AS terzo GROUP BY ruota, numero
    UNION ALL SELECT ruota, numero, count(numero) AS conteggio FROM (
        SELECT ruota, quattro AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
            ORDER BY data DESC LIMIT 1080 ) AS quarto GROUP BY ruota, numero
    UNION ALL SELECT ruota, numero, count(numero) AS conteggio FROM (
        SELECT ruota, cinque AS numero FROM estrazioni WHERE ruota IN ('CA','BA')
            ORDER BY data DESC LIMIT 1080 ) AS quinto GROUP BY ruota, numero
) AS preliminare GROUP BY ruota, numero ORDER BY conteggio DESC LIMIT 20;

最后一个版本将五个 1080 行子选择中的出现求和,然后将它们从一个五行选择中求和,将 1080 分组五次,而不是将 5400 行分组一次。它应该使用更少的内存;是否更快,我不确定。

更新:我已经修复了 SQL 并验证了最后一个查询。

于 2012-08-29T10:37:13.600 回答
0

无需再次重复完整的 SQL 脚本,您可以IN使用 SQL 中的 for 子句并将两个变量指定为逗号分隔值,然后在同一查询中选择结果。就像是

WHERE ruota IN ('CA' ,'BA')
于 2012-08-29T10:15:24.723 回答