Update a column using the value of another column per row - postgresql

I'm trying to update a value in one table based on the value of another table in a one-to-many relationship, where there will be one movie but many reviews
Here's the schema for my tables
movie
+----+-------------+------+
| id | reviewCount |score |
+----+-------------+------+
review
+--------+---------+-------+
| userId | movieId | score |
+--------+---------+-------+
And here's the query I'm trying to run
UPDATE movie
SET score =
CASE
WHEN m."reviewCount" = 1
THEN 0
ELSE ((m.score * m."reviewCount") - r.score) / (m."reviewCount" - 1)
END,
"reviewCount" = m."reviewCount" - 1
FROM movie AS m INNER JOIN (
SELECT "userId", "movieId", score
FROM review) r
ON m.id = r."movieId"
WHERE r."userId" = $1;
However, when I run it, I get the same value across all my rows rather than accounting for the score of each review. Is there something I'm doing wrong or a better way to run this query?

As documented in the manual you should not repeat the target table of an UPDATE in the FROM clause.
There is also no need for a derived table ("sub-query") to get the values from the review table:
UPDATE movie m
SET score = CASE
WHEN m."reviewCount" = 1 THEN 0
ELSE ((m.score * m."reviewCount") - r.score) / (m."reviewCount" - 1)
END,
"reviewCount" = m."reviewCount" - 1
FROM review r
WHERE m.id = r."movieId" --<< this is the join between the two tables
AND r."userId" = $1;
This assumes that each user only reviews each movie once (i.e. one row per userid/movied combination in the review table). If that is not the case, the outcome is not predictable.

Last line should have
ON m.id = r."movieId"
WHERE movie.id = r."movieId" AND r."userId" = $1;
rather than m.id = r."movieId"

Related

T-SQL Question for Getting One Customer Type When There Can be More Than One Value

We have an organization that can have more than one customer type basically. However, what a user wants to see is either the partner or direct type (customer type is either Direct, Partner1, Partner2, or Partner3 but can be direct plus a partner value but only can be one of the partner values). So if a customer is both (ex: Direct and Partner1) they just want the type that is a partner (ex: Partner1). So I tried splitting out partners only into one temp table from a few tables joining together different org data. I have the same query without any limit pulling into a different temp table. Then I calculate count and put that into a temp table. Then I tried gathering data from all the temp tables. That is where I run into trouble and lose some of the customers where the type is direct (I have a image link below for a directcustomer and a customer who is both). I have been out of SQL for a bit so this one is throwing me...I figure the issue is the fact that I have a case statement referencing a table that a direct customer will not exist in (#WLPO). However I am not sure how to achieve pulling in these customers while also only selecting which partner type it is for a customer that has a partner and is also direct. FYI using MSSMS for querying.
If OBJECT_ID('tempdb..#WLPO') IS NOT NULL
DROP TABLE #WLPO
IF OBJECT_ID('tempdb..#org') IS NOT NULL
DROP TABLE #org
IF OBJECT_ID('tempdb..#OrgCount') IS NOT NULL
DROP TABLE #OrgCount
IF OBJECT_ID('tempdb..#cc') IS NOT NULL
DROP TABLE #cc
Select
o.OrganizationID,
o.OrganizationName,
os.WhiteLabelPartnerID,
s.StateName
INTO #WLPO
from [Org].[Organizations] o
join [Org].[OrganizationStates] os on o.OrganizationID=os.OrganizationID --and os.WhiteLabelPartnerID = 1
join [Lookup].[States] s on os.StateID = s.StateID
join [Org].[PaymentOnFile] pof on pof.OrganizationID=o.OrganizationID
where os.WhiteLabelPartnerID in (2,3,4)
and os.StateID in (1, 2, 3)
and o.OrganizationID = 7613
select * from #WLPO
Select
o.OrganizationID,
o.OrganizationName,
os.WhiteLabelPartnerID,
s.StateName
INTO #org
from [Org].[Organizations] o
join [Org].[OrganizationStates] os on o.OrganizationID=os.OrganizationID --and os.WhiteLabelPartnerID = 1
join [Lookup].[States] s on os.StateID = s.StateID
join [Org].[PaymentOnFile] pof on pof.OrganizationID=o.OrganizationID
where 1=1--os.WhiteLabelPartnerID = 1
and os.StateID in (1, 2, 3)
and o.OrganizationID = 7613
select * from #org
Select
OrganizationID,
count(OrganizationID) AS CountOrgTypes
INTO #OrgCount
from #org
where OrganizationID = 7613
group by OrganizationID
select * from #OrgCount
Select distinct
ct.OrganizationID,
ok.OrganizationName,
ct.CountOrgTypes,
case when ct.CountOrgTypes = 2 then wlp.WhiteLabelPartnerID
when ct.CountOrgTypes = 1 then ok.WhiteLabelPartnerID
END AS CustomerTypeCode,
case when ct.CountOrgTypes = 2 then wlp.StateName
when ct.CountOrgTypes = 1 then ok.StateName END As OrgState
INTO #cc
from #org ok
left join #WLPO wlp on wlp.OrganizationID=ok.OrganizationID
join #OrgCount ct on wlp.OrganizationID=ct.OrganizationID
select * from #cc
Select
OrganizationID,
OrganizationName,
CountOrgTypes,
case when CustomerTypeCode = 1 then 'Direct'
when CustomerTypeCode = 2 then 'Partner1'
when CustomerTypeCode = 3 then 'Partner2'
when CustomerTypeCode = 4 then 'Partner3' ELSE Null END AS CustomerType,
OrgState
from #cc
order by OrganizationName asc
DirectCustomer
CustomerwithBoth

Postgresql Update & Inner Join

I am trying to update data in Table: local.import_payments from Table: local.payments based on update and Inner Join queries. The query I used:
Update local.import_payments
Set local.import_payments.client_id = local.payments.payment_for_client__record_id,
local.import_payments.client_name = local.payments.payment_for_client__company_name,
local.import_payments.customer_id = local.payments.customer__record_id,
local.import_payments.customer_name = local.payment_from_customer,
local.import_payments.payment_id = local.payments.payment_id
From local.import_payments
Inner Join local.payments
Where local.payments.copy_to_imported_payments = 'true'
The client_id, client_name, customer_id, customer_name in the local.import_payments need to get updated with the values from the table local.payments based on the condition that the field copy_to_imported_payments is checked.
I am getting a syntax error while executing the query. I tried a couple of things, but they did not work. Can anyone look over the queries and let me know where the issue is
Try the following
UPDATE local.import_payments
Set local.import_payments.client_id =
local.payments.payment_for_client__record_id,
local.import_payments.client_name =
local.payments.payment_for_client__company_name,
local.import_payments.customer_id = local.payments.customer__record_id,
local.import_payments.customer_name = local.payment_from_customer,
local.import_payments.payment_id = local.payments.payment_id
FROM local.payments as lpay
WHERE lpay.<<field>> = local.import_payments.<<field>>
AND local.payments.copy_to_imported_payments = 'true'
You shouldn't to specify the schema/table for updated columns, only column names:
Do not include the table's name in the specification of a target column — for example, UPDATE table_name SET table_name.col = 1 is invalid.
from the doc
You shouldn't to use the updating table in the from clause except of the case of self-join.
You can to make your query shorter using "column-list syntax".
update local.import_payments as target
set (
client_id,
client_name,
customer_id,
customer_name,
payment_id) = (
source.payment_for_client__record_id,
source.payment_for_client__company_name,
source.customer__record_id,
source.payment_from_customer,
source.payment_id)
from local.payments as source
where
<join condition> and
source.copy_to_imported_payments = 'true'

Apply join on two result set - Postgres

I have query that gives me the documentid
select documentid from tbldocumentbyclient
where tbldocumentbyclient.isactive = true
and applicationid = '000116'
result:
Another query that give me the following result
SELECT documentcategory,documentcategoryid, string_agg(documentid::text, ',') as documentid
FROM tbldocumentmaster
where accounttype = 1 and usertype= 'INDIVIDUAL'
group by documentcategory,documentcategoryid
order by documentcategoryid;
result :
[![enter image description here][2]][2]
Now,Can someone please suggest me how to get CategoryName that is not associated with any documentid
For Above case my result should be following.
DP Proof - 134 not available in first result
Address Proof Permanent - row 4.. not a single id available in documenid result
Here this are the documentcategory that is not associate with any document id
I think a simple join between your two tables should do the trick. The logic here is if a document category from tbldocumentmaster really has no document IDs which match to anything in the tbldocumentbyclient table then the join should filter it off, leaving behind those categories which do match.
SELECT t1.documentcategory
FROM tbldocumentmaster t1
LEFT JOIN tbldocumentbyclient t2
ON t1.documentid = t2.documentid
WHERE t2.isactive = true AND
t2.applicationid = '000116' AND
t1.accounttype = 1 AND
t1.usertype = 'INDIVIDUAL' AND
t2.documentid IS NULL
try this:
SELECT distinct documentcategory,documentcategoryid
FROM tbldocumentmaster m
LEFT OUTER JOIN tbldocumentbyclient d on d.documentid = m.documentid
where accounttype = 1 and usertype= 'INDIVIDUAL'
and m.documentid is null
and applicationid = '000116'
group by documentcategory,documentcategoryid
order by documentcategoryid;
I have not tested but you can try this query:
SELECT documentcategory,documentcategoryid, string_agg(documentid::text, ',') as documentid
FROM tbldocumentmaster
where accounttype = 1 and usertype= 'INDIVIDUAL' and documentid not in (select documentid from tbldocumentbyclient where tbldocumentbyclient.isactive = true and applicationid = '000116')
group by documentcategory,documentcategoryid
order by documentcategoryid;

Update big amount of data postgresql

The main table used is transaction, and can store million rows (let's say 4-5 million max). I need to update a status as fast as possible.
The update query looks like this :
UPDATE transaction SET transaction.status = 'TO_EXECUTE'
WHERE transaction.id IN (SELECT transaction.id FROM transaction
JOIN anotherTable ON transaction.id = anotherTable.id
JOIN anotherTable2 ON transaction.serviceId = ontherTable2.id
WHERE transaction.status = :filter1, transaction.filter2 = :filter2, ...)
Do you have a better solution? Could it be better to create another table to store the status an the id ? (I red that updating large Tables can be really slow).
The IN part of your query could likely be re-written as "exists" to potentially get improvements, depending on the other table layouts and volume. Also, it's highly possible that you do not need the transaction table mentioned yet again in the sub query (exists or in)
UPDATE transaction tx SET transaction.status = 'TO_EXECUTE'
WHERE exists (SELECT *
FROM anotherTable
JOIN anotherTable2 ON tx.serviceId = anotherTable2.id
WHERE anothertable.id=tx.id and
transaction.status = :filter1 and transaction.filter2 = :filter2,
...)
try this:
UPDATE transaction
SET transaction.status = 'TO_EXECUTE'
From anotherTable
JOIN anotherTable2 ON transaction.serviceId = anotherTable2.id
WHERE transaction.id = anotherTable.id AND transaction.status = :filter1, transaction.filter2 = :filter2, ...

How to join the tables in linq to sql?

Table1 :
userid name address
1 venkat srinagr
2 venkatesh sainagar
Table2:
id userid lat lon
1 1 14.000 15.000
2 2 14.3526 15.3698
by passing "venkat" as parameter then need to pull all matching records and his userid,name,lat,lon.
in above table1 "venkat" contains in both rows then need to pull 2 records.how to get userid,name,lat,lon for all matching rows..
for sigle record i am able to get.but there are multiple rows how to get please tell me....
var result = from p in cxt.Table2
where p.Table1.Name.Contains(name)
select new
{
p.Users.User_Id,p.Users.Name,p.Latitude,p.Longitude
};
Im sure someone will say this is not the most effective way but this is how i would do it.
string InputString = "venkat";
var tab =(from a in db.tablea
from b in db.tableb
where a.userid == b.userid && a.name == InputString
select new
{
UserID = a.userid,
Username = a.name,
Latitude = b.lat,
Longditude = b.lon
}).FirstOrDefault();
FirstOrDefault() is only if you want to force only one output or null,
if you want a collection of some sort, then just remove it.