1

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

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

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

4

2 回答 2

3

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

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

当您使用 SQL 的汇总功能时,就会有很大的不同。例如,select x, count(x) from wherever, group by x将显示每个值x和每个值的计数。对于这样的功能,您通常会在 C++ 或Java中使用std::mapor 。std::unordered_mapHashMapTreeMap

编辑:

举一个非常简单的例子,让我们考虑一个相当简单的 group-by 子句的结果,我们想要计算不同年份出生的人。我们将从这样的原始数据开始:

last-name<tab>first-name<tab>height<tab>birth-year

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

Coffin\tJerry\t70\t1964

在 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 << "Year\tCount\n";
for (auto c : year_counts)
    std::cout << c.first << "\t" << c.second << "\n";
于 2013-05-07T18:23:44.797 回答
0

Use guava, It's Function can be used to pull out the group by field, and it's multimap to hold references from the group by to the instances of that item. Example can be found here: 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]));
            }
        }
    }
}
于 2013-05-07T18:42:12.463 回答