选择“查询 - 每两行合并为单个结果行”



假设我有以下"产品"表:

ProductID | ProductName 
----------+---------
0255463   | ProductA       
0254483   | ProductB
0255341   | ProductC
0905454   | ProductD

有没有办法(在Android的SQLite中)将每个连续的行选择成单个结果行?以下是所需的查询结果:

FirstProductID | FirstProductName | SecondProductID | SecondProductName 
---------------+------------------+-----------------+---------
0255463        | ProductA         |        0254483  | ProductB
0255341        | ProductC         |       0905454   | ProductD

我想要一个可用于任何表的通用解决方案,无论表内容如何。

创建具有自动增量列的临时表

CREATE TEMP TABLE temp(
  id int not null primary auto increment,
  pid int,
  pname text,    
);

将选择此数据插入到临时表中

INSERT INTO temp (pid, pname) SELECT * FROM Products;

在第一个实例具有id % 2 = 0id = id + 1上联接临时表

SELECT t1.pid AS t1_pid, t1.pname AS t1_pname,
  t2.pid AS t2_pid, t2.pname AS t2_pname
FROM temp as t1 LEFT JOIN temp AS t2
  ON t1.id + 1 = t2.id
WHERE t1.id % 2 = 0;

单个查询(不是更快):

SELECT
    First.ProductId AS FirstProductId,
    First.ProductName AS FirstProductName,
    Second.ProductId AS SecondProductId,
    Second.ProductName AS SecondProductName 
FROM
    (SELECT *, Cnt/2 AS Line FROM (
        SELECT *, (
            SELECT COUNT() FROM Products AS _ WHERE ROWID<Products.ROWID
        ) AS Cnt FROM Products WHERE Cnt%2=0
    )) AS First
LEFT JOIN
    (SELECT *, Cnt/2 AS Line FROM (
        SELECT *, (
            SELECT COUNT() FROM Products AS _ WHERE ROWID<Products.ROWID
        ) AS Cnt FROM Products WHERE Cnt%2=1
    )) AS Second
ON First.Line = Second.Line
ORDER BY First.Line;

如果你需要一个更快的解决方案,@kzarns提出了一个很好的解决方案。

如果行有连续的 ID,这很容易:

SELECT t1.productID AS productID1, t1.ProductName AS productName1, t2.productID AS productID2, t2.ProductName AS ProductName2
FROM product t1
JOIN product t2 WHERE t1.id+1 = t2.id
WHERE MOD(t1.id,2) = 1
ORDER BY t1.id
这是

示例想法,基本上我所做的是从 2 个 select 语句中获得不同的结果并加入它,试一试,欢呼=)

-

-样品表

DECLARE @SAMPLE TABLE
(
ProductID INT,
ProductName NVARCHAR(255)
)
-

-样本数据

INSERT INTO @SAMPLE
VALUES
('1','ProductA'),
('2','ProductB'),
('3','ProductC'),
('4','ProductD')
SELECT FirstProductID,FirstProductName,SecondProductID,SecondProductName FROM
(
-

-查询获取第一个产品项

SELECT ROW_NUMBER() OVER (ORDER BY FirstProductID) firstrn,FirstProductID,FirstProductName
FROM(
SELECT ProductID 'FirstProductID',ProductName 'FirstProductName' FROM 
(
SELECT ROW_NUMBER() OVER (Order by productid) firstrn1,ProductID,ProductName
FROM @SAMPLE
) FIRSTPRODUCTTABLE
WHERE firstrn1%2 = 1
) FIRSTPRODUCTTABLE1 
)t1

-执行连接

LEFT OUTER JOIN (
-

-查询获取第二个产品项

SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY SecondProductID) rownumber,SecondProductID,SecondProductName
FROM(
SELECT ProductID 'SecondProductID',ProductName 'SecondProductName' FROM 
(
SELECT ROW_NUMBER() OVER (Order by productid) rn,ProductID,ProductName
FROM @SAMPLE
) SECONDPRODUCTTABLE
WHERE rn%2 = 0
)SECONDPRODUCTTABLE1
) t2
) t3 ON t1.firstrn=t3.rownumber

在SQL中执行此操作将相当复杂和缓慢。

像这样对列值重新排序的最干净方法是实现您自己的 Cursor 类,该类包装原始数据库游标,但将列数加倍,并将所有列访问重定向到相应的记录。像这样:

class DoubleColumnCursor implements Cursor {
    Cursor baseCursor;
    int baseColumns;
    int currentPosition;
    public getColumnCount() {
        return baseColumns * 2;
    }
    public String getColumnName(int columnIndex) {
        if (columnIndex < baseColumns)
            return baseCursor.getColumnName(columnIndex) + "1";
        else
            return baseCursor.getColumnName(columnIndex - baseColumns) + "2";
    }
    public boolean moveToPosition(int position) {
        boolean result = baseCursor.moveToPosition(position * 2);
        if (result)
            currentPosition = position;
        return result;
    }
    public String getString(int columnIndex) {
        if (columnIndex < baseColumns) {
            baseCursor.moveToPosition(currentPosition * 2);
            return baseCursor.getString(columnIndex);
        } else {
            baseCursor.moveToPosition(currentPosition * 2 + 1);
            return baseCursor.getString(columnIndex - baseColumns);
        }
    }
    ...
};

最新更新