复杂的sqlite查询和使用数组

时间:2013-02-19 03:49:50

标签: sqlite sorting

我有两个表,“日志”和“会话”。日志具有logID,logName,logDateTime和sessionID。会话具有sessionID和sessionName。

日志不需要是会话的一部分,但它可以。如果它不是会话的一部分,则字段logs.sessionID为NULL。如果它是会话的一部分,则关联的sessionID位于logs.sessionID中,并且它与会话表相关联。

目标: 这是我使用钛工作室开发的iphone应用程序的一部分。我需要创建一个tableview,其中每个日志都是一行,除非会话中有多个日志。在这种情况下,将创建具有会话名称的行,并将具有会话的logNames的标签添加到sessionRow。 tableview行需要按日期时间排序,并且给定会话的日期时间由最新的日志计算。所以把它想象成一个tableview ......


12-12-12 logName1


12-11-12 logName2


SESSIONNAME

logName3,logName4,logName5


12-10-12 logName6


sessionName2

logName7,logName8,logName9


问题:我不太确定如何从查询/排序角度处理这个问题。我想到了很多想法,但它们似乎都有问题。我不是在寻找构建此tableview的UI的帮助,只是处理数据的解决方案。

正在进行中:

**OPTION 1:**

var rowArray=[];
var ignoreArray=[];

var rows = select logID, logName, logDateTime, logs.sessionID, sessionName
           FROM logs, sessions WHERE logs.sessionID=sessions.sessionID OR
           logs.sessionID IS NULL ORDER BY logDateTime DESC, logs.sessionID;

while(rows.isValidRow()){
    var logSessionID = rows.fieldByName('sessionID');

    if(logSessionID){//if the current log is part of a session
        //1. check ignoreArray to see if this session has
             already been created. If not, continue steps 2-4.
        //2. create a tableview row with the sessionName
        //3. loop through all rows, and add the logName to the row created above
             ONLY when it contains the current sessionID
        //4. add session row to rowArray
        //5. put current sessionID into ignoreArray, so that there won't be
             duplicate session rows.
    }else{
        //1. create a regular log row, as it is not part of a session
        //2. add log row to rowArray
    }

    rows.next();
}

//everything is complete, set the array of data to the tableview
tableview.setData(rowArray);

我对选项1的疑虑/问题:

  1. 由于每次点击新会话时循环遍历所有行,这是非常低效吗

  2. 数百只(如果不是数千条)日志会慢吗?

  3. 如何在循环遍历所有行(嵌套)的过程中循环遍历所有行?

    选项2:

    var presortArray=[];
    
    var logs = select * from logs WHERE sessionID IS NULL;
    var sessionlogs = select * from logs WHERE sessionID IS NOT NULL;
    var sessions = select * from sessions;
    
    while(logs.isValidRow()){
        //1. create log row, push to presortArray;
    };
    while(sessions.isValidRow()){
        //1. create session row
        //2. loop through sessionlogs, adding each to the session row
             that contains the current sessionID. Make sure the session
             Row gets a custom date field for future array sorting
        //3. push session row to presortArray
    };
    
    //all rows are now in presortArray.
    var sortArray = //find a way to sort the rows in presortArray based on datetime
    
    tableview.setData(sortArray);
    
  4. 我对选项2的疑虑/问题:

    1. 根据数组中每个对象的自定义字段,使用某种形式的数组排序会不会很慢?

    2. 我可以多次遍历“sessionLogs”,有没有办法在每次循环时将其设置回第一行?

    3. 最重要的问题:现在我已经认真努力解释并希望不会过度解释我的目标和正在进行的工作。有没有更简单的方法来做到这一点,我还没有意识到?

1 个答案:

答案 0 :(得分:1)

使用此示例数据:

CREATE TABLE logs(logID, logName, logDateTime, sessionID);
CREATE TABLE sessions(sessionID, sessionName);
INSERT INTO sessions VALUES (1, 'sessionName'), (2, 'sessionName2');
INSERT INTO logs VALUES (1, 'logName1', '2012-12-12', NULL),
                        (2, 'logName2', '2012-11-12', NULL),
                        (3, 'logName3', '2012-11-01', 1),
                        (4, 'logName4', '2012-11-02', 1),
                        (5, 'logName5', '2012-11-03', 1),
                        (6, 'logName6', '2012-10-12', NULL),
                        (7, 'logName7', '2012-10-01', 2),
                        (8, 'logName8', '2012-10-02', 2),
                        (9, 'logName9', '2012-10-03', 2);

以下查询:

SELECT logID,
       NULL AS sessionID,
       logDateTime,
       logName,
       NULL AS NamesInRandomOrder
FROM logs
WHERE sessionID IS NULL

UNION ALL

SELECT NULL,
       sessions.sessionID,
       MAX(logDateTime),
       sessionName,
       group_concat(logName)
FROM logs JOIN sessions ON logs.sessionID = sessions.sessionID
GROUP BY sessions.sessionID

ORDER BY 3 DESC

将提供此输出:

logID  sessionID  logDateTime  logName       NamesInRandomOrder
-----  ---------  -----------  ------------  --------------------------
1                 2012-12-12   logName1
2                 2012-11-12   logName2
       1          2012-11-03   sessionName   logName3,logName4,logName5
6                 2012-10-12   logName6
       2          2012-10-03   sessionName2  logName7,logName8,logName9


如果您想要订购logName,可以使用此查询:

SELECT logID,
       sessions.sessionID,
       logDateTime,
       sessionName,
       logName
FROM logs LEFT JOIN sessions ON logs.sessionID = sessions.sessionID
ORDER BY logDateTime DESC

会给你这个输出:

logID  sessionID  logDateTime  sessionName   logName
-----  ---------  -----------  ------------  --------
1                 2012-12-12                 logName1
2                 2012-11-12                 logName2
5      1          2012-11-03   sessionName   logName5
4      1          2012-11-02   sessionName   logName4
3      1          2012-11-01   sessionName   logName3
6                 2012-10-12                 logName6
9      2          2012-10-03   sessionName2  logName9
8      2          2012-10-02   sessionName2  logName8
7      2          2012-10-01   sessionName2  logName7

当您到达一个会话的日志列表末尾时,这将要求您签入代码。