从两个表中选择/订购数据

时间:2012-11-30 13:05:45

标签: javascript mysql sqlite

我有两张桌子可以存放两种不同游戏的游戏数据。为简单起见,假设它们只共享一个名为Timestamp的列(特别是它们具有不同数量的列)。我想渲染一个包含两个表信息的列表,同时按Timestamp排序。

我目前正在做的工作,但几乎所有的赌注都有更好的方法来做到这一点。我最关心的是某些时候的表现(移动应用)。这是一个代表结构的存根 - 相信我,我知道这看起来有多可怕。我只想让它先工作,现在我正在寻找改进。 ;)

var readyA,
    readyB = false;

var dataA, 
    dataB;

function doLoop () {
    setTimeout(renderData, 100);
}

function renderData () {
    if (!readyA || !readyB) {
        doLoop();
        return;
    }

    var dataAll = dataA.concat(dataB);
    dataAll.sort(function (a,b) {
        return a['Timestamp'] <= b['Timestamp'];
    });

    // pass data into a template depending on from which game it is and render it
    // ...
}

// wait for both queries to finish
doLoop();

// select data from game A
myDatabaseClass.query('SELECT ... FROM GameA', function (results) {
    dataA = new Array(results.rows.length);
    for (var i=0; i<results.rows.length; i++) { 
        dataA[i] = results.rows.item(i); 
    }

    readyA = true;
});

// select data from game B
myDatabaseClass.query('SELECT ... FROM GameB', function (results) {
    dataB = new Array(results.rows.length);
    for (var i=0; i<results.rows.length; i++) { 
        dataB[i] = results.rows.item(i); 
    }

    readyB = true;
});

现在的问题是,如果我可以通过查询中的某种UNIONJOIN以某种方式简化此操作。显然,Timeout构造很糟糕,但是如果查询可以在一个查询中完成(或者至少有一个事务 - 数据库类可以处理它),那么它将自动折叠成一个简单的回调函数。

编辑:我确实找到了这个(Pull from two different tables and order),但整个NULL AS some_column感觉很脏。真的没有更好的选择吗?

2 个答案:

答案 0 :(得分:2)

查询的结果始终是具有固定列数的单个表,因此所有SELECT必须具有相同的列数:

SELECT a1, a2, a3,   Timestamp FROM GameA
UNION ALL
SELECT b1, b2, NULL, Timestamp FROM GameB
ORDER BY Timestamp

UNION ALLUNION快,因为它不会尝试删除重复项。)

答案 1 :(得分:1)

你的代码非常好。从像我这样的SQL黑客的角度来看,你在客户端做UNION和ORDER BY。这没什么不对。你似乎做得差不多。你的“concat”是客户端的UNION等价物,你的“sort”相当于ORDER BY。

如果你使用服务器端NULL as missing-column操作,你说UNION结构有点脏。但是,显然要将两个不同的结果集视为相同,这样您就可以对它们进行排序,以使它们必须以某种方式使它们相互适应。排序函数中的a['Timestamp'] <= b['Timestamp']排序排序标准也是一种使两个结果集相互符合的方案。它的性能可能低于使用UNION。

不要害怕使用NULL as missing-column使UNION中的两个结果集相互一致。它不脏,而且价格不贵。

请考虑以某种方式限制SELECT操作,可能是通过一系列时间戳。这将允许您的系统向上扩展,特别是如果您在用于限制SELECT的列上放置索引。

(顺便说一句,你的sort函数有错误.sort函数需要返回-1,0或+1,具体取决于第一项是小于,等于还是大于第二项。你正在返回一个真/假值。这不能正常工作。)

(你将两个查询并行化到同一个MySQL实例。这很聪明,但实际上可能是一个在游戏扩展时重载MySQL的公式。请记住,游戏的每个用户都有自己的机器在运行Javascript但他们都共享你的MySQL。)