joining multiple common table expressions
Try this query, perhaps this is what you are looking for.
;WITH cte AS
(SELECT dbo.Cable.*,
row_number() over(partition by dbo.Cable.TagNo order by dbo.Cable.CableRevision desc) as rn
FROM dbo.Cable
WHERE dbo.Cable.CableRevision = @CoreRevision
), cte2 AS
(SELECT dbo.Cable.TagNo, dbo.Core.*,
row_number() over(partition by dbo.Core.CoreNo order by dbo.Core.CoreRevision desc) as rn
FROM dbo.Core INNER JOIN dbo.Cable ON dbo.Cable.Id = dbo.Core.CableId
WHERE dbo.Core.CoreRevision <= @CoreRevision
)
SELECT *
FROM cte c FULL JOIN cte2 c2 ON c.TagNo = c2.TagNo
WHERE c.rn = 1 OR c2.rn = 1
How to use multiple CTEs in a single SQL query?
Use the key word WITH
once at the top. If any of your Common Table Expressions (CTE) are recursive (rCTE) you have to add the keyword RECURSIVE
at the top once also, even if not all CTEs are recursive:
WITH RECURSIVE
cte1 AS (...) -- can still be non-recursive
, cte2 AS (SELECT ...
UNION ALL
SELECT ...) -- recursive term
, cte3 AS (...)
SELECT ... FROM cte3 WHERE ...
The manual:
If
RECURSIVE
is specified, it allows aSELECT
subquery to
reference itself by name.
Bold emphasis mine. And, even more insightful:
Another effect of
RECURSIVE
is thatWITH
queries need not be ordered:
a query can reference another one that is later in the list. (However,
circular references, or mutual recursion, are not implemented.)
WithoutRECURSIVE
,WITH
queries can only reference siblingWITH
queries that are earlier in theWITH
list.
Bold emphasis mine again. Meaning that the order of WITH
clauses is meaningless when the RECURSIVE
key word has been used.
BTW, since cte1
and cte2
in the example are not referenced in the outer SELECT
and are plain SELECT
commands themselves (no collateral effects), they are never executed (unless referenced in cte3
).
How can I have multiple common table expressions in a single SELECT statement?
I think it should be something like:
WITH
cte1 as (SELECT * from cdr.Location),
cte2 as (SELECT * from cdr.Location)
select * from cte1 union select * from cte2
Basically, WITH
is just a clause here, and like the other clauses that take lists, "," is the appropriate delimiter.
Keeping it simple and how to do multiple CTE in a query
You can have multiple CTE
s in one query, as well as reuse a CTE
:
WITH cte1 AS
(
SELECT 1 AS id
),
cte2 AS
(
SELECT 2 AS id
)
SELECT *
FROM cte1
UNION ALL
SELECT *
FROM cte2
UNION ALL
SELECT *
FROM cte1
Note, however, that SQL Server
may reevaluate the CTE
each time it is accessed, so if you are using values like RAND()
, NEWID()
etc., they may change between the CTE
calls.
combining two CTE in a single query
If you are joining values from CTE1
and CTE2
based on CHILDID
column then you can write as:
SELECT
CTE1.CONSUMERID,
CTE1.CHILDID,
CTE1.APPLICATIONUSAGESTARTDATE,
CTE1.WEEKNUMBER,
-- a.CHILDID ,
AVG(CONVERT(DECIMAl,DATEDIFF ( minute , b.TIMESTAMP , a.TIMESTAMP)))
as CURRENTWEEKTIMERRESTART
FROM
CTE2 a
LEFT JOIN CTE2 b on a.CHILDID = b.CHILDID and a.row = b.row+1
LEFT JOIN CTE1 on CTE1.CHILDID = a.CHILDID and CTE1.RN = 1
group by CTE1.CONSUMERID,CTE1.CHILDID,CTE1.APPLICATIONUSAGESTARTDATE,CTE1.WEEKNUMBER
ORDER BY CTE1.CHILDID ASC
Joining more than one common table expression (CTE) is taking too long in SQL (query will not end) is there something wrong with my code?
I have the answer to this question.
I have just heard back from a tech guy and it is because of indexing.
By adding an index the cost of the query went from:
cost=151491121951.08
to
cost=820386.91
You can do:
EXPLAIN SELECT primary_key as timing,
MIN(timedate) AS second_try,
FROM table t1
WHERE timedate > (SELECT MIN(timedate) FROM table t2 WHERE t1.primary_key = t2.primary_key group by primary_key)
AND criteria1='x' AND timedate BETWEEN 'x' AND 'x' GROUP BY 1
to get the cost of the query using EXPLAIN
Joining multiple CTEs
Since you only work with two tables, orders
and rev
, consider conditional aggregation by moving WHERE
conditions to CASE
logic for single aggregate query. Also, consider only one CTE for all possible country/brand pairs for LEFT JOIN
on the two tables.
WITH cb AS (
SELECT Country, Brand FROM orders
UNION
SELECT Country, Brand FROM rev
)
SELECT cb.Country
, cb.Brand
, SUM(o.netprice) AS OrdersNet
, SUM(CASE
WHEN o.isopen = 1
THEN o.netprice
END) AS OpenOrdersNet
, SUM(CASE
WHEN r.bdate BETWEEN '2020-12-01' AND '2020-12-31'
THEN r.netprice
END) AS Revenue
, SUM(CASE
WHEN r.bdate BETWEEN '2020-12-01' AND '2020-12-31'
THEN r.rpro
END) AS RawProceeds
, SUM(CASE
WHEN r.bdate BETWEEN '2020-11-01' AND '2020-11-30'
THEN r.netprice
END) AS RevenueCompare
, SUM(CASE
WHEN r.bdate BETWEEN '2020-11-01' AND '2020-11-30'
THEN r.rpro
END) AS RawProceedsCompare
FROM cb
LEFT JOIN orders o
ON cb.Country = o.Country
AND cb.Brand = o.Brand
LEFT JOIN rev r
ON cb.Country = r.Country
AND cb.Brand = r.Brand
GROUP BY cb.Country
, cb.Brand
SQL Fiddle
SQL join on CTE with multiple
Consider joining by two derived tables (subqueries in FROM
and JOIN
clauses) as your duplicate count includes both tables and not just one:
...
SELECT q.c1, q.c2, q.c3, q.t2_c1, a.[TWO]
FROM
(
SELECT *
FROM (
SELECT ONE, TWO,
ROW_NUMBER() OVER(PARTITION BY ONE ORDER BY ONE) duplicate_count
FROM all_col1
) sub
WHERE sub.duplicate_count = 1
) a
INNER JOIN
(
SELECT t1.c1, t1.c2, t1.c3, t2.c1 as t2_c1
FROM s1.t2 t2
INNER JOIN s1.t1 t1 on t2.c6 = t5.c6
WHERE t2.c5 >= '2014-01-01'
AND t2.c5 >= '2014-01-01'
AND t1.c4 = 'P'
) q
ON a.ONE = q.c1
How to join the result set of Common Table Expression with other existing table in sql server 2005?
You can define multiple CTEs for a single select, and each CTE can reference previously defined ones. So you can do:
With CTEQuery
as
(SELECT StudentOnlineExamCourseAnswer.StudentID, StudentOnlineExamCourseAnswer.OnlineExamID, StudentOnlineExamCourseAnswer.CourseID,
StudentOnlineExamCourseAnswer.CentreID,
case QuestionBank.ComplexLevelID when 1 then (2) when 2 then (4) when 3 then (6) when 4 then (8) when 5 then (10) end as Mark
FROM QuestionBank INNER JOIN
StudentOnlineExamCourseAnswer ON QuestionBank.Answer = StudentOnlineExamCourseAnswer.Answer AND
QuestionBank.QuestionID = StudentOnlineExamCourseAnswer.QuestionID)
, SummarizedCTE as (
select StudentID, OnlineExamID ,CourseID , CentreID , sum(Mark) as TotalMark from CTEQuery
group by StudentID, OnlineExamID ,CourseID , CentreID)
select <new query involving joining SummarizedCTE with the "other table" referenced in your discussion>
Related Topics
Why Can't You Use Sqlite Rowid as a Primary Key
Geometry and Geography Difference SQL Server 2008
How to Replace Blank (Null ) Values with 0 for All Records
How to Get Array/Bag of Elements from Hive Group by Operator
How to Increment Value in Postgres Update Statement on JSON Key
Acts-As-Taggable-On Find All Tags by Context
Postgresql Query to Select Data from Last Week
Referencing a Composite Primary Key
How to Return Rows from a Declare/Begin/End Block in Oracle
How to Drop All Foreign-Key Constraints on a Table in SQL Server 2000
Compare Performance Difference of T-Sql Between and '<' '>' Operator
In SQL Server, How to Create While Loop in Select
How to Do a SQL Update in Batches, Like an Update Top
Best Practices for Multithreaded Processing of Database Records
Blank Out Duplicate Column Values in SQL Reporting Services
How to Use Left & Right Functions in SQL to Get Last 3 Characters