ORDER BY CASE中的SQL Server Row_number

时间:2018-06-05 13:07:27

标签: sql sql-server sql-order-by case row-number

编辑整个主题。

我需要创建一个视图,按类型对文章进行排序。

  1. 如果我只有类型:* VALUE - >我只需要显示这一行。
  2. 如果我有类型:* VALUE& 2 - >仍然相应地显示行* VALUE类型。
  3. 如果我只有类型:2 - >显示这一个。
  4. 我已经做过这样的事了:

    VALUE *是一个值,应该来自另一个带有Join的表。

    SELECT Id_item ,Name_item , Type_item , Id_type_item FROM ITEM WHERE Name_item = 'Gillette' AND (Id_Type_item = VALUE* OR Id_Type_item ='10')
    ORDER BY CASE WHEN row_number() OVER(ORDER BY Id_item DESC , Id_Type_Item DESC) <= 1 THEN 0 ELSE 1 END;

    但是,如果我们为类型提供了两行(* VALUE&amp; 10),那就是这样做:

    Id_item / Name_item / Type_item / Id_Type_Item
    1       Gillette    45            30 (*VALUE)
    1       Gillette    2             10
    

    所以我认为Over()的顺序可能总是按* VALUE排序(实际上是另一个表中的另一列)

    我总是只想选择1行数据! :)

3 个答案:

答案 0 :(得分:1)

我猜,你想要的是从每个SELECT返回的“第一”行?对于同一个表中的每个变量,不需要使用单独的SELECT语句,您可以使用窗口函数来执行此操作。我相信这就是你可能会追求的目标。

WITH CTE AS(
    --The following assumes table A and B have the same DDL (which begs the question, why are they different tables?)
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY var
                              ORDER BY (SELECT NULL)) AS RN --Replace SELECT(NULL) with your actual ordering criteria
    FROM A
    WHERE var IN (1,2)
    UNION --ALL(?)
    SELECT *
           ROW_NUMBER() OVER (PARTITION BY var
                              ORDER BY (SELECT NULL)) AS RN --Replace SELECT(NULL) with your actual ordering criteria
    FROM B
    WHERE var IN (3))
SELECT *
FROM CTE
WHERE RN = 1;

答案 1 :(得分:0)

这是一个可能的解决方案。在这种情况下,ROW_NUMBER,RANK和DENSE_RANK都可以工作。但是,ROW_COUNT不是sql server中的有效窗口函数。

DECLARE @A TABLE(ID INT, Value INT)
DECLARE @B TABLE(ID INT,Value INT)
INSERT INTO @A VALUES (1,1),(2,1),(3,2),(4,3),(5,2),(6,1),(7,3)
INSERT INTO @B VALUES (1,1),(2,1),(3,1),(4,2),(5,3),(6,2),(7,1),(8,3)

;WITH D AS
(
    SELECT ID,Value FROM @A WHERE Value IN(1,2)
    UNION ALL
    SELECT ID,Value FROM @B WHERE Value IN (3)
 )
SELECT * FROM
(
    SELECT
      ID, Value,
      ValueRankInSet = DENSE_RANK() OVER(PARTITION BY VALUE ORDER BY ID) -- <-- If you do not have an ID field you can subst ID with NEWID() as order is not important 
    FROM D
)AS X
WHERE ValueRankInSet = 1

答案 2 :(得分:0)

在Select(s)中分配优先级,然后在row_number中按顺序排序:

with cte as 
 (
    SELECT *,
       row_number()
       over (-- partition by ??? 
             order by prio) as Position
    FROM 
    (
    SELECT 1 as prio, * FROM A WHERE var = 1
    UNION -- probably a more efficient UNION ALL
    SELECT 2 as prio, * FROM A WHERE var = 2
    UNION -- probably a more efficient UNION ALL
    SELECT 3 as prio, * FROM B WHERE var = 3
    )
 )
select *
from cte
WHERE Position = 1