【问题标题】:sqlite2: Joining max values per column from another table (subquery reference)?sqlite2:从另一个表(子查询参考)加入每列的最大值?
【发布时间】:2011-04-25 20:29:30
【问题描述】:

我正在使用以下数据库:

CREATE TABLE datas (d_id INTEGER PRIMARY KEY, name_id numeric, countdata numeric);
INSERT INTO datas VALUES(1,1,20);  //(NULL,1,20);
INSERT INTO datas VALUES(2,1,47);  //(NULL,1,47);
INSERT INTO datas VALUES(3,2,36);  //(NULL,2,36);
INSERT INTO datas VALUES(4,2,58);  //(NULL,2,58);
INSERT INTO datas VALUES(5,2,87);  //(NULL,2,87);
CREATE TABLE names (n_id INTEGER PRIMARY KEY, name text);
INSERT INTO names VALUES(1,'nameA'); //(NULL,'nameA');
INSERT INTO names VALUES(2,'nameB'); //(NULL,'nameB');

我想要做的是选择names 的所有值(行)-datas 的所有列都将附加到其中,datas.countdata 是 @ 的最大值的行987654326@(当然还有name_id = n_id)。

我可以通过以下查询到达那里:

sqlite> .header ON

sqlite> SELECT * FROM names AS n1 
    LEFT OUTER JOIN (
        SELECT d_id, name_id, countdata FROM datas AS d1 
        WHERE d1.countdata IN (
            SELECT MAX(countdata) FROM datas 
            WHERE name_id=1 
            ) 
        ) AS p1 ON n_id=name_id;

n1.n_id|n1.name|p1.d_id|p1.name_id|p1.countdata
1|nameA|2|1|47
2|nameB|||

...但是 - 显然 - 它只适用于单行(由name_id=1 明确设置的行)。

问题是,每当我尝试以某种方式引用“当前”n_id 时,SQL 查询都会失败:

sqlite> SELECT * FROM names AS n1 
    LEFT OUTER JOIN (
        SELECT d_id, name_id, countdata FROM datas AS d1 
        WHERE d1.countdata IN (
            SELECT MAX(countdata) FROM datas 
            WHERE name_id=n1.n_id 
            ) 
        ) AS p1 ON n_id=name_id;

SQL error: no such column: n1.n_id

有什么方法可以在 Sqlite2 中实现我想要的吗??

提前致谢,

干杯!

【问题讨论】:

    标签: join subquery max sqlite2


    【解决方案1】:

    哦,好吧 - 这一点都不简单,但这里有一个解决方案:

    sqlite> SELECT * FROM names AS n1 
            LEFT OUTER JOIN ( 
                SELECT d1.* 
                FROM datas AS d1, ( 
                    SELECT max(countdata) as countdata,name_id 
                    FROM datas 
                    GROUP BY name_id
                    ) AS ttemp 
                WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata 
            ) AS p1 ON n1.n_id=p1.name_id;
    
    
    n1.n  n1.name       p1.d_id     p1.name_id  p1.countdata                       
    ----  ------------  ----------  ----------  -----------------------------------
    1     nameA         2           1           47                                 
    2     nameB         5           2           87                                 
    

    嗯,希望这最终能帮助某人,:) 干杯!

    注意事项:请注意,仅调用 max(countdata) 就会完全搞砸d_id

    sqlite> select d_id,name_id,max(countdata) as countdata from datas group by name_id;
    
    d_id  name_id       countdata 
    ----  ------------  ----------
    3     2             87        
    1     1             47        
    

    所以要获得正确的对应d_id,我们必须分别对datas 执行max() - 然后与完整的datas 执行某种相交(除了 sqlite 中的相交要求有两个数据集中的列数相等,这里不是这种情况——即使我们这样做了,如上所示d_id 将是错误的,因此 intersect 将不起作用)。

    一种方法是使用一种临时表,然后使用多表 SELECT 查询,以便在完整的datas 和通过max(countdata) 返回的子集之间设置条件,如下所示:

    sqlite> CREATE TABLE ttemp AS SELECT max(countdata) as countdata,name_id FROM datas GROUP BY name_id;
    sqlite> SELECT d1.*, ttemp.* FROM datas AS d1, ttemp WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata;
    
    d1.d  d1.name_id    d1.countda  ttemp.coun  ttemp.name_id                      
    ----  ------------  ----------  ----------  -----------------------------------
    2     1             47          47          1                                  
    5     2             87          87          2                                  
    
    sqlite> DROP TABLE ttemp;
    

    或者,我们可以重写上面的代码,使用 SELECT 子查询(sub-select?),如下所示:

    sqlite> SELECT d1.* FROM datas AS d1, (SELECT max(countdata) as countdata,name_id FROM datas GROUP BY name_id) AS ttemp WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata;
    
    d1.d  d1.name_id    d1.countda
    ----  ------------  ----------
    2     1             47        
    5     2             87        
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多