I've declared a table variable '#t', and have correctly performed the 'INSERT-INTO-SELECT'.
When I was trying to query the table variable with some additional computation for per-group row numbering, I got error either "Must declare the variable" when using '#t' directly or "invalid object name" while using alias of '#t'. Please kindly advise.
SELECT
*,
(SELECT COUNT(*) FROM "LTV" "COUNTER"
WHERE
"COUNTER"."Collateral_ID" = "LTV"."Collateral_ID"
AND
"COUNTER"."m_il_no" = "LTV"."m_il_no"
AND
"COUNTER"."Ref_Key" <= "LTV"."Ref_Key"
GROUP BY "COUNTER"."Collateral_ID", "COUNTER"."m_il_no"
) "MIL_IDX"
FROM #t AS LTV
Use:
SELECT x.*,
y.num
FROM #t x
JOIN (SELECT t.collateral_id,
t.m_il_no,
COUNT(*) AS num
FROM #t t
GROUP BY t.collateral_id, t.m_il_no) y ON y.collateral_id = x.collateral_id
AND y.m_il_no = x.m_il_no
Related
I am trying to create a table in teradata with sql, but I keep getting the following error:
CREATE TABLE FAILED. [3707] Syntax error, expected something like a name or a Unicode delimited identifier or an 'UDFCALLNAME' keyword or a 'SELECT' keyword or '(' between '(' and the 'WITH' keyword
My goal is to create a table that takes the maximum data, named "verwerkingdatum" in my code for every "contract_nr". Without the create table statement it worked just fine. Now I'm trying to create a table out of this. But I get the error above.
Here is my code:
create table mi_temp.beslagrek_saldo as
(SEL * FROM( WITH x AS
(
SELECT geld_contract_event_id, contract_nr, contract_soort_code,
contract_hergebruik_volgnr,
verwerking_datum,
event_dat,
valuta_code,
saldo_na_muteren_orig,
saldo_na_muteren_eur,
saldo_na_muteren_dc_ind,
valuta_datum,
geld_transactie_soort_code,
tegenrekening_nr,
tegenrekening_naam,
boek_datum,
storno_ind,
mutatie_bedrag_orig,
mutatie_bedrag_eur,
mutatie_bedrag_dc_ind,
soort_overboeking,
tegenrekening_nr_num,
automaat_transactie_type,
automaat_id,
automaat_datum,
automaat_tijd,
ROW_NUMBER() OVER (PARTITION BY contract_nr ORDER BY
verwerking_datum DESC) AS RowNum
FROM MI_VM_Ldm.vgeld_contract_event
WHERE verwerking_datum >= 1181201 AND verwerking_datum <= 1181231
)
SELECT geld_contract_event_id, contract_nr, contract_soort_code,
contract_hergebruik_volgnr,
verwerking_datum,
event_dat,
valuta_code,
saldo_na_muteren_orig,
saldo_na_muteren_eur,
saldo_na_muteren_dc_ind,
valuta_datum,
geld_transactie_soort_code,
tegenrekening_nr,
tegenrekening_naam,
boek_datum,
storno_ind,
mutatie_bedrag_orig,
mutatie_bedrag_eur,
mutatie_bedrag_dc_ind,
soort_overboeking,
tegenrekening_nr_num,
automaat_transactie_type,
automaat_id,
automaat_datum,
automaat_tijd
FROM X
WHERE RowNum = 1))
If I'm reading your post correctly, are you are trying to is filter your select so that your rownum = 1. You can just use qualify to accomplish that.
create table foo as (
SELECT geld_contract_event_id, contract_nr, contract_soort_code,
contract_hergebruik_volgnr,
verwerking_datum,
event_dat,
valuta_code,
saldo_na_muteren_orig,
saldo_na_muteren_eur,
saldo_na_muteren_dc_ind,
valuta_datum,
geld_transactie_soort_code,
tegenrekening_nr,
tegenrekening_naam,
boek_datum,
storno_ind,
mutatie_bedrag_orig,
mutatie_bedrag_eur,
mutatie_bedrag_dc_ind,
soort_overboeking,
tegenrekening_nr_num,
automaat_transactie_type,
automaat_id,
automaat_datum,
automaat_tijd
from
MI_VM_Ldm.vgeld_contract_event
WHERE verwerking_datum >= 1181201 AND verwerking_datum <= 1181231
qualify ROW_NUMBER() OVER (PARTITION BY contract_nr ORDER BY verwerking_datum DESC) =1
) with data;
I have this query (which runs perfect):
WITH TEMPTABLE AS(
SELECT count(CONTRACT_ID) AS no_contract, T.BRANCH_ID as branch
FROM CONTRACT, "EMPLOYMENT" T, TABLE(T."EMPLOYEE") TT
WHERE CONTRACT.EMPLOYEE_ID = TT.EMPLOYEE_ID
AND CONTRACT.CONTRACT_VT_START BETWEEN '01/01/2018' AND '30/06/2018'
GROUP BY T.BRANCH_ID
)
SELECT branch
FROM TEMPTABLE
WHERE no_contract IN (SELECT MAX(no_contract)
FROM TEMPTABLE);
And I was wondering if it can be done with another way instead of WITH clause. Something like this:
SELECT count_per_branch.BRANCH
FROM (SELECT count(CONTRACT_ID) AS no_contract, BRANCH_ID AS BRANCH
FROM CONTRACT, "EMPLOYMENT" T, TABLE(T."EMPLOYEE") TT
WHERE CONTRACT.EMPLOYEE_ID = TT.EMPLOYEE_ID
AND CONTRACT.CONTRACT_VT_START BETWEEN '01/01/2018' AND '30/06/2018'
GROUP BY T.BRANCH_ID) count_per_branch
WHERE count_per_branch.no_contract =
(SELECT max(count_per_branch.no_contract)
FROM count_per_branch);
Which gives an ORA-00942: "table or view does not exist"
Error at Line: 9
You can use a subquery in the FROM clause:
FROM (SELECT count(CONTRACT_ID) ... )
And you can give it an alias:
FROM (SELECT count(CONTRACT_ID) ... ) count_per_branch
And you can use that alias to qualify column references:
WHERE count_per_branch.no_contract =
But you cannot use that alias as a row source in another subquery, which is what you are trying to do here:
(SELECT max(count_per_branch.no_contract)
FROM count_per_branch)
To "reuse" a subquery in this manner, you have to use the Common Table Expression syntax -- i.e., the WITH clause.
I'm trying to insert value into my temporary table with the code below.
And I got this error
SAP Hana Database Error: cannot
use parameter variable: DOCENTRY: line 8 col 35 (at pos 127) 2 0
I don't know what is wrong,
Please give some advise
thanks
This is the code:
CREATE PROCEDURE REP_PROC11( in docentry nvarchar(2))
AS
totalval DECIMAL (19,6);
BEGIN
CREATE local TEMPORARY TABLE #TempItem AS (
select
'FGA000001' as "ItemCode",
'2IN' as "WhsCode",
ifnull(
(
select
"U_IM1_GR"
from "#OFNC" where "DocEntry" = :docentry
),0) as "Qty",
'11080302' as "Account",
'S02' as "ProfitCode",
'IN-PN' as "ProfitCode2"
from DUMMY
union all
select
'FGA000002' as "ItemCode",
'2IN' as "WhsCode",
ifnull(
(
select
U_IM2_GR
from "#OFNC" where "DocEntry" = :docentry
),0) as "Qty",
'11080302' as "Account",
'S02' as "ProfitCode",
'IN-FN' as "ProfitCode2" from dummy);
SELECT X.*, (X."Qty"*:totalval)/Y."TotalQty" as "Val", :totalval as "TotalVal"
FROM #TempItem X
LEFT JOIN (SELECT SUM(X1."Qty") as "TotalQty" FROM #TempItem X1) Y ON 1 = 1
WHERE X."Qty" > 0;
drop TABLE #TempItem;
end
That’s a limitation of the SQL in your DDL code - the CREATE TEMPORARY TABLE bit.
Given your code so far, you don’t need to use a temp. table but could yield the same result (with less resource usage) by using table variables.
I'm using Sql Server 2012.
I need to select rows from a table for processing. The number of rows needs to be variable. I need to update the rows I'm selecting to a "being processed" status - I have a guid to populate for this purpose.
I've encountered several examples of using row_number() and a couple of examples of ways of using CTE's, but I'm not sure on how to combine them (or if that's even the correct strategy). I would appreciate any insight.
Here is what I have so far:
DECLARE #SessionGuid uniqueidentifier, #rowcount bigint
SELECT #rowcount = 1000
SELECT #sessionguid = newid()
DECLARE #myProductChanges table (
ProductChangeId bigint
, ProductTypeId smallint
, SourceSystemId tinyint
, ChangeTypeId tinyint );
WITH NextPage AS
(
SELECT
ProductChangeId, ServiceSessionGuid,
ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS 'RowNum'
FROM dbo.ProductChange
WHERE 'RowNum' < #rowcount
)
UPDATE dbo.ProductChange
SET ServiceSessionGuid = #sessionguid, ProcessingStateId = 2, UpdatedDate = getdate()
OUTPUT
INSERTED.ProductChangeId,
INSERTED.ProductTypeId,
INSERTED.SourceSystemId,
INSERTED.ChangeTypeId
INTO #myProductChanges
FROM dbo.ProductChange as pc join NextPage on pc.ProductChangeId = NextPage.ProductChangeId
From here I will select from my temp table and return the data:
SELECT mpc.ProductChangeId
, pt.ProductName as ProductType
, ss.Name as SourceSystem
, ct.ChangeDescription as ChangeType
FROM #myProductChanges as mpc
join dbo.R_ProductType pt on mpc.ProductTypeId = pt.ProductTypeId
join dbo.R_SourceSystem ss on mpc.SourceSystemId = ss.SourceSystemId
join dbo.R_ChangeType ct on mpc.ChangeTypeId = ct.ChangeTypeId
ORDER BY ProductType asc
So far this doesn't work for me. I get an error when I try to run it:
Msg 8114, Level 16, State 5, Line 20
Error converting data type varchar to bigint.
I'm not clear on what I'm doing wrong - so - any help is appreciated.
Thanks!
BTW, here are some of the questions I've used as reference to try and solve this:
https://stackoverflow.com/questions/9777178
https://stackoverflow.com/questions/3319842
https://stackoverflow.com/questions/6402103
This subquery makes no sense:
SELECT
ProductChangeId, ServiceSessionGuid,
ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS 'RowNum'
FROM dbo.ProductChange
WHERE 'RowNum' < #rowcount
You can't reference the alias RowNum at the same scope (and you are trying to compare a string, not an alias, anyway), because when the WHERE clause is parsed, the SELECT list hasn't been materialized yet. What you need is either another nest:
SELECT ProductChangeId, ServiceSessionGuid, RowNum
FROM (SELECT ProductChangeId, ServiceSessionGuid,
ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS RowNum
FROM dbo.ProductChange
) AS x WHERE RowNum < #rowcount
Or:
SELECT TOP (#rowcount-1) ProductChangeId, ServiceSessionGuid,
ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS RowNum
FROM dbo.ProductChange
ORDER BY ProductChangeId
Also please stop using 'alias' - when you need to delimit aliases (you don't in this case), use [square brackets].
I'm guessing, but I think you want <= rather than < if you want to affect #rowcount rows, not one less.
Another tip is that CTEs can be updated directly*, as shown here:
WITH NextPage AS
(
SELECT TOP(#rowcount) *
FROM dbo.ProductChange
)
UPDATE NextPage
SET ServiceSessionGuid = #sessionguid, ProcessingStateId = 2, UpdatedDate = getdate()
OUTPUT
INSERTED.ProductChangeId,
INSERTED.ProductTypeId,
INSERTED.SourceSystemId,
INSERTED.ChangeTypeId
INTO #myProductChanges
* The updates affect the base table in the CTE, i.e. dbo.ProductChange
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