Home > Back-end >  Is there any better method without subquery?
Is there any better method without subquery?

Time:06-21

I have some data like this:

TYPE A B C
aaa 5 6 2022-05-01
aaa 8 7 2022-05-08
aaa 9 8 2022-05-16
bbb 7 4 2022-05-09
bbb 6 8 2022-05-14
bbb 3 3 2022-05-25

I need to get an output like this:

TYPE A D C
aaa 22 8 2022-05-16
bbb 16 3 2022-05-25

My current code :

SELECT type, SUM(A) AS A, SUM(D) AS D, MAX(C) AS C
FROM
    (SELECT 
         type, A, B, C,
         CASE 
             WHEN C = MAX(C) OVER(PARTITION BY type) 
                 THEN B
                 ELSE 0
         END AS D,
     FROM
         data) AS bbb
GROUP BY
    type

Is there any better method without using a subquery?

I'm using SQL Server.

CodePudding user response:

Since you are asking for a query without a subquery, you can try this one:

SELECT DISTINCT TYPE,
  SUM(A) OVER(PARTITION BY TYPE) AS A,
  FIRST_VALUE(B) OVER(PARTITION BY TYPE ORDER BY C DESC) AS D,
  MAX(C) OVER(PARTITION BY TYPE) AS C
FROM data;

Output:

TYPE A D C
aaa 22 8 2022-05-16 00:00:00.000
bbb 16 3 2022-05-25 00:00:00.000

See this db<>fiddle demo.

CodePudding user response:

Here is one approach using ROW_NUMBER along with pivoting logic:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY TYPE ORDER BY C DESC) rn
    FROM data
)

SELECT TYPE, SUM(A) AS A,
       MAX(CASE WHEN rn = 1 THEN B END) AS D,
       MAX(CASE WHEN rn = 1 THEN C END) AS C
FROM cte
GROUP BY TYPE;

Here is a working demo.

  • Related