SQL减少了表上选择的数量

时间:2015-12-02 11:08:51

标签: oracle11g query-performance

我的SQL查询存在性能问题:(在Oracle SQL上)

SELECT CONVERT(CHAR(10),GETDATE(),103) + ' ' + RIGHT(CONVERT(CHAR(26),GETDATE(),109),14)

专用于特定processid的所有行的结果(4711):

Data:
- step:number
- processid:number
- Status:number
- process_planed:number

- id:primary
- ... and many more

我的数据库充满了这样的数据。问题是,步长值没有固定。它也可以是:

step   |processid  |Status   |Process_planned |....
---------------------------------------------------
10     |4711       |30       | 75             |....
20     |4711       |50       | 81             |....
30     |4711       |10       | 81             |....
40     |4711       |10       | 36             |....
50     |4711       |10       | 25             |....

现在我想了解每个具有process_planned = 75和Status = 10的数据,但我只想要这些进程,它们的第一个条目(在上面的步骤10中的示例中)等于10.我的解决方案如下:

  • 1获取具有不同processid的process_planned = 75的所有行的查询
  • 现在我拥有process_id = 75
  • 所涉及的所有流程
  • 然后我为每个process_id做一个子查询,检查第一步是否与process_planned = 75有关,以及Status = 10
  • 然后我将这个单个数据写入数组。

现在问题是我的解决方案缺乏性能!例如40个processid用我的解决方案241查询每个6个步骤!必须有一种更简单的方法来做到这一点。

但是我不知道,如果这个步骤会被修复就很容易,那么只需要在步骤= 10的地方加上第一步就可以了。

有你的想法吗?

2 个答案:

答案 0 :(得分:0)

您是否尝试使用ROW_NUMBER查找每个进程ID的第一条记录?

您可以使用行号对每个进程ID的返回记录进行排名。然后,您可以筛选最高排名。

Example

WITH SampleDate AS
    (
        /* This CTE returns some example records.
         */
        SELECT
            r.*
        FROM
            (
                VALUES    
                    (10, 4711, 30, 75),
                    (20, 4711, 50, 81),
                    (30, 4711, 10, 75),
                    (40, 4711, 10, 75),
                    (50, 4711, 10, 25)
            ) AS r(Step, ProcessId, [Status], Processed_Planned)
    )
/* Main query returns the first row for 
 * each process id with a planned of 75
 * and a status of 10.
 */
SELECT
    r.*
FROM
    (
        /* This sub query ranks the steps from each 
         * procsss id.
         */
        SELECT
            ROW_NUMBER() OVER(PARTITION BY ProcessId ORDER BY Step) AS RowNumber,
            *
        FROM
            SampleDate
        WHERE
            Processed_Planned = 75
            AND [Status] = 10
    ) AS r
WHERE
    RowNumber = 1 
;

答案 1 :(得分:0)

我认为你要求step process_planned = 75status = 10的{​​{1}}的最低值,在这种情况下你可以做

SELECT MIN(step) AS step, processid, status, process_planned
FROM data
WHERE process_planned = 75 AND status = 10
GROUP BY processid, status, process_planned;