Reputation: 469
I have a query statement that selects a list of tools. These tools need to be placed into a 2D vector, where the first level is it's category and second is the category's "bucket".
struct Tool {};
typedef boost::shared_ptr< Tool > ToolPtr;
typedef std::vector< ToolPtr > ToolVec;
typedef std::vector< ToolVec > ToolCategory;
The query statement looks like this:
const QString getTools =
"SELECT tool_id, category_id, category_name, tool_name FROM tool_relation "
"WHERE course_id = ? ORDER BY category_id ASC, tool_id ASC";
q.bindValue(0, courseID);
q.exec();
while (q.next())
{
}
I would like to do this with one query statement, but the only way I can think of is to use a temporary pointer to the correct bucket and test every record to see if the category id changes. Seems inefficient.
EDIT: Something like this is what I came up with when only using one query statement.
ToolVector *curBucket = 0;
int curCategory = 0;
while (q.next())
{
if (q.value(1).toInt() != curCategory)
{
curCategory = q.value(1).toInt();
ToolVec toolVec;
curBucket = &toolVec;
categories.push_back(toolVec);
}
ToolPtr toolPtr(new Tool(
q.value(0).toInt(),
q.value(2).toString()));
curBucket->push_back(toolPtr);
}
Upvotes: 0
Views: 160
Reputation: 7293
We probably differ in the definition of "efficiency". For me it's speed and memory requirements. Processing two SELECT statements will be always slower and more consuming than processing one, even with if
statement for each returned row.
But, even that i don't know anything about your logic, i am somewhat missing how you would be looking for the tool buckets. category_id
is not saved anywhere, and category_name
only inside the Tool
struct. You cannot find a bucket unless you iterate all tools. What about a bucket map
? It might also fulfill your efficiency requirements:
typedef std::map< int, ToolVec > ToolCategory;
while (q.next())
{
curCategory = q.value(1).toInt();
...
categories[curCategory].push_back(toolPtr);
}
Upvotes: 1