How pass paraeter to WITH clause - sql

I want pass parameter to WITH class something like this:
WITH sction(id) AS (
SELECT q.value1
FROM Example q
WHERE q.id=id )
is it possible?Anyone can help me?

WITH factoring clause a.k.a. CTE (Common Table Expression) is what we some time ago used to call a "subquery". As such, it uses a WHERE clause which you can use to pass that "parameter". For example:
WITH sction AS
(SELECT q.id,
q.value1
FROM Example q
)
SELECT *
FROM sction
WHERE id = 125 --> "125" is that "parameter" you pass while selecting from SCTION CTE
As of a subquery I mentioned: that would have been
select *
from (
select id, value1 from example --> this is a CTE
)
where id = 125
In CTE, it is moved "up", outside your "main" query.

with sction as (select q.value1,q.id from example q )
select * from sction where id = 1;

Related

Running nested CTEs

On the BigQuery SELECT syntax page it gives the following:
query_statement:
query_expr
query_expr:
[ WITH cte[, ...] ]
{ select | ( query_expr ) | set_operation }
[ ORDER BY expression [{ ASC | DESC }] [, ...] ]
[ LIMIT count [ OFFSET skip_rows ] ]
I understand how the (second line) select could be either:
{ select | set_operation }
But what is the ( query_expr ) in the middle for? For example, if it can refer to itself, wouldn't it make the possibility to construct a lisp-like query such as:
with x as (select 1 a)
(with y as (select 2 b)
(with z as (select 3 c)
select * from x, y, z))
Actually, I just tested it and the answer is yes. If so, what would be an actual use case of the above construction where you can use ( query_expr ) ?
And, is there ever a case where using a nested CTE can do something that multiple CTEs cannot? (For example, the current answer is just a verbose way or writing what would more properly be written with a single WITH expression with multiple CTEs)
The following construction might be useful to model how an ETL flow might work and to encapsulate certain 'steps' that you don't want the outer query to have access to. But this is quite a stretch...
WITH output AS (
WITH step_csv_query AS (
SELECT * FROM 'Sales.CSV'),
step_filter_csv AS (
SELECT * FROM step_csv_query WHERE Country='US'),
step_mysql_query AS (
SELECT * FROM MySQL1 LEFT OUTER JOIN MySQL2...),
step_join_queries AS (
SELECT * FROM step_filter_csv INNER JOIN step_mysql_query USING (id)
) SELECT * FROM step_join_queries -- output is last step
) SELECT * FROM output -- or whatever we want to do with the output...
This query might be useful in that case where a CTE is being referred to by subsequent CTEs.
For instance, you can use this if you want to join two tables, use expressions and query the resulting table.
with x as (select '2' as id, 'sample' as name )
(with y as ( select '2' as number, 'customer' as type)
(with z as ( select CONCAT('C00',id), name, type from x inner join y on x.id=y.number)
Select * from z))
The above query gives the following output :
Though there are other ways to achieve the same, the above method would be much easier for debugging.
Following article can be referred for further information on the use cases.
In nested CTEs, the same CTE alias can be reused which is not possible in case of multiple CTEs. For example, in the following query the inner CTE will override the outer CTEs with the same alias :
with x as (select '1')
(with x as (select '2' as id, 'sample' as name )
(with x as ( select '2' as number, 'customer' as type)
select * from x))

Declaring and using variables using WITH clause

I have a query that uses WITH clause (subquery factoring) and i need to define a variable and assign a value to it to use in a couple of the subqueries within the WITH clause.
Is it possible?
Thanks.
I've tried some ways to define the variable and affect it but i always have syntax error.
You can use the following two methods:
1. Use within WITH clause
WITH MY_VARIABLE ( VAL ) AS (
SELECT
12 -- your variable value goes here
FROM
DUAL
), MY_MAIN_WITH_QUERY ( DIFFERENT_COLUMNS ) AS (
SELECT
1
FROM
MY_VARIABLE M
WHERE
M.VAL > 10 -- the use of a variable in your main query
)
SELECT
*
FROM
MY_MAIN_WITH_QUERY;
2. Use DEFINE
DEFINE VAL=12; -- declaring and assigning value to your variable
WITH MY_MAIN_WITH_QUERY ( DIFFERENT_COLUMNS ) AS (
SELECT
1
FROM
DUAL
WHERE
&VAL > 10 -- the use of your variable in your query
)
SELECT
*
FROM
MY_MAIN_WITH_QUERY;
Cheers!!
You can always define your column value in the with clause.
with cte as ( select 1 as your_value from dual )
Then use it to your need. For example:
select your_value from cte

simple subquery not working DB2

hey guys this is a very simple sql query that is not giving me the correct result.
subquery:
SELECT NEODB2ADMIN.ORDERS.MEMBER_ID
FROM NEODB2ADMIN.ORDERS
WHERE NEODB2ADMIN.ORDERS.ORDERS_ID = 6371043
this subquery successfully returns a correct value 627809
simple query:
SELECT *
FROM NEODB2ADMIN.ADDRESS
WHERE MEMBER_ID IN (627809)
this query executes properly and returns 4 rows.(4 addresses for a member)
but if I try to combine these queries in 1 query as follows:
SELECT *
FROM NEODB2ADMIN.ADDRESS
WHERE MEMBER_ID IN (
SELECT NEODB2ADMIN.ORDERS.MEMBER_ID
FROM NEODB2ADMIN.ORDERS
WHERE NEODB2ADMIN.ORDERS.ORDERS_ID = 6371043
)
then the query returns 0 rows. why is this happening?
Thanks
Your query looks OK, the only I can think is maybe you mistake the value on the result.
can you try this:
SELECT *
FROM NEODB2ADMIN.ADDRESS
WHERE MEMBER_ID IN (
SELECT 627809
FROM NEODB2ADMIN.ORDERS
WHERE NEODB2ADMIN.ORDERS.ORDERS_ID = 6371043
)
and this
SELECT *
FROM NEODB2ADMIN.ADDRESS
WHERE MEMBER_ID IN (
SELECT 627809
FROM NEODB2ADMIN.ORDERS
)
Since your Order (presumably) can only carry a single Member_ID -- can you please try your full query without the "IN", rather try an equal join as follows:
SELECT *
FROM NEODB2ADMIN.ADDRESS
WHERE MEMBER_ID = (
SELECT NEODB2ADMIN.ORDERS.MEMBER_ID
FROM NEODB2ADMIN.ORDERS
WHERE NEODB2ADMIN.ORDERS.ORDERS_ID = 6371043
)

With clause subquery availablility for the entire SQL statement in Oracle

I am trying to write a SQL statement which reuses the subquery of the With clause multiple times in Oracle.
With mySubQ as (
...
)
Select Something
From SomeTable,
(
Select *
From mySubQ
where mySubQ.Something >= 0
) newSubQ
where mySubQ.Something = SomeTable.Something
This gives me error - ORA-32034 unsupported use of WITH clause
What am I missing?
You need to join with mySubQ, not just define it.
WITH mySubQ AS (...)
SELECT Something
FROM SomeTable
JOIN mySubQ ON mySubQ.Something = SomeTable.Something
WHERE mySubQ.Something >= 0
If you put the query of mySubQ in a subquery, you can't reference mySubQ in the WHERE clause of the main query. Each level of query can only access tables in its own FROM and JOIN clauses, not those of subqueries.
Here is the error: where mySubQ.Something = SomeTable.Something.
The bottom query selects from SomeTable and from the subquery with alias newSubQ,
so mySubQ.Something is not known in this context.
If something is a real column name, not only a "placeholder in the pseudocode", then there is also another error here: Select Something - the column is ambiguous, because both sometable and the subquery have this column.
Try this query:
With mySubQ as (
SELECT * FROM sometable
)
Select newSubQ.Something
From SomeTable,
(
Select *
From mySubQ
where mySubQ.Something >= 0
) newSubQ
where newSubQ.Something = SomeTable.Something
;
Demo --> http://www.sqlfiddle.com/#!4/88855/12
This demo contains also another example of using WITH clause:
WITH mySubQ AS (
SELECT *
FROM sometable
),
mySubQ_1 AS (
SELECT *
FROM mySubQ
WHERE somethingelse = 1
),
mySubQ_2 AS (
SELECT *
FROM mySubQ
WHERE something between 2 AND 5
)
SELECT *
FROM sometable s, mySubQ_1 m1,
(
SELECT * FROM mySubQ_2
WHERE something < 10
) m2
WHERE s.something = m1.something
AND m1.somethingelse = m2.somethingelse

SQL Server : convert sub select query to join

I have 2 two tables questionpool and question where question is a many to one of question pool. I have created a query using a sub select query which returns the correct random results but I need to return more than one column from the question table.
The intent of the query is to return a random test from the 'question' table for each 'QuizID' from the 'Question Pool' table.
SELECT QuestionPool.QuestionPoolID,
(
SELECT TOP (1) Question.QuestionPoolID
FROM Question
WHERE Question.GroupID = QuestionPool.QuestionPoolID
ORDER BY NEWID()
)
FROM QuestionPool
WHERE QuestionPool.QuizID = '5'
OUTER APPLY is suited to this:
Select *
FROM QuestionPool
OUTER APPLY
(
SELECT TOP 1 *
FROM Question
WHERE Question.GroupID = QuestionPool.QuestionPoolID
ORDER BY NEWID()
) x
WHERE QuestionPool.QuizID = '5'
Another example of OUTER APPLY use http://www.ienablemuch.com/2012/04/outer-apply-walkthrough.html
Live test: http://www.sqlfiddle.com/#!3/d8afc/1
create table m(i int, o varchar(10));
insert into m values
(1,'alpha'),(2,'beta'),(3,'delta');
create table x(i int, j varchar, k varchar(10));
insert into x values
(1,'a','hello'),
(1,'b','howdy'),
(2,'x','great'),
(2,'y','super'),
(3,'i','uber'),
(3,'j','neat'),
(3,'a','nice');
select m.*, '' as sep, r.*
from m
outer apply
(
select top 1 *
from x
where i = m.i
order by newid()
) r
Not familiar with SQL server, but I hope this would do:
Select QuestionPool.QuestionPoolID, v.QuestionPoolID, v.xxx -- etc
FROM QuestionPool
JOIN
(
SELECT TOP (1) *
FROM Question
WHERE Question.GroupID = QuestionPool.QuestionPoolID
ORDER BY NEWID()
) AS v ON v.QuestionPoolID = QuestionPool.QuestionPoolID
WHERE QuestionPool.QuizID = '5'
Your query appears to be bringing back an arbitrary Question.QuestionPoolId for each QuestionPool.QuestionPoolId subject to the QuizId filter.
I think the following query does this:
select qp.QuestionPoolId, max(q.QuestionPoolId) as any_QuestionPoolId
from Question q join
qp.QuestionPoolId qp
on q.GroupId = qp.QuestionPoolId
WHERE QuestionPool.QuizID = '5'
group by qp.QuestionPoolId
This returns a particular question.
The following query would allow you to get more fields:
select qp.QuestionPoolId, q.*
from (select q.*, row_number() over (partition by GroupId order by (select NULL)) as randrownum
from Question q
) join
(select qp.QuestionPoolId, max(QuetionPool qp
on q.GroupId = qp.QuestionPoolId
WHERE QuestionPool.QuizID = '5' and
randrownum = 1
This uses the row_number() to arbitrarily enumerate the rows. The "Select NULL" provides the random ordering (alternatively, you could use "order by GroupId".
Common Table Expressions (CTEs) are rather handy for this type of thing...
http://msdn.microsoft.com/en-us/library/ms175972(v=sql.90).aspx