/ / Cómo seleccionar u omitir la siguiente fila si cumple con ciertos criterios: sql, sql-server, tsql, ranking

Cómo seleccionar u omitir la siguiente fila si cumple ciertos criterios: sql, sql-server, tsql, ranking

Realmente ni siquiera estoy seguro de qué dirección tomar con esto ... Estoy tratando de seleccionar una lista de clientes según las siguientes reglas:

  • Seleccione todas las filas del Cliente donde Clasificación = 1,

  • O si Clasificación = 1 Y Tipo = Almacenar, luego Rango 1 y devolver la fila con Rango 2.

  • O si el cliente solo tiene 1 fila, devuélvala incluso si type = Store.

La clasificación no se asigna con una declaración de clasificación en la consulta. Más bien es una columna real en la tabla Cliente (rellenada por un proceso almacenado que hace la clasificación).

Usando el siguiente ejemplo, me gustaría que se devuelvan las filas 1, 4, 6 y 10.

Tabla de clientes

RowID   CustID  Type    Ranking

-----   ------  ----    -------

1       9       Web      1
2       9       Catalog  2
3       9       Store    3
4       10      Store    1
5       11      Store    1
6       11      Web      2
7       12      Store    1
8       12      Web      2
9       12      Catalog  3
10      13      Web      1

Siento que esta tarea es más difícil ¡PORQUE la clasificación ya está hecha cuando se crea la tabla! ¡Cualquier sugerencia es bienvenida!

Respuestas

1 para la respuesta № 1

Podrías probar algo como esto (¡no lo he probado!):

SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE (c.Ranking = 1 AND c.Type != "Store")
OR (c.Type = "Store" AND Ranking = 2)
OR (c.Type = "Store" AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2))

Si la tabla de clientes es grande, es posible que la consulta sea un poco lenta y algo como esto sería más rápido:

SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Ranking = 1 AND c.Type != "Store"

UNION ALL

SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Type = "Store" AND Ranking = 2

UNION ALL

SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Type = "Store" AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2)

0 para la respuesta № 2

Al igual que con la otra respuesta, no he hecho muchaspruebas exhaustivas, pero esto es lo que miraría. La idea aquí es construir una fila_número sobre el tipo de prioridad del conjunto de datos: almacenar en la parte superior y luego usar el rango como la condición de clasificación secundaria.

select *
from (
select
rid = row_number() over  (partition by CustID, order by case when type = "Store" then 0 else 1 end, Rank desc),
rowid,
CustID,
Type,
Ranking
from customer)
where RID = 1

0 para la respuesta № 3

Tratar:

SELECT *
FROM Customer c
WHERE
-- There"s only one row for this customer
(
SELECT COUNT(*)
FROM Customer
WHERE CustID = c.CustID
) = 1
-- There"s a row with Ranking = 1 and Type = "Store", so select Ranking = 2
OR (Ranking = 2 AND EXISTS (SELECT 1 FROM Customer WHERE CustID = c.CustID AND Ranking = 1 AND Type = "Store"))
-- There"s a row with Ranking = 1 that"s not Type = "Store"
OR (Ranking = 1 AND Type <> "Store")