在Java或C++等编程语言中有效地模拟SQL的group by子句,而不是求助于RDBMS

Efficiently emulate SQL's group by clause in a programming language like Java or C++ instead of resorting to an RDBMS

本文关键字:子句 by group RDBMS 求助于 SQL C++ Java 编程语言 模拟 有效地      更新时间:2023-10-16

我想在上载的文件上执行动态SQL GROUP BY。我不想先将文件存储在数据库中,然后再执行子句,因为这对我的需求来说太费时了。

我可以在Java或c++中使用的有效算法是什么?最好是c++。

提前感谢您的任何想法和答案。

最简单的方法可能是对SQL中group by子句中使用的字段上的数据进行排序。

分组具有比排序更宽松的约束,因此理论上它可能比排序稍微快一些,但除非您处理的是大量数据,否则您不太可能看到速度差异。

当您使用SQL的汇总功能时,最大的区别就出现了。例如,select x, count(x) from wherever, group by x将显示x的每个值和每个值的计数。对于这样的功能,您通常会在c++中使用std::mapstd::unordered_map,或者在Java中使用HashMapTreeMap。 编辑:

对于一个确实微不足道的示例,让我们考虑一个相当简单的group-by子句的结果,其中我们想要在不同年份出生的人的计数。我们将从这样的原始数据开始:
last-name<tab>first-name<tab>height<tab>birth-year

所以(例如)我将被编码为:

CoffintJerryt70t1964
在SQL中,我们可以使用:
select birth_year, count(birth_year) 
    from people
    group by birth_year
    order by birth_year

对于c++中的粗略等价,我们可以这样写代码:

struct person { 
    std::string last_name;
    std::string first_name;
    int height;
    int birth_year;
};

我们从一个文件中读取一群人的数据,就像这样:

 std::ifstream in("people.txt");
 std::vector<person> people((std::istream_iterator<person>(in)),
                             std::istream_iterator<person>());

然后我们会像这样收集我们关心的数据:

std::map<int, int> year_counts;
for ( auto &p : people)
    ++year_counts[p.birth_year];

然后我们可以像这样打印出数据:

std::cout << "YeartCountn";
for (auto c : year_counts)
    std::cout << c.first << "t" << c.second << "n";

使用guava,它的函数可以用来取出group by字段,并且它的multimap可以保存从group by到该条目实例的引用。例子可以在这里找到:http://www.gregbugaj.com/?p=228

public class GroupByMultimap {
    public static void main(String[] args) {
        Object[] o1 = new Object[] { 1, "Greg", "Dev" };
        Object[] o2 = new Object[] { 2, "Leo", "Support" };
        Object[] o3 = new Object[] { 3, "Roman", "Dev" };
        Object[] o4 = new Object[] { 4, "Jobby", "Support" };
        List<Object[]> rows = Lists.newArrayList(o1, o2, o3, o4);
        Multimap<String, Object[]> grouped = Multimaps.index(rows,
                new Function<Object[], String>() {
                    @Override
                    public String apply(Object[] item) {
                        return (String) item[2];
                    }
                });
        Iterator<String> keyIterator = grouped.asMap().keySet().iterator();
        while (keyIterator.hasNext()) {
            String key = keyIterator.next();
            System.out.println("key = " + key);
            Collection<Object[]> dataRows = grouped.get(key);
            for (Object[] o : dataRows) {
                System.out.println(String.format("  %d : %s", o[0], o[1]));
            }
        }
    }
}