He comenzado a leer acerca de Common Table Expression y no puedo pensar en un caso de uso en el que necesitaría usarlos. Parecen ser redundantes, ya que lo mismo se puede hacer con tablas derivadas. ¿Hay algo que me falta o que no entiendo bien? ¿Puede alguien darme un ejemplo simple de limitaciones con consultas de selección, derivadas o tablas temporales para hacer el caso de CTE? Cualquier ejemplo simple sería muy apreciado.Cuándo utilizar Common Table Expression (CTE)
Respuesta
Un ejemplo, si necesita hacer referencia/unirse al mismo conjunto de datos varias veces, puede hacerlo definiendo un CTE. Por lo tanto, puede ser una forma de reutilización de código.
Un ejemplo de auto referencia es la recursividad: Recursive Queries Using CTE
para excitar Microsoft definiciones Taken from Books Online:
Un CTE se puede utilizar para:
crear una consulta recursiva. Para obtener más información, consulte Recursive Queries Using Common Table Expressions.
Sustituya una vista cuando no se requiera el uso general de una vista; es decir, no es necesario almacenar la definición en metadatos.
Habilite la agrupación por columna que se deriva de una subselección escalar, o una función que no es determinista o tiene acceso externo.
Haga referencia a la tabla resultante varias veces en la misma instrucción.
Los uso para separar consultas complejas, especialmente combinaciones complejas y sub-consultas. Me parece que los estoy usando cada vez más como 'pseudo-views' para ayudarme a entender el propósito de la consulta.
Mi única queja es que no se pueden volver a utilizar. Por ejemplo, puedo tener un proceso almacenado con dos instrucciones de actualización que podrían usar el mismo CTE. Pero el 'alcance' del CTE es la primera consulta solamente.
¡El problema es que los "ejemplos simples" probablemente no necesiten realmente CTE!
Aún así, muy útil.
bien. ¿Puedes hacer un caso con algún ejemplo relativamente complejo que pueda ayudarme a manejar este concepto? – imak
"Mi única queja sobre ellos es que no se pueden volver a usar": un CTE que desee volver a utilizar debe considerarse candidato para una "VISTA" :) – onedaywhen
@onedaywhen: Entendido, pero eso implica un alcance con el que no siempre me siento cómodo. Algunas veces, dentro del alcance de un proceso, me gustaría definir un CTE y usarlo para selecciones y actualizaciones, o seleccionar datos similares de diferentes tablas. – n8wrl
Hay dos razones por las que veo utilizar las cte.
Para usar un valor calculado en la cláusula where. Esto me parece un poco más limpio que una tabla derivada.
Supongamos que hay dos mesas - Preguntas y Respuestas unidas por Questions.ID = Answers.Question_Id (y Identificación del cuestionario)
WITH CTE AS
(
Select Question_Text,
(SELECT Count(*) FROM Answers A WHERE A.Question_ID = Q.ID) AS Number_Of_Answers
FROM Questions Q
)
SELECT * FROM CTE
WHERE Number_Of_Answers > 0
Aquí hay otro ejemplo en el que quiero obtener una lista de preguntas y respuestas. Quiero que las Respuestas se agrupen con las preguntas en los resultados.
WITH cte AS
(
SELECT [Quiz_ID]
,[ID] AS Question_Id
,null AS Answer_Id
,[Question_Text]
,null AS Answer
,1 AS Is_Question
FROM [Questions]
UNION ALL
SELECT Q.[Quiz_ID]
,[Question_ID]
,A.[ID] AS Answer_Id
,Q.Question_Text
,[Answer]
,0 AS Is_Question
FROM [Answers] A INNER JOIN [Questions] Q ON Q.Quiz_ID = A.Quiz_ID AND Q.Id = A.Question_Id
)
SELECT
Quiz_Id,
Question_Id,
Is_Question,
(CASE WHEN Answer IS NULL THEN Question_Text ELSE Answer END) as Name
FROM cte
GROUP BY Quiz_Id, Question_Id, Answer_id, Question_Text, Answer, Is_Question
order by Quiz_Id, Question_Id, Is_Question Desc, Name
Hoy vamos a aprender sobre la expresión de tabla común que es una nueva característica que se introdujo en SQL Server 2005 y también está disponible en versiones posteriores.
Expresión de tabla común: - La expresión de tabla común se puede definir como un conjunto de resultados temporales o, en otras palabras, es un sustituto de las vistas en SQL Server. La expresión de tabla común solo es válida en el lote de instrucción donde se definió y no se puede usar en otras sesiones.
Sintaxis de declarar CTE (expresión de tabla común): -
with [Name of CTE]
as
(
Body of common table expression
)
Le permite tomar un ejemplo: -
CREATE TABLE Employee([EID] [int] IDENTITY(10,5) NOT NULL,[Name] [varchar](50) NULL)
insert into Employee(Name) values('Neeraj')
insert into Employee(Name) values('dheeraj')
insert into Employee(Name) values('shayam')
insert into Employee(Name) values('vikas')
insert into Employee(Name) values('raj')
CREATE TABLE DEPT(EID INT,DEPTNAME VARCHAR(100))
insert into dept values(10,'IT')
insert into dept values(15,'Finance')
insert into dept values(20,'Admin')
insert into dept values(25,'HR')
insert into dept values(10,'Payroll')
He creado dos tablas empleados y Dept y se inserta 5 filas en cada tabla . Ahora me gustaría unirme a estas tablas y crear un conjunto de resultados temporales para usarlo más.
With CTE_Example(EID,Name,DeptName)
as
(
select Employee.EID,Name,DeptName from Employee
inner join DEPT on Employee.EID =DEPT.EID
)
select * from CTE_Example
Vamos a tomar cada línea de la declaración una por una y entender.
Para definir CTE escribimos "con" cláusula, a continuación, damos un nombre a la expresión de tabla, nombre aquí me he dado como "CTE_Example"
Entonces escribimos "como" y encierran nuestro código en dos soportes (---), podemos unir varias tablas en los corchetes adjuntos.
En la última línea, he usado "Seleccionar * de CTE_Example", estamos refiriendo la expresión de tabla común en la última línea de código, así que podemos decir que es como una vista, donde estamos definiendo y usando el ver en un solo lote y CTE no se almacena en la base de datos como un objeto permanente. Pero se comporta como una vista. podemos realizar una declaración de eliminación y actualización en CTE y eso tendrá un impacto directo en la tabla a la que se hace referencia que se están utilizando en CTE. Tomemos un ejemplo para entender este hecho.
With CTE_Example(EID,DeptName)
as
(
select EID,DeptName from DEPT
)
delete from CTE_Example where EID=10 and DeptName ='Payroll'
En la declaración anterior que están suprimir una fila de CTE_Example y se eliminarán los datos de la tabla de referencia "DEPARTAMENTO" que se utiliza en el CTE.
Todavía no entiendo el punto. ¿Cuál es la diferencia entre esto y solo borrar de DEPT con exactamente la misma condición? No parece hacer nada más fácil. –
Generalmente utilizo CTE para crear vistas donde no puedo usar tablas temporales locales o globales.
Uno de los escenarios que encontré útil para usar CTE es cuando desea obtener filas DISTINCT de datos basadas en una o más columnas, pero devuelve todas las columnas en la tabla. Con una consulta estándar, primero debe volcar los valores distintos en una tabla temporal e intentar volver a unirlos a la tabla original para recuperar el resto de las columnas o puede escribir una consulta de partición extremadamente compleja que pueda devolver los resultados en una ejecución, pero con la mayor probabilidad, será ilegible y causará problemas de rendimiento.
embargo, usando CTE (como respondida por Tim Schmelter en Select the first instance of a record)
WITH CTE AS(
SELECT myTable.*
, RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
FROM myTable
)
SELECT * FROM CTE
WHERE RN = 1
Como se puede ver, esto es mucho más fácil de leer y mantener. Y en comparación con otras consultas, es mucho mejor en rendimiento.
;with cte as
(
Select Department, Max(salary) as MaxSalary
from test
group by department
)
select t.* from test t join cte c on c.department=t.department
where t.salary=c.MaxSalary;
probar esto
Quizás su más sentido pensar en un CTE como un sustituto de una vista utilizada para una sola consulta. Pero no requiere la sobrecarga, los metadatos o la persistencia de una vista formal.Muy útil cuando necesita:
- Cree una consulta recursiva.
- Utilice los resultados de CTE más de una vez en su consulta.
- Promueva la claridad en su consulta reduciendo trozos grandes de subconsultas idénticas.
- El grupo habilitado por una columna derivada en el conjunto de resultados de la CTE
He aquí un ejemplo de cortar y pegar para jugar con:
WITH [cte_example] AS (
SELECT 1 AS [myNum], 'a num' as [label]
UNION ALL
SELECT [myNum]+1,[label]
FROM [cte_example]
WHERE [myNum] <= 10
)
SELECT * FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_all' FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_odd' FROM [cte_example] WHERE [myNum] % 2 = 1
UNION
SELECT SUM([myNum]), 'sum_even' FROM [cte_example] WHERE [myNum] % 2 = 0;
Disfrute
- 1. ¿Cómo se especifican los tipos de columna para CTE (Common Table Expressions) en PostgreSQL?
- 2. ¿Existe algo así como Common Table Expressions en PL/SQL?
- 3. Para CTE o no para CTE
- 4. consulta iterativa sin utilizar CTE
- 5. Cuándo utilizar IList y cuándo utilizar List
- 6. Cuándo usar SQL Table Alias
- 7. Cuándo utilizar retener y cuándo utilizar la copia
- 8. Cuándo utilizar "ON UPDATE CASCADE"
- 9. ¿Cuándo debería usar doctrine ORM y cuándo zend-db-table?
- 10. Cuándo utilizar WCF/REST
- 11. ¿Cuándo NO utilizar NoSQL?
- 12. Cuándo utilizar Dependency Injection
- 13. Cuándo utilizar un HashTable
- 14. Cuándo utilizar la opción
- 15. Cuándo utilizar el operador "^"
- 16. Cuándo utilizar archivos .xcconfig
- 17. Cuándo utilizar NSNotificationCenter
- 18. Cuándo utilizar importaciones absolutas
- 19. cuándo utilizar hibernate.connection.provider_class
- 20. Cuándo utilizar memcached
- 21. Cuándo utilizar NSEnumerationConcurrent
- 22. Cuándo utilizar/proc y cuándo/dev
- 23. Cuándo utilizar Request.UrlReferrer y cuándo Request.ServerVariables ["HTTP_REFERER"]?
- 24. ¿Cuándo debe elegir utilizar InnoDB en MySQL?
- 25. cuándo y en qué escenario usar Expression Tree
- 26. Cuándo utilizar IModelBinder versus DefaultModelBinder
- 27. Cuándo utilizar ServiceTracker vs ServiceReference
- 28. Cuándo utilizar patrones de fábrica?
- 29. cuándo utilizar OPTIMIZE en mysql
- 30. - Cuándo utilizar DataContractSerializer/Binario/XMLSerialiser
Sí. No puedes unirte a una tabla derivada. Vale la pena señalar que un autoinscribirse en un CTE aún lo dejará con dos invocaciones separadas de él. –
@Martin - Estoy sorprendido. ¿Puedes respaldar esa declaración? – RichardTheKiwi
@John Gracias, estoy encontrando http://www.4guysfromrolla.com/webtech/071906-1.shtml bastante útil también – imak