如何在查询结果中更改具有特定值的行的位置

时间:2018-05-01 05:51:52

标签: sql postgresql

这就是我想要做的事情。

我有以下示例数据。

trxn_id event_id  timestamp
1         4        111
1        16        121
1         1        110

现在,我希望事件16在 order by timestamp desc 的结果中显示在4和1之间。意味着结果总是按时间顺序排序,除了event_id = 16行,就在event_id = 4行的正下方,无论时间是什么

我在考虑首先选择event_id = 4结果,然后将其与选择event_id的其余部分的结果联合起来,但它们不保持应用union的顺序。可以做些什么?感谢。

编辑:我正在根据特定的trxn_id进行选择。一个trxn中可以有多个event_id=16。所有内容都需要显示在event_id=4下方。

3 个答案:

答案 0 :(得分:2)

我认为您可以预定义event_id的层次结构,首先按其排序,然后按TIMESTAMP DESC排序。

ORDER BY CASE event_id
        WHEN 4
            THEN 1
        WHEN 16
            THEN 2
        WHEN 1
            THEN 3
        END
    ,TIMESTAMP DESC

答案 1 :(得分:1)

在Postgres中,我建议使用数组:

public boolean gameStatus(MyBoard gameBoard, int columnPosition, CellState gameToken) {
    int rowPosition = 0;

    for (int i = 0; i < gameBoard.getWidth(); i++)
        for (int j = 0; j < gameBoard.getHeight(); j++)
            if (gameBoard.get(i, columnPosition) != CellState.FREE)
                rowPosition = i;

    if (checkColumn(gameBoard, columnPosition, gameToken, rowPosition))
        return true;
}


public boolean checkColumn(MyBoard gameBoard, int columnPosition, CellState gameToken, int rowPosition) {
    int tokenCounter = 1;

    if ((rowPosition + 4) <= 6)
        for (int i = rowPosition + 1; i <= rowPosition + 3; i++)
            if (gameToken == gameBoard.get(i, columnPosition))
                tokenCounter++;
            else
                break;

    if (tokenCounter == 4)
        return true;

    return false;
}

答案 2 :(得分:0)

基本上,如果时间戳16的时间戳等于4的时间戳,那么您可以通过新的时间戳和事件ID对其进行排序。使用窗口函数可以有一个更短的解决方案,但我不确定它是否适用于postgresql

select t1.txn_id, t1.event_id, t1.timestamp, case when t2.min_time is not null then t2.min_time else t1.timestamp end as timestamp2
from table as T1
left join 
(
  select trxn_id, min(timestamp) as min_time
  from table
  group by trxn_id
) as T2
on T1.trxn_id = T2.trxn_id
  and T1.event_id = 16
order by t1.txn_id, timestamp2 desc, t1.event_id, t1.timestamp desc