How to create an Update statement from a subquery in TSQL - tsql

I need to update all records that match my criteria. But the Sql below is giving this error:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
-- Set MasterAccountId = NULL where there is no Receivable with equivalent BillingAccountId and TaskAccountId
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
WHERE EXISTS ( SELECT * FROM MasterAccount M
WHERE (ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))
Basically, I need to update all records that return in that subquery.
Does any one know how to fix it?

Can you give a try on this. This is base from the repond of https://stackoverflow.com/users/40655/robin-day on this link How do I UPDATE from a SELECT in SQL Server?.
UPDATE
R
SET
R.MasterAccountId = NULL
FROM
Receivable R
INNER JOIN
MasterAccount M
ON
(ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))

I don't think you are getting the said error in posted query May be somewhere else. Again in your EXISTS subquery, instead of saying select * ... it's always better to say WHERE EXISTS ( SELECT 1 FROM MasterAccount M
Also try using the JOIN version of this query instead like
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
JOIN MasterAccount M ON M.BillingAccountId = R.BillingAccountId
OR M.TaskAccountId = R.TaskAccountId
WHERE ISNULL(M.BillingAccountId, 0) > 0
OR ISNULL(M.TaskAccountId, 0) > 0;

Related

Database migration syntax

I am unsure how to rewrite this. I understand the issue or at least I think I do. I am unable to use instances of t before it is defined by the follow "AS" statement. How can I resolve this so that so that it works the same way without using the instance of t before definition?
The error that I am getting thrown from the converter is "unable to convert .t"
Converted code
INSERT INTO t$trades_long (portfolio_name, fund, cusip, td_num, desc_instmt, trd_price, trd_trade_dt, t.trd_settle_dt, trd_counterparty, trd_td_par, tran_type, sec_type, trd_type, t.trd_trader)
SELECT
p.portfolio_name, t.fund, t.cusip, t.td_num, a.desc_instmt, t.trd_price, t.trd_trade_dt, t.trd_settle_dt, t.trd_counterparty, t.trd_td_par, t.tran_type, a.sec_type, 'long' AS trd_type, trd_trader
FROM pfi_pilot.br_transaction AS t, pfi_pilot.br_portfolio_group AS p, pfi_pilot.br_asset AS a
WHERE t.fund = p.fund AND p.portfolio_group = 'ALL_FUNDS' AND t.cusip = a.cusip AND t.tran_type IN ('BUY', 'SELL', 'ISSUE', 'ALLOC') AND t.trd_status <> 'C' AND a.sm_sec_group NOT IN ('CASH', 'FUTURE', 'FX', 'FUND', 'SWAP', 'OPTION') AND a.sec_type != 'MBS_TBA' AND t.trd_counterparty NOT IN ('IFUND', 'GHOST', 'SPO', 'SPOBO', 'CONV', 'ASSGN') AND t.trd_trade_dt >= par_from_dt AND t.trd_trade_dt <= par_to_dt AND t.cusip NOT IN (SELECT DISTINCT
cusip
FROM pfi_pilot.br_asset
WHERE (COALESCE(risk_country, country) = 'US' AND sm_sec_type IN ('GOVT', 'TBILL'))) AND t.trd_td_par > 0;
Original code
insert into #trades_long(portfolio_name, fund, cusip, td_num, desc_instmt, trd_price, trd_trade_dt, t.trd_settle_dt,
trd_counterparty, trd_td_par, tran_type , sec_type, trd_type, t.trd_trader)
select p.portfolio_name, t.fund, t.cusip, t.td_num, a.desc_instmt, t.trd_price, t.trd_trade_dt, t.trd_settle_dt,
t.trd_counterparty, t.trd_td_par, t.tran_type, a.sec_type,'long' as trd_type, trd_trader
from br_transaction t, br_portfolio_group p, br_asset a
where t.fund = p.fund
and p.portfolio_group = 'ALL_FUNDS'
and t.cusip = a.cusip
and t.tran_type in ('BUY','SELL','ISSUE','ALLOC')
and t.trd_status <> 'C'
and a.sm_sec_group not in ('CASH','FUTURE','FX','FUND','SWAP','OPTION')
and a.sec_type != 'MBS_TBA'
and t.trd_counterparty not in ('IFUND','GHOST','SPO','SPOBO','CONV','ASSGN')
and t.trd_trade_dt >= #from_dt
and t.trd_trade_dt <= #to_dt
and t.cusip not in (select distinct cusip from br_asset where (isnull(risk_country,country) = 'US'
and sm_sec_type in ('GOVT','TBILL')))
and t.trd_td_par > 0

Why does the gorm postgresql throws pq: syntax error at or near ")"?

SELECT_QUERY = `SELECT * FROM events WHERE c_id = ? AND start_time > ? and
end_time < ?`
query := sr.db.Raw(SELECT_QUERY, request.GetCId(), startTime, endTime)
var v = request.GetVIds()
if len(v) > 0 {
query = query.Where(` v_id IN (?) `, v)
} //Only this block introduces first ) after end_time
var c = request.GetStatus().String()
if len(c) > 0 {
query = query.Where( " status = ? ", c) // this introduces the other opening brace //after AND
}
Following is the query generated and found in logs
SELECT * FROM events WHERE c_id = 1 AND start_time > '2020-04-16 18:42:00' and
end_time < '2020-04-16 18:45:50' ) AND ( v_id IN (1,2)) AND ( status = 'STATUS_MIDDLE_CLASS' ORDER BY start_time DESC LIMIT 5 OFFSET 1
The other solution in stackoverflow and internet article doesn't help.
PS: Is it because I mix db.Raw( ) and query.Where() ?
Changing ? to $1 doesn't fix the issue.
Basically a few things fixed the issue.
1) Mixing Raw and query.Where was one issue.
After making the Raw query to sr.db.Where
2)
SELECT_QUERY = `SELECT * FROM events WHERE c_id = ? AND start_time > ? and
end_time < ?`
already has select * from. And then using query := sr.db.Raw(SELECT_QUERY, request.GetCId(), startTime, endTime) introduces nested select *.
So, changed SELECT_QUERY as follows
SELECT_QUERY = `events WHERE c_id = ? AND start_time > ? and
end_time < ?`
solved the issue.
I found a workaround to the error which I received when I tried to add a timestamp filed in Go/Gorm solution with PostgreSQL equivalent to default: now() which is default: time.Now().Format(time.RFC3339)
I received the error because I use AutoMigrate() to create the tables in PostgreSQL. The one problem I found is when trying to use the default value of a function instead of a string (which one can use for a fixed timestamp).
So I had to go into DataGrid (since I use JetBrains, but you can use any PostgreSQL admin tool like pgAdmin) and manually add the timestamp field with default of now() or merely update the existing field to add the default of now(). Then the error goes away when doing your next build in Go.

Multiple concurrent invocations of same query returning in same time as one invocation multiplied by the number of invocations

When running the following query on Postgres 10 using a connection pool in a concurrent manner, the results return in n * the length of time it takes to run one invocation.
Tested in Racket using threads and Node with promises. Both return ~ the same timings in milliseconds.
1 invocation:
8322
10 invocations:
82432, 82260, 82025, 82260, 82432, 82103, 82025, 82556, 82040, 82119
Here is the query:
WITH contact_searches as (select
md.geo_point as md_point, md.sf_id as md_name, md.sf_id as md_sf_id,
md.freehold_tenure as md_fh_ten,
md.freehold_search_price md_fh_sp, md.leasehold_tenure as md_lh_ten,
md.leasehold_search_price as md_lh_sp,
md.special_tenure_search_price as md_st_sp, md.geo_point as point,
ss.freehold_tenure as ss_fh_ten, ss.leasehold_tenure as ss_lh_ten,
ss.price_from as ss_pf, ss.price_to as ss_pt, md.marketing_trades as md_trades,
ss.trades as ss_trades,
ss.sf_id as ss_sf_id, ss.person_id as person_id, ss.areas as areas
from saved_searches ss
inner join marketing_details md on md.marketing_trades && ss.trades
where md.sf_id = ANY ($1)
and
((md.freehold_tenure is not null and ss.freehold_tenure ='true'
and (md.freehold_search_price is null or md.freehold_search_price >= ss.price_from)
and (md.freehold_search_price is null or md.freehold_search_price <= ss.price_to))
or
(md.leasehold_tenure is not null and ss.leasehold_tenure ='true'
and (md.leasehold_search_price is null or md.leasehold_search_price >= ss.price_from)
and (md.leasehold_search_price is null or md.leasehold_search_price <= ss.price_to))
or
(md.special_tenure_search_price is not null
and (md.special_tenure_search_price >= ss.price_from)
and (md.special_tenure_search_price <= ss.price_to))
)
), contact_ids as (select distinct person_id as sf_id
from contact_searches inner join areas a on st_contains(a.polygon, contact_searches.point)
where a.name = ANY (contact_searches.areas))
select c.sf_id, hasoptedoutofemail, preferred_contact_method, cco_email_opt_out, cf_email_opt_out, valid_email(c)
from contacts c inner join contact_ids on c.sf_id = contact_ids.sf_id where c.applicant_status = 'Live'
Does anyone have any insight as to whether complex queries don't run in parralell or whether there is a config change I could make or anything else that could help?

Kentico document query API always returns empty result

I have the following query:
var newsItems = tree.SelectNodes()
.Types(pageTypesArray)
.Path(path)
.OrderBy(orderBy)
.CombineWithDefaultCulture(false)
.Page(page, count)
.OnCurrentSite()
.NestingLevel(-1)
.Culture(CurrentDocument.DocumentCulture)
.InCategories(categories)
.TopN(topN)
.Where("ListableDocumentImage is not null AND ListableDocumentImage != ''")
.Columns(columns);
Which translates like so:
WITH AllData AS
(
SELECT TOP 6 * for brevity, ROW_NUMBER() OVER (ORDER BY [NewsOccurrenceDate] DESC) AS [CMS_RN]
FROM View_CMS_Tree_Joined AS V WITH (NOLOCK, NOEXPAND) INNER JOIN SOS_News AS C WITH (NOLOCK) ON [V].[DocumentForeignKeyValue] =
[C].[NewsID] AND V.ClassName = N'News' LEFT OUTER JOIN COM_SKU AS S WITH (NOLOCK) ON [V].[NodeSKUID] = [S].[SKUID]
WHERE [NodeSiteID] = #NodeSiteID AND (([DocumentCanBePublished] = 1 AND ([DocumentPublishFrom] IS NULL OR [DocumentPublishFrom] <= #Now)
AND ([DocumentPublishTo] IS NULL OR [DocumentPublishTo] >= #Now))
AND [NodeAliasPath] LIKE #NodeAliasPath AND [DocumentCulture] = #DocumentCulture
**AND 0 = 1)** <<<------------------- WHERE DID THIS COME FROM?????
)
SELECT *, (SELECT COUNT(*) FROM AllData) AS [CMS_TOT]
FROM AllData
WHERE CMS_RN BETWEEN 4 AND 6
ORDER BY CMS_RN
Has anyone ever come across anything like this before? I can't figure out why they're sticking in the AND 0=1 in my where clause.
Properly structuring your document API call will help with this. In your query results, you can see your WHERE condition is not even being added so it does make a difference the order of the methods being called.
For instance:
var newsItems = tree.SelectNodes()
.Types(pageTypesArray)
.Path(path)
.Where("ListableDocumentImage is not null AND ListableDocumentImage != ''")
.TopN(topN)
.OrderBy(orderBy)
.CombineWithDefaultCulture(false)
.Page(page, count)
.NestingLevel(-1)
.Culture(CurrentDocument.DocumentCulture)
.InCategories(categories)
.OnCurrentSite()
.Columns(columns);

Updating using subqueries sql server 2008

There are two update queries and 1st update query execute successfully but 2nd update query is not execute and show the following message:
Msg 512, Level 16, State 1, Line 10
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. The statement has been terminated.
1st update query:
update dbo.TblPrePostApproval
set
dbo.TblPrePostApproval.PAApprovedDate = (select dbo.TblMasterInfo.AppRefDate
from dbo.TblMasterInfo
Where dbo.TblMasterInfo.Appid = dbo.TblPrePostApproval.Appid),
dbo.TblPrePostApproval.PAApprovedTenor = '36',
dbo.TblPrePostApproval.PAApprovedAmt = (select dbo.TblMasterInfo.AppReqeustAmt
from dbo.TblMasterInfo
where dbo.TblPrePostApproval.Appid = dbo.TblMasterInfo.AppID),
dbo.TblPrePostApproval.PADisbBr = (select dbo.TblMasterInfo.AppSourceBrName
from dbo.TblMasterInfo
where dbo.TblPrePostApproval.Appid = dbo.TblMasterInfo.AppID)
2nd update query
update dbo.TblPrePostApproval
set
dbo.TblPrePostApproval.PAApprovedDate = (select dbo.TestPost.PADate
from dbo.TestPost
Where dbo.TestPost.Appid = dbo.TblPrePostApproval.Appid),
dbo.TblPrePostApproval.PAApprovedTenor = (select dbo.TestPost.PATenor
from dbo.TestPost
Where dbo.TestPost.Appid = dbo.TblPrePostApproval.Appid),
dbo.TblPrePostApproval.PAApprovedAmt = (select dbo.TestPost.PAAmt
from dbo.TestPost
where dbo.TestPost.Appid = dbo.TblPrePostApproval.AppID),
dbo.TblPrePostApproval.PADisbBr = (select dbo.TestPost.PABr
from dbo.TestPost
where dbo.TestPost.Appid = dbo.TblPrePostApproval.AppID)
Where is my problem? Pls any one suggest me.
One of your subqueries (I guess on line 10) is returning more than one row, so it can't check to see if it equals anything, because it's a set, not a value. Just change your query to be more specific. Try adding LIMIT 0, 1 to the end of the subqueries, or TOP (1) after the the SELECT in each subquery.
Why don't you use JOINs for your update? Much easier to read and understand!
Query #1:
UPDATE ppa
SET
PAApprovedDate = info.AppRefDate,
PAApprovedTenor = '36',
PAApprovedAmt = info.AppReqeustAmt,
PADisbBr = info.AppSourceBrName
FROM
dbo.TblPrePostApproval ppa
INNER JOIN
dbo.TblMasterInfo.TblMasterInfo info ON info.Appid = ppa.Appid
Query #2:
UPDATE ppa
SET
PAApprovedDate = tp.PADate,
PAApprovedTenor = tp.PATenor,
PAApprovedAmt = tp.PAAmt,
PADisbBr = tp.PABr
FROM
dbo.TblPrePostApproval ppa
INNER JOIN
dbo.TestPost tp ON tp.Appid = ppa.AppID