jerarquica - optimizar consultas lentas mysql
Seleccione distinto de mĂșltiples campos usando sql (8)
Tengo 5 columnas correspondientes a las respuestas en una base de datos de juegos de preguntas y respuestas: correcto, wrong1, wrong2, wrong3, wrong4
Quiero devolver todas las respuestas posibles sin duplicados. Esperaba lograr esto sin usar una tabla temporal. ¿Es posible usar algo similar a esto ?:
select c1, c2, count(*)
from t
group by c1, c2
Pero esto devuelve 3 columnas. Me gustaría una columna de respuestas distintas.
Gracias por tu tiempo
¿Es esto lo que querías?
select distinct c1 from t
Bueno, puedes usar UNIÓN y ejecutar 5 instrucciones de selección, una para cada columna en tu tabla. Se vería algo como esto:
SELECT right FROM answers
UNION
SELECT wrong1 FROM answers
UNION
SELECT wrong2 FROM answers
UNION
SELECT wrong3 FROM answers
UNION
SELECT wrong4 FROM answers
Esto le dará una lista única que contiene todas las respuestas. Sin embargo, aún tendrá duplicados si tiene varias copias de la misma respuesta dentro de una sola columna.
En MySQL
Y MS SQL
:
SELECT
CASE
WHEN which = 1 THEN c1
WHEN which = 2 THEN c2
WHEN which = 3 THEN c3
WHEN which = 4 THEN c4
WHEN which = 5 THEN c5
END AS answer,
which
FROM mytable, (
SELECT 1 AS which
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
) w
Para Oracle
, agregue FROM DUAL
a cada uno de los números seleccionados.
Esto debería darle todos los valores distintos de la tabla. Supongo que querrá agregar cláusulas Where para seleccionar solo para una pregunta en particular. Sin embargo, esta solución requiere 5 subconsultas y puede ser lenta si su tabla es enorme.
SELECT DISTINCT(ans) FROM (
SELECT right AS ans FROM answers
UNION
SELECT wrong1 AS ans FROM answers
UNION
SELECT wrong2 AS ans FROM answers
UNION
SELECT wrong3 AS ans FROM answers
UNION
SELECT wrong4 AS ans FROM answers
) AS Temp
SELECT DISTINCT(ans) FROM (
SELECT right AS ans FROM answers
UNION
SELECT wrong1 AS ans FROM answers
UNION
SELECT wrong2 AS ans FROM answers
UNION
SELECT wrong3 AS ans FROM answers
UNION
SELECT wrong4 AS ans FROM answers
) AS Temp
El DISTINCT es superfluo, porque UNION no devolverá filas idénticas para todas las columnas. (Cuando desee duplicar, o si sabe que no existen duplicados, use UNION ALL para obtener un rendimiento más rápido)
Esto le dará una lista única que contiene todas las respuestas. Sin embargo, aún tendrá duplicados si tiene varias copias de la misma respuesta dentro de una sola columna.
Ese no debería ser el caso si usa UNION, solo si usa UNION ALL
SELECT [value] INTO #TEMP
FROM
(
SELECT [value] = 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 1
) AS X
(4 row(s) affected)
SELECT [value]
FROM #TEMP
value
-----------
1
2
3
1
(4 row(s) affected)
SELECT [value]
FROM #TEMP
UNION
SELECT [value]
FROM #TEMP
value
-----------
1
2
3
(3 row(s) affected)
Las columnas de "right, wrong1, wrong2, wrong3, wrong4" significan que tiene una base de datos mal diseñada. En general, un sufijo de número o letra en el nombre de una columna debe ser una bandera roja para replantear el problema.
Como observó, su diseño requirió que navegue para encontrar una solución a un problema típico de reducción de datos.
Esta es la respuesta exacta.
SELECT (ans) FROM (
SELECT correct AS ans FROM tGeoQuiz
UNION
SELECT wrong1 AS ans FROM tGeoQuiz
UNION
SELECT wrong2 AS ans FROM tGeoQuiz
UNION
SELECT wrong3 AS ans FROM tGeoQuiz
UNION
SELECT wrong4 AS ans FROM tGeoQuiz
) AS Temp
Proporcioné una respuesta más arriba .
Sin embargo, me pareció una forma mucho mejor de hacerlo con UNPIVOT.
SELECT DISTINCT(ans)
FROM (
SELECT [Name], ANS
FROM (
SELECT right, wrong1, wrong2, wrong3, wrong4
FROM answers
) AS PVT
UNPIVOT
(ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT
) AS OUTPUT;
Puede proporcionar cualquier cláusula WHERE en la subconsulta interna:
SELECT DISTINCT(ans)
FROM (
SELECT [Name], ANS
FROM (
SELECT right, wrong1, wrong2, wrong3, wrong4
FROM answers
WHERE (...)
) AS PVT
UNPIVOT
(ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT
) AS OUTPUT;