example - SQL usando CASE en SELECT con GROUP BY. Necesita CASE-value pero obtener valor de fila
select case when (5)
En realidad, hay una prueba de igualdad comodín. No estoy seguro de por qué agruparías por campo1, eso parecería imposible en tu ejemplo. Traté de encajarlo en tu pregunta:
SELECT FIELD1,
CASE WHEN FIELD2 = 1 THEN FIELD3 END AS CASEFIELD1,
CASE WHEN FIELD2 = 2 THEN FIELD4 END AS CASEFIELD2
FROM
(
SELECT * FROM A
INTERSECT
SELECT * FROM B
) C
UNION -- results in a distinct
SELECT
A.FIELD1,
null,
null
FROM
(
SELECT * FROM A
EXCEPT
SELECT * FROM B
) C
Esto no funcionará para los tipos de datos que no son comparables
así que básicamente hay 1 pregunta y 1 problema:
1. pregunta : cuando tengo como 100 columnas en una tabla (y no hay ninguna clave o uindex establecido) y quiero unirme o subseleccionar esa tabla consigo mismo, ¿realmente tengo que escribir cada nombre de columna?
2. problema : el ejemplo a continuación muestra la pregunta 1. y el problema real de mi declaración SQL
Ejemplo:
A.FIELD1,
(SELECT CASE WHEN B.FIELD2 = 1 THEN B.FIELD3 ELSE null FROM TABLE B WHERE A.* = B.*) AS CASEFIELD1
(SELECT CASE WHEN B.FIELD2 = 2 THEN B.FIELD4 ELSE null FROM TABLE B WHERE A.* = B.*) AS CASEFIELD2
FROM TABLE A
GROUP BY A.FIELD1
La historia es: si no coloco el CASE en su propia instrucción select, entonces tengo que poner el nombre de fila real en el GROUP BY y el GROUP BY no agrupa el valor NULL del CASE, sino el valor real del fila. Y debido a eso, tendría que unirme o subseleccionar con todas las columnas, ya que no hay ninguna clave y ningún uindex, o de alguna manera encontrar otra solución.
DBServer es DB2.
Así que ahora para describirlo solo con palabras y sin SQL: tengo "artículos de pedido" que se pueden dividir en "ZD" y "EK" (1 = ZD, 2 = EK) y se pueden agrupar por "distribuidor". Aunque los "artículos de pedido" pueden tener uno de dos "departamentos" diferentes (ZD, EK), los campos / filas para "ZD" y "EK" siempre están llenos. Necesito que la agrupación considere el "departamento" y solo si el "departamento" designado (ZD o EK) está cambiando, entonces quiero que se cree un nuevo grupo.
SELECT
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END) AS ZD,
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END) AS EK,
TABLE.DISTRIBUTOR,
sum(TABLE.SOMETHING) AS SOMETHING,
FROM TABLE
GROUP BY
ZD
EK
TABLE.DISTRIBUTOR
TABLE.DEPARTEMENT
Esto aquí funcionó en SELECT y ZD, EK en GROUP BY. El único problema era que, incluso si EK no era el DEPARTEMENT designado, todavía se abría un nuevo grupo si cambiaba, porque estaba usando el valor EK real y no el NULL del CASE, como ya lo explicaba arriba.
No, no hay prueba de igualdad comodín. Tendría que enumerar todos los campos que desee probar individualmente. Si no desea probar cada campo individual, podría usar un hack tal como concatenar todos los campos, por ej.
WHERE (a.foo + a.bar + a.baz) = (b.foo + b.bar + b.az)
pero de cualquier forma, estás enumerando todos los campos.
Si necesita encontrar todas las filas en la Tabla A que coincidan en la Tabla B, ¿qué le parece INTERSECT o INTERSECT DISTINCT?
select * from A
INTERSECT DISTINCT
select * from B
Sin embargo, si solo quiere filas desde A, donde toda la fila coincide con los valores en una fila de B, ¿por qué su código de muestra toma algunos valores de A y otros de B? Si la fila coincide con todas las columnas, entonces parecería inútil. (Tal vez su pregunta podría ser explicada un poco más completamente?)
Podría tender a resolver algo como esto
WITH q as
(SELECT
Department
, (CASE WHEN DEPARTEMENT = 1 THEN ZD
WHEN DEPARTEMENT = 2 THEN EK
ELSE null
END) AS GRP
, DISTRIBUTOR
, SOMETHING
FROM mytable
)
SELECT
Department
, Grp
, Distributor
, sum(SOMETHING) AS SumTHING
FROM q
GROUP BY
DEPARTEMENT
, GRP
, DISTRIBUTOR
Y aquí damas y caballeros es la solución al problema:
SELECT
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END) AS ZD,
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END) AS EK,
TABLE.DISTRIBUTOR,
sum(TABLE.SOMETHING) AS SOMETHING,
FROM TABLE
GROUP BY
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END),
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END),
TABLE.DISTRIBUTOR,
TABLE.DEPARTEMENT
@ t-clausen.dk: ¡Gracias!
@otros: ...