Reputation: 13
I'm trying to find orders with multiple products and exclude orders with only one product.
My data is organized as follows:
ORDER_ID | PRODUCT_GROUP_ID | PRODUCT_ID | PROD_RANK |
---|---|---|---|
3574 | 1038 | 460 | 1 |
3574 | 1038 | 461 | 2 |
3574 | 1038 | 462 | 3 |
3574 | 3748 | 750 | 1 |
1417 | 9113 | 175 | 1 |
2265 | 8202 | 472 | 1 |
2265 | 3203 | 475 | 1 |
I've tested trying to grab only order with multiple product by this basic rank SQL and it does what it should, but how do I exclude order id 1417 from the rank? Is there a better way to accomplish what I'm trying to accomplish?
Below is the SQL with the output. As you can see, the rank is doing it's job but now I need to exclude all orders with only one product_group_id (1417).
Thanks
WITH TESTRANK AS(
SELECT
ORDER_ID
,PRODUCT_GROUP_ID
,PRODUCT_ID
,RANK() OVER(PARTITION BY ORDER_ID, PRODUCT_GROUP_ID ORDER BY PRODUCT_ID) AS ROWNUM_RANK
FROM ORDER_DETAIL
WHERE
ORDER_ID IN (3574, 1417, 2265)
)
SELECT * FROM TESTRANK
--WHERE ROWNUM_RANK=1
ORDER_ID | PRODUCT_GROUP_ID | PRODUCT_ID | PROD_RANK |
---|---|---|---|
3574 | 1038 | 460 | 1 |
3574 | 3748 | 750 | 1 |
1417 | 9113 | 175 | 1 |
2265 | 8202 | 472 | 1 |
2265 | 3203 | 475 | 1 |
Upvotes: 0
Views: 97
Reputation: 1269823
I would just use max()
and min()
:
WITH TESTRANK AS (
SELECT ORDER_ID, PRODUCT_GROUP_ID, PRODUCT_ID,
RANK() OVER (PARTITION BY ORDER_ID, PRODUCT_GROUP_ID ORDER BY PRODUCT_ID) AS ROWNUM_RANK,
MAX(PRODUCT_GROUP_ID) OVER (PARTITION BY ORDER_ID) as MAX_PGI,
MIN(PRODUCT_GROUP_ID) OVER (PARTITION BY ORDER_ID) as MIN_PGI,
FROM ORDER_DETAIL OD
WHERE ORDER_ID IN (3574, 1417, 2265)
)
SELECT *
FROM TESTRANK
WHERE MIN_PGI <> MAX_PGI;
Upvotes: 1
Reputation: 27225
I think you're looking for COUNT(DISTINCT PRODUCT_GROUP_ID) OVER (PARTITION BY ORDER_ID)
which unfortunately isn't possible. But which can be mimicked using DENSE_RANK
.
WITH TESTRANK AS (
SELECT
ORDER_ID
, PRODUCT_GROUP_ID
, PRODUCT_ID
, RANK() OVER (PARTITION BY ORDER_ID, PRODUCT_GROUP_ID ORDER BY PRODUCT_ID) AS ROWNUM_RANK
-- Count distinct window function
, DENSE_RANK() OVER (PARTITION BY ORDER_ID ORDER BY PRODUCT_GROUP_ID ASC) +
DENSE_RANK() OVER (PARTITION BY ORDER_ID ORDER BY PRODUCT_GROUP_ID DESC) - 1 AS WINDOW_COUNT
FROM #ORDER_DETAIL
WHERE ORDER_ID IN (3574, 1417, 2265)
)
SELECT *
FROM TESTRANK
WHERE ROWNUM_RANK = 1 and WINDOW_COUNT > 1;
Returns:
ORDER_ID | PRODUCT_GROUP_ID | PRODUCT_ID |
---|---|---|
2265 | 8202 | 472 |
2265 | 3203 | 475 |
3574 | 3748 | 750 |
3574 | 1038 | 460 |
Upvotes: 1