【问题标题】:How can you simulate a SQL join in C++ using STL and or Boost如何使用 STL 和/或 Boost 在 C++ 中模拟 SQL 连接
【发布时间】:2011-06-17 12:36:06
【问题描述】:

如何使用 c++ 模拟两个动态数据集(即在运行时获取数据)之间的 SQL 连接。
示例表 A 是学生、他们的姓名和课程编号的向量(任何 STL 或 Boost 数据结构都可以)的二维向量。表 B 是一个 2D 向量向量(任何 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


表 C StudentID FirstName LastName Room CourseNum CourseDesc 3490 Saundra Bribiesca 400B F100X 人类生物学 1288 Guy Shippy 500B F103X 生物学和社会 5383 Tia Roache 500B F103X 生物学和社会 5746 Jamie Grunden 340A F101X 动态地球 2341 Emilia Hankinson 300C F120X 冰川、地震和火山

【问题讨论】:

  • 您创建表 B 的代码从这里看起来是错误的。

标签: c++ boost stl


【解决方案1】:

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

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

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

无论哪种方式都可以将您从O(N*M) 带到O((N+M)*logM),除非 N(表 A 的大小)非常小,否则这是一种改进。如果你的大学的学生比课程少得多,那就大错特错了;-)

[*] 这里的“元组”是指任何包含所有值的东西——你一直在使用向量,就可以了。

【讨论】:

    【解决方案2】:

    Sine only 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>g++ test.cpp &&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  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      相关资源
      最近更新 更多