如何使用STL和/或Boost在C ++中模拟SQL连接

时间:2011-06-17 12:36:07

标签: c++ boost stl

如何使用c ++模拟两个动态数据集之间的SQL连接(即在运行时获取数据)。
示例表A是学生的矢量(任何STL或Boost数据结构都可以)的2D矢量,它们的名称和课程编号。表B是矢量的二维矢量(任何STL或Boost数据结构都可以),当然还有编号,描述和房间号

//Table A
// Columns: StudentID   FirstName   LastName    CourseNum
std::vector<std::string> a1 = boost::assign::list_of("3490")( "Saundra")( "Bribiesca")( "F100X");
std::vector<std::string> a2 = boost::assign::list_of("1288")( "Guy")( "Shippy")( "F103X");
std::vector<std::string> a3 = boost::assign::list_of("5383")( "Tia")( "Roache")( "F103X");
std::vector<std::string> a4 = boost::assign::list_of("5746")( "Jamie")( "Grunden")( "F101X");
std::vector<std::string> a5 = boost::assign::list_of("2341")( "Emilia")( "Hankinson")( "F120X");

std::vector<std::vector<std::string > > TableA = boost::assign::list_of(a1)(a2)(a3)(a4)(a5);

//Table B
//Columns: CourseNum    CourseDesc  Room
 std::vector<std::string> b1 = boost::assign::list_of("F100X")("Human Biology")("400B");
 std::vector<std::string> b2 = boost::assign::list_of("F103X")("Biology and Society")("500B");
 std::vector<std::string> b3 = boost::assign::list_of("F101X")("The Dynamic Earth 340A");
 std::vector<std::string> b4 = boost::assign::list_of("F120X")("Glaciers, Earthquakes and Volcanoes")("300C");Earthquakes and Volcanoes");


 std::vector<std::vector<std::string > > TableB = boost::assign::list_of(b1)(b2)(b3)(b4);

  //Table C ( result of joining A and B ) using TableA[3] and TableB[0] as key
//I want to produce a resultset Table C, like this


Table C
StudentID   FirstName   LastName    Room    CourseNum   CourseDesc
3490    Saundra Bribiesca   400B    F100X   Human Biology
1288    Guy Shippy  500B    F103X   Biology and Society
5383    Tia Roache  500B    F103X   Biology and Society
5746    Jamie   Grunden 340A    F101X   The Dynamic Earth
2341    Emilia  Hankinson    300C   F120X   Glaciers, Earthquakes and Volcanoes

2 个答案:

答案 0 :(得分:4)

SQL引擎使用各种不同的技术来执行连接,具体取决于可用的索引(或者它认为应该动态创建的哈希表)。

最简单的是两个表上的O(N * M)嵌套循环。因此,要进行内部连接,需要比较A中的每一对元素和B中的一对元素。当您看到匹配时,输出一行。

如果您需要加快速度,在这种情况下,您可以在第一列创建表B的“索引”,即第一列为键的std::multimap和元组[*其余列的值为value。然后,对于A中的每一行,在索引中查找其第三列,并为每个匹配输出一行。如果表N中的CourseNum是唯一的,看似合理,那么您可以使用map而不是multimap

无论哪种方式都可以让你从O(N*M)O((N+M)*logM),这是一种改进,除非N(表A的大小)非常小。如果你的学院的学生数量比课程少很多,那么就会出现严重错误; - )

[*]其中“元组”是指任何包含所有值的东西 - 你一直在使用向量,这样做。

答案 1 :(得分:2)

正弦只有A没有任何代码...我决定A这个ooooold Q.
请注意,设计(字符串的向量而不是类使代码不可读)

int main()
{  
    map<string,std::vector<vector<string > >::const_iterator> mapB;
    for(auto it = TableB.cbegin(); it!=TableB.cend(); ++it)
    { 
        mapB[(*it)[0]]=it;// in first map we put primary key and iterator to tableB where that key is
    }
    assert(mapB.size()== TableB.size());// how unique is primary key?
    for_each(TableA.cbegin(), TableA.cend(),
    [&mapB] (const vector<string>& entryA )
    {
        auto itB= mapB.find(entryA.at(3));
        if (itB!=mapB.end()) // if we can make "JOIN"  we do it
        {
            auto entryB = itB->second;
            cout << entryA.at(0) << " " << entryA.at(1) << "  " << entryA.at(2) << "  " << entryB->at(2) << "  " << entryB->at(0) << "  " << entryB->at(1) << endl;
        }
    });
}

输出:

C:\ STL \ MinGW&gt; g ++ test.cpp&amp;&amp; a.exe

3490 Saundra  Bribiesca  400B  F100X  Human Biology  
1288 Guy  Shippy  500B  F103X  Biology and Society  
5383 Tia  Roache  500B  F103X  Biology and Society  
5746 Jamie  Grunden  340A  F101X  The Dynamic Earth  
2341 Emilia  Hankinson  300C  F120X  Glaciers, Earthquakes and Volcanoes