How to get the Values of recently inserted columns from Temporary Table? - sql

I am not able to use the recently inserted Quantity value of #ACCT table in the Select statement to be used like
ser.ServiceRate * Quantity
Every time I get the ERROR
Cannot insert the value NULL into column 'Amount'
I am just a beginner so any pointers to solve this would help.
DECLARE #MinReservationId INT = (SELECT MIN(f.ReservationId) FROM dbo.Reservation AS f)
DECLARE #MaxReservationId INT = (SELECT MAX(f.ReservationId) FROM dbo.Reservation AS f)
DECLARE #QuantityNew INT
WHILE #MinReservationId <= #MaxReservationId
BEGIN
CREATE TABLE #Acct
(
ServiceId INT,
Quantity INT --> I WANT THIS VALUE TO BE USED BELOW
)
INSERT INTO dbo.[Transaction]
(
ReservationId,
ServiceId,
Rate,
Quantity,
Amount
)
OUTPUT inserted.ServiceId,Inserted.Quantity
INTO #Acct
(
ServiceId,
Quantity
)
SELECT
#MinReservationId,
ser.ServiceId,
ser.ServiceRate,
ABS(CHECKSUM(NEWID())%3) + 1,
ser.ServiceRate * (SELECT acc.Quantity from #Acct as acc) -> QUANTITY from #ACCT should be used here
FROM dbo.[Service] AS ser
SELECT #MinReservationId=#MinReservationId+1
Drop table #Acct
END

You can use a CTE in order to capture the NEWID() value created for every record of table dbo.[Service]. Then use this CTE to do the INSERT:
;WITH ToInsert AS
(
SELECT ServiceId ,
ServiceRate,
ABS(CHECKSUM(NEWID())%3) + 1 AS Quantity
FROM dbo.[Service]
)
INSERT INTO dbo.[Transaction]
(
ReservationId,
ServiceId,
Rate,
Quantity,
Amount
)
SELECT #MinReservationId,
ServiceId,
ServiceRate,
Quantity,
ServiceRate * Quantity
FROM ToInsert

Related

Get max date based on another column in SQL

I have a table variable which consists of columns id, date and status as shown below
DECLARE #DateValues TABLE (
id int identity(1,1),
dates datetime,
status varchar (5)
)
And follows is the sample data
INSERT INTO #DateValues values ('5/22/2021','')
INSERT INTO #DateValues values ('5/21/2021','ABC')
INSERT INTO #DateValues values ('5/22/2021','ABC')
Also declared a variable as shown below.
DECLARE #MaxID INT
From this table I need to get the row which containing the maximum value of date( MAX(dates) ) where status is 'ABC', from the above sample values, I should get the 3rd row as the result and I need to assign the corresponding id value of the row id to a variable (#MaxID).
I tried following queries but getting multiple result set
SELECT id, MAX(dates), Footer
FROM #DateValues
WHERE STATUS = 'ABC'
GROUP BY id, STATUS
SELECT id, dates, status
FROM #DateValues
WHERE dates = (
SELECT MAX(dates)
FROM #DateValues
);
I need something like:
#MaxID = id
FROM #DateValues
WHERE dates = (
SELECT MAX(dates)
FROM #DateValues
WHERE STATUS='ABC'
);
Please help.
Is this what you want?
SELECT *
FROM (
SELECT *, RN = ROW_NUMBER() OVER (ORDER BY dates DESC)
FROM #DateValues
WHERE status = 'ABC'
) AS D
WHERE D.RN = 1

An aggregate may not appear in the set list of an UPDATE statement T-SQL

In T-SQL I'm attempting to update a stock user field with the number of weeks we expect it to be delivered to us by taking the difference between today and the purchase order due in dates. However the select query can return more than one line of purchase orders if there is more than one purchase order containing that product (obviously). I would like to take the smallest number it returns / minimum value but obviously cannot do this within the update query. Can anyone recommend a workaround? Thanks.
UPDATE [Exchequer].[ASAP01].[STOCK]
SET stUserField7 = DATEDIFF(day,CONVERT(VARCHAR(8), GETDATE(), 112),min(tlLineDate)) / 7 + 1
FROM [Exchequer].[ASAP01].[STOCK]
JOIN [Exchequer].[ASAP01].[CUSTSUPP]
ON stSupplier = acCode
JOIN [Exchequer].[ASAP01].[DETAILS]
ON stCode = tlStockCodeTrans1
WHERE stSupplier <> '' AND stQtyOnOrder > '0' AND stQtyOnOrder > stQtyAllocated
AND tlOurRef like 'POR%' AND (floor(tlQtyDel) + floor(tlQtyWOFF)) < floor(tlQty)
AND tlLineDate >= CONVERT(VARCHAR(8),GETDATE(), 112)
Why are you casting date to varchar for the difference?
This is not date but how you can use a window function in an update
declare #maps table(name varchar(10), isUsed bit, code varchar(10));
insert into #Maps values
('NY', 1, 'NY1')
, ('NY', 0, 'NY2')
, ('FL', 0, 'FL1')
, ('TX', 0, 'TX1')
declare #Results table (id int identity primary key, Name varchar(20), Value int, Code varchar(20), cnt int)
insert into #results values
('FL', 12, 'FL1', null)
, ('TX', 54, 'TX1', null)
, ('TX', 56, 'TX1', null)
, ('CA', 50, 'CA1', null)
, ('NJ', 40, 'NJ1', null)
select * from #results
order by name, Value desc
update r
set r.cnt = tt.cnt
from #results r
join ( select id, max(value) over (partition by name) as cnt
from #Results
) tt
on r.id = tt.id
select * from #results
order by name, value desc
Build a SELECT query with columns for the following:
The primary key of the [Exchequer].[ASAP01].[STOCK] table
The new desired stUserField7
Given the MIN(tlLineDate) expression in the original question, if this SELECT query does not have either a GROUP BY clause or change to use an APPLY instead of a JOIN, you've probably done something wrong.
Once you have that query, use it in an UPDATE statement like this:
UPDATE s
SET s.stUserField7 = t.NewValueFromSelectQuery
FROM [Exchequer].[ASAP01].[STOCK] s
INNER JOIN (
--- your new SELECT query here
) t ON t.<primary key field(s)> = s.<primary key field(s)>

Find missing numbers with SQL

In a large log file I have records containing the field INVNO (invoice-number).
The lowest and highest values are easy to find, BUT it looks like some numbers in between are not there.
Anyone got a trick with SQL, which can tell which numbers are missing within the number range?
use the following table valued function that takes 2 parameters : the min and max numbers,
and returns a list of missing number,
suppose your table name is YOUR_TABLE and the column name called InvNo
create FUNCTION [dbo].[MissingInvoiceNumbers]
(
#minPaym bigint,
#MaxPaym bigint
)
RETURNS #tmp table(numbers bigint)
AS
BEGIN
declare #n bigint --#minPaym bigint , #MaxPaym bigint,
declare #tmpAll table(Allnumbers bigint)
set #n= #minPaym
delete #tmp
delete #tmpAll
while (#n<=#MaxPaym)
begin
INSERT INTO #tmpAll
(AllNUMBERS)
VALUES (#n)
set #n=#n+1
end
INSERT INTO #tmp
(numbers)
SELECT Allnumbers
FROM #tmpAll
where Allnumbers not in (select distinct convert(bigint,InvNo) as InvoiceNum from YOUR_TABLE where
InvNo <> '' )
return
END
For oracle this should work. For any other database you just need to change way to generate the number sequence.
with vals as (
select rownum r
from dual
connect by rownum between {min} and {max}
)
select *
from vals v
left join {sometable} s on s.{someid} = v.r
where s.{someid} is null
The trick is just to generate numbers between min and max value, join table with invoices to this generated sequence and filter out everything that match.
Just join the table on itself...
DECLARE #tvp TABLE ( INVNO INT )
INSERT INTO #tvp
VALUES ( 1 ),
( 2 ),
( 3 ),
( 5 ),
( 6 ),
( 7 ),
( 8 ),
( 9 ),
( 10 ),
( 11 )
SELECT *
FROM #tvp;
SELECT t.INVNO + 1
FROM #tvp t
LEFT OUTER JOIN #tvp x ON x.INVNO = t.INVNO + 1
WHERE ISNULL(x.INVNO, 0) = 0;

Assign multiple values to Table variable in SQL

DECLARE #ID INT
SET #ID = (select top 1 USER_REQ_JOB_ID
from T8504_USER_REQ_JOB
where JOB_GRP_ID = 160
order by LST_UPDT_TS desc)
SELECT INPUT_PARM_VAL_TX
from TBL_RPT_JOB_INPUT_PARAM
where USER_REQ_JOB_ID = #ID
This returns these results:
USA
USCC
6
7
2
These five records what I get I want to assign to five different variables to use in stored procedure.
I was trying with table variable like this :
declare #CID table (
Region Char(3)
,Segment Char(3)
,MasterContractId int
,ctcid int
,templateid int)
insert into #CID (Region,Segment,MasterContractId,ctcid,templateid)
But how to insert that 5 rows here?
INSERT INTO #CID
select * from
(
select
'Temp' + convert(char(1), row_number() over (order by (select 0))) as columnName,
INPUT_PARM_VAL_TX as Value
from TBL_RPT_JOB_INPUT_PARAM where USER_REQ_JOB_ID = #ID
) d
pivot
(
max(value)
for columnname in (Temp1, Temp2, Temp3, Temp4, Temp5)
) piv;
See if this helps.
Take a look at this fiddle for an example.
Courtesy:
Add row number to this T-SQL query
Efficiently convert rows to columns in sql server
EDIT: The sql adds an extra column to generate row numbers to use it as an extra column, which is pivoted as column heading.
it's really gross, but one way you could probably do it is this (though you'll need to apply it to your case):
http://sqlfiddle.com/#!6/d41d8/21507
declare #table TABLE (value varchar(50))
INSERT INTO #table
VALUES ('first')
INSERT INTO #table
VALUES ('second')
INSERT INTO #table
VALUES (3)
INSERT INTO #table
VALUES (4)
DECLARE #temp TABLE (id int identity(1,1), value varchar(50))
INSERT INTO #temp
SELECT [value]
FROM #table t
SELECT *
FROM #temp
DECLARE #CID TABLE (Region varchar(50), cont varchar(50), another int, andAnother int)
INSERT INTO #CID
(
Region,
cont,
another,
andAnother
)
VALUES
(
(SELECT value FROM #temp WHERE id = 1), -- Region - varchar
(SELECT value FROM #temp WHERE id = 2), -- cont - varchar
(SELECT value FROM #temp WHERE id = 3), -- another - int
(SELECT value FROM #temp WHERE id = 4) -- andAnother - int
)
SELECT * FROM #cid
note that i assumed you're using mssql, you did not specify

transact-sql question

Assume there were 100 records in tableA and tableA contained a column named 'price'.
How do I select the first-n record if where sum of price > a certain amount (e.g. 1000) without using cursor?
thanks
Top N implies some kind of order, which you did not supply, so I assumed any random order.
You can change this on the OVER clause of the ROW_NUMBER().
Try something like
DECLARE #Table TABLE(
Price FLOAT
)
INSERT INTO #Table SELECT 1
INSERT INTO #Table SELECT 11
INSERT INTO #Table SELECT 12
INSERT INTO #Table SELECT 15
INSERT INTO #Table SELECT 10
INSERT INTO #Table SELECT 65
INSERT INTO #Table SELECT 100
DECLARE #TotalPrice FLOAT
SELECT #TotalPrice = 100
;WITH Vals AS (
SELECT *,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RNR
FROM #Table
)
, Totals AS (
SELECT v.RNR,
SUM(vP.Price) TotalPrice
FROM Vals v LEFT JOIN
Vals vP ON v.RNR >= vP.RNR
GROUP BY v.RNR
)
, LimitValue AS (
SELECT TOP 1
RNR
FROM Totals
WHERE TotalPrice >= #TotalPrice
ORDER BY RNR
)
SELECT *
FROM Vals
WHERE RNR <= (
SELECT RNR
FROM LimitValue
)
select price from tableA
where price > 1000
limit n;
n - no. of records you want in result set
--
Cheers