簡體   English   中英

如何在 oracle sql 中的 select 計數中對 rownum 使用 case 語句?

[英]How to use a case statement on rownum from a select count in oracle sql?

我對 SQL 有點陌生,並且有一個關於 where 子句中基於 count(*) 的 case 語句的問題。

我有一個名為 CARS 的表,我正在查詢特定的制造商和汽車的制造日期。

從那里,假設我正在隨機檢查一些汽車以確保數據正確,所以我想首先隨機排序結果,然后根據我返回的結果數量選擇“x”行(查詢的結果越多,我隨機檢查的越多)

在下面的查詢中,我首先從 CARS 表中獲取特定的汽車,獲取結果的行數,然后我想做一個案例語句說:如果在結果,這里是前 'y' 行。

select count(*) over() as carcount,
    vehicles.*
from (
        select *
        from CARS
        where MANUFACTURER IN (
                'BMW',
                'Ford',
                'Volkswagen',
                'Toyota',
                'Saab',
                'Porsche',
                'Hyundai',
                'Alfa Romeo'
            )
            and MANUFACTURED_DATE >= sysdate
            and MANUFACTURED_DATE <= (SYSDATE + 30)
            and MANUFACTURED_DATE is not null
        ORDER BY DBMS_RANDOM.RANDOM
    ) vehicles
where rownum < (
        CASE
            WHEN carcount = 1 THEN 1
            WHEN carcount = 2 THEN 2
            WHEN carcount >= 3 AND carcount <= 4 THEN 2
            WHEN carcount >= 5 AND carcount <= 14 THEN 4
            WHEN carcount >= 15 AND carcount <= 52 THEN 15
            WHEN carcount >= 53 AND carcount <= 365 THEN 25
            WHEN carcount > 365 THEN 30
            ELSE 0
        END
    );

當我運行我的查詢時,我收到了錯誤:

ORA-00904: "carcount": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

我不太確定為什么 carcount 不是有效標識符,以及如何在隨機結果中獲得前“x”行。 我將不勝感激任何幫助/建議 - 在此先感謝您!

應該在子查詢中計算carcount以使查詢正常工作。 我會更進一步,使用row_number()而不是rownum

select *
from (
    select 
        c.*, 
        row_number() over(order by dbms_random.random) rn,
        count(*) over() cnt
    from cars c
    where 
        manufacturer in (
            'bmw',
            'ford',
            'volkswagen',
            'toyota',
            'saab',
            'porsche',
            'hyundai',
            'alfa romeo'
        )
        and manufactured_date >= sysdate
        and manufactured_date <= sysdate + 30
) c
where rn <= case
    when cnt >  365 then 30
    when cnt >= 53  then 4
    when cnt >= 15  then 15
    when cnt >= 5   then 4
    when cnt >= 2   then 2
    else 1
end

旁注:

  • 子查詢中的條件and manufactured_date is not null是多余的 - 您已經在此列上有不等式謂詞,它會過濾掉null

  • 可以通過首先對具有高值的條件進行排序來簡化case表達式 - 還有一些冗余條件,並且第二個分支中的目標行數似乎不公平地低

  • 似乎您希望在行號的不等式條件中使用<=而不是< (否則,例如,當子查詢僅返回 1 行時,您的查詢將過濾掉結果)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM