PostgreSQL update not working as expected - sql

With 20+ years of experience with MS Access and SQL Server, I'm not a novice with respect to SQL, but I am new to PostgreSQL and I have encountered an issue that makes me feel like a complete noob. I have a simple UPDATE query in which I want to update the destination table d with data from the source View m:
UPDATE chgman.tc_data
SET reporttime = m.reporttime, endtime = m.endtime,
itismessage = m.itismessage, shortdesc = m.shortdesc,
longdesc = m.longdesc, severity = m.severity,
tc_source = m.tc_source, tc_state = m.tc_state,
ushr_state = m.ushr_state, mainroad = m.mainroad,
start_location = m.start_location, end_location = m.end_location
FROM
chgman.tc_matched_raw AS m
INNER JOIN
chgman.tc_data AS d ON d.tc_id = m.tc_id;
The result of the query is that EVERY row in table d is populated with data from the FIRST row of View m.
I am prepared for the embarrassment - please enlighten me as to what I have done wrong...

The from/update in Postgres works a bit differently from SQL Server/MS Access.
This should do what you want:
UPDATE chgman.tc_data d
SET reporttime = m.reporttime, . . .
FROM chgman.tc_matched_raw m
WHERE d.tc_id = m.tc_id;
You don't repeat the table in the FROM clause -- that is a new reference to the table.

Related

Find matching rows in database table using SQL where no matching key is present

I have an old table with legacy data and approx 10,000 rows and a new table with about 500 rows. The columns are the same in both tables. I need to compare a few columns in the new table with the old one and report on data that is duplicated in the new table.
I've researched articles with similar issues, attempted table joins and where exists / where not exists clauses but I just can't get the SQL right. I have included my latest version.
One issue causing trouble for me, I think, is that there is no "Key" as such like a userid or similar unique identifier in either table.
What I want to do is find the data in the "new" table where all rows except for the "reference_number" (doesn't matter if it does or does not) is duplicated, i.e. exists already in the "old" table.
I have this so far...
select
old.reference_number
new.reference_number
new.component
new.privileges
new.protocol
new.authority
new.score
new.means
new.difficulty
new.hierarchy
new.interaction
new.scope
new.conf
new.integrity
new.availability
new.version
from old, new
where
old.component = new.component
old.privileges = new.privileges
old.protocol = new.protocol
old.authority = new.authority
old.score = new.score
old.means = new.means
old.difficulty = new.difficulty
old.hierarchy = new.hierarchy
old.interaction = new.interaction
old.scope = new.scope
old.conf = new.conf
old.integrity = new.integrity
old.availability = new.availability
old.version = new.version
I have tried this here but it doesn't seem to pull out ALL of the data for some reason.
It is evident that actually there are MORE rows in the old table that are duplicated in the new table but I'm only getting a small number of rows returned from the query.
Can anyone spot why that might be, is there another way I should be approaching this?
If it matters, this is Postgresql.
Thanks for any help given.
The following should do what you want:
select distinct o.reference_number,
n.reference_number,
n.component,
n.privileges,
n.protocol,
n.authority,
n.score,
n.means,
n.difficulty,
n.hierarchy,
n.interaction,
n.scope,
n.conf,
n.integrity,
n.availability,
n.version
from new n
inner join old o
on o.component = n.component and
o.privileges = n.privileges and
o.protocol = n.protocol and
o.authority = n.authority and
o.score = n.score and
o.means = n.means and
o.difficulty = n.difficulty and
o.hierarchy = n.hierarchy and
o.interaction = n.interaction and
o.scope = n.scope and
o.conf = n.conf and
o.integrity = n.integrity and
o.availability = n.availability and
o.version = n.version
You should use left join and then select only rows with new values is null. sql should be something like this:
select
old.reference_number
new.reference_number
new.component
new.privileges
new.protocol
new.authority
new.score
new.means
new.difficulty
new.hierarchy
new.interaction
new.scope
new.conf
new.integrity
new.availability
new.version
from old
left join new
on
old.component = new.component
old.privileges = new.privileges
old.protocol = new.protocol
old.authority = new.authority
old.score = new.score
old.means = new.means
old.difficulty = new.difficulty
old.hierarchy = new.hierarchy
old.interaction = new.interaction
old.scope = new.scope
old.conf = new.conf
old.integrity = new.integrity
old.availability = new.availability
old.version = new.version
where new.component is null

MS Access UPDATE Query errors

I am having a hard time using MS Access because the syntax is a little finicky compared to other db's.
I am trying to validate a table and compare that table to a master table with multiple columns of information. At the moment I am trying to update a table with a field name of Difference_Value in table ct2011 to be equal to (ct2011.Distribution_Amount - AggregateFinal.SumOfDollars).
Also specifying the lines in which are going to be updated because not all rows in the MASTER are in the table ct2011.
Below is my query.
UPDATE ct2011
SET ct2011.Difference_Value = (ct2011.Distribution_Amount - AggregateFinal.SumOfDollars)
FROM
ct2011 as ct
INNER JOIN
AggregateFinal af
ON
ct.Employee_ID = af.EmpId AND ct.Legal_Name = af.LegalName AND ct.Distribution_Plan_Year = af.CalculationAwardPeriod AND ct.Award_Year = af.AwardPeriod;
I am getting a Syntax error (missing operator). It specifies that it is encountering the error during the SET expressions after the =.
In an MS Access update query, the join criteria should follow the update keyword, e.g.:
update
ct2011 ct inner join aggregatefinal af on
ct.employee_id = af.empid and
ct.legal_name = af.legalname and
ct.distribution_plan_year = af.calculationawardperiod and
ct.award_year = af.awardperiod
set
ct.difference_value = (ct.distribution_amount - af.sumofdollars)

SQL GROUP BY function returning incorrect SUM amount

I've been working on this problem, researching what I could be doing wrong but I can't seem to find an answer or fault in the code that I've written. I'm currently extracting data from a MS SQL Server database, with a WHERE clause successfully filtering the results to what I want. I get roughly 4 rows per employee, and want to add together a value column. The moment I add the GROUP BY clause against the employee ID, and put a SUM against the value, I'm getting a number that is completely wrong. I suspect the SQL code is ignoring my WHERE clause.
Below is a small selection of data:
hr_empl_code hr_doll_paid
1 20.5
1 51.25
1 102.49
1 560
I expect that a GROUP BY and SUM clause would give me the value of 734.24. The value I'm given is 211461.12. Through troubleshooting, I added a COUNT(*) column to my query to work out how many lines it's running against, and it's giving a result of 1152, furthering reinforces my belief that it's ignoring my WHERE clause.
My SQL code is as below. Most of it has been generated by the front-end application that I'm running it from, so there is some additional code in there that I believe does assist the query.
SELECT DISTINCT
T000.hr_empl_code,
SUM(T175.hr_doll_paid)
FROM
hrtempnm T000,
qmvempms T001,
hrtmspay T166,
hrtpaytp T175,
hrtptype T177
WHERE 1 = 1
AND T000.hr_empl_code = T001.hr_empl_code
AND T001.hr_empl_code = T166.hr_empl_code
AND T001.hr_empl_code = T175.hr_empl_code
AND T001.hr_ploy_ment = T166.hr_ploy_ment
AND T001.hr_ploy_ment = T175.hr_ploy_ment
AND T175.hr_paym_code = T177.hr_paym_code
AND T166.hr_pyrl_code = 'f' AND T166.hr_paid_dati = 20180404
AND (T175.hr_paym_type = 'd' OR T175.hr_paym_type = 't')
GROUP BY T000.hr_empl_code
ORDER BY hr_empl_code
I'm really lost where it could be going wrong. I have stripped out the additional WHERE AND and brought it down to just T166.hr_empl_code = T175.hr_empl_code, but it doesn't make a different.
By no means am I any expert in SQL Server and queries, but I have decent grasp on the technology. Any help would be very appreciated!
Group by is not wrong, how you are using it is wrong.
SELECT
T000.hr_empl_code,
T.totpaid
FROM
hrtempnm T000
inner join (SELECT
hr_empl_code,
SUM(hr_doll_paid) as totPaid
FROM
hrtpaytp T175
where hr_paym_type = 'd' OR hr_paym_type = 't'
GROUP BY hr_empl_code
) T on t.hr_empl_code = T000.hr_empl_code
where exists
(select * from qmvempms T001,
hrtmspay T166,
hrtpaytp T175,
hrtptype T177
WHERE T000.hr_empl_code = T001.hr_empl_code
AND T001.hr_empl_code = T166.hr_empl_code
AND T001.hr_empl_code = T175.hr_empl_code
AND T001.hr_ploy_ment = T166.hr_ploy_ment
AND T001.hr_ploy_ment = T175.hr_ploy_ment
AND T175.hr_paym_code = T177.hr_paym_code
AND T166.hr_pyrl_code = 'f' AND T166.hr_paid_dati = 20180404
)
ORDER BY hr_empl_code
Note: It would be more clear if you have used joins instead of old style joining with where.

SQL query running slow after including the OR checking inside WHERE clause

This is my query .After i comment the part OR (NITransactionStatus = 'SUCCESS') ,there is no slowness.
How can i modify this query such that there is no slow and also i need to include both the conditions thats inside 'WHERE' clause?
SELECT COUNT(*)
FROM IN_CTD D
INNER JOIN IN_CTC C
ON C.InwardCustFileId = D.InwardCustFileId
WHERE (D.CurrentStatusId = 30) OR (NITransactionStatus = 'SUCCESS')
Trying to make it brief :
While i excute this query,it takes too much time to complete its execution . After i comment the 'OR' checking,there is no slowness.The 'IN_CTD' table mentioned in the query contains 2830539 records and the table 'IN_CTC' have 1965 records.How can i modify this query including the 'OR' checking such that it won't take much time to execute ?
Maybe you can try sub query. If NITransactionStatus column is on IN_CTD table, try this:
SELECT COUNT(*)
FROM IN_CTC C
INNER JOIN (SELECT InwardCustFileId FROM IN_CTD WHERE (CurrentStatusId = 30) OR (NITransactionStatus = 'SUCCESS')) AS D
ON C.InwardCustFileId = D.InwardCustFileId
If NITransactionStatus column is on IN_CTC table, try this:
SELECT COUNT(*)
FROM IN_CTC C
INNER JOIN (SELECT InwardCustFileId FROM IN_CTD WHERE CurrentStatusId = 30) AS D
ON C.InwardCustFileId = D.InwardCustFileId
WHERE (NITransactionStatus = 'SUCCESS')
Hope it can help.

Updating rows with a sub-query involved Oracle 11g

The script below returns the 01427 error that the single row sub-query returns more than one row. The rownum<2 gets a few rows updated. The obvious solution is looping through with pl/sql, but I am trying to determine if there is a SQL only solution.
UPDATE ldl.clens le
SET master_song_id =
(SELECT cf.song_id#
FROM lt.master_songs cf
WHERE le.lot_id = cf.lot_id
AND song_id#_fk =
(SELECT msc_songs.song_id#
FROM lt.msc_songs
WHERE msc_songs.song_name = le.song_name)
---- AND ROWNUM < 2
);
Any and all help and suggestions deeply appreciated!
MD
I'm not sure I grasped the relation between the tables, but if I did, you can use below UPDATE:
UPDATE ldl.clens le
SET master_song_id =
(SELECT cf.song_id#
FROM lt.master_songs cf
JOIN lt.msc_songs ms ON (cf.song_id#_fk = ms.song_id#)
WHERE
ms.song_name = le.song_name
AND le.lot_id = cf.lot_id)
;
It will work if msc_songs.song_name and master_songs.lot_id will give you a unique master_songs.song_id#.