How do i update this field in my sql database? - tsql

i have two tables.
BoardPosts
BoardPostId INT PK
ModifiedOn DATETIME NULLABLE
BoardComments
BoardCommentId INT PK
BoardPostId INT
CreatedOn DATETIME
A board post has zero to many comments.
I wish to set the ModifiedOn field to be the most recent comment date, if the board has a comment. Otherwise, just leave it null.
How do i do this, using TSql ?
something like ...
UPDATE BoardPosts
SET ModifiedOn = CreatedOn
SELECT TOP(1) CreatedOn
FROM BoardPosts a INNER JOIN BoardComments b ON a.BoardPostId = b.BoardPostId
???

I think this will work...
UPDATE BoardPosts
SET ModifiedOn = (SELECT MAX(CreatedOn)
FROM BoardComments
WHERE BoardComments.BoardPostId = BoardPosts.BoardPostId)

I decided to take into account both commented and uncommented posts:
update p1 set ModifiedOn = (
select
max(case when c.CreatedOn is null then p.CreatedOn
else c.CreatedOn end) as ModDate
from
boardposts p
left outer join BoardComments c on
p.BoardPostId = c.BoardPostId
where
p.BoardPostId = p1.BoardPostId
group by p.BoardPostId
)
from
BoardPosts p1
Hope this helps!

Related

update join and where using Postgres

i have two tables : productprice and product
and i have a field name id on that tables, i would like update field name enddate on productprice base on code on product i try several syntax:
update productprice
set enddate = ’2016-12-31 00:00:00’
from product inner join
productprice
on product.id = productprice.id
where product.code = ‘9301940252’
but the result is "table name “productprice” specified more than once"
What I am doing wrong here? Thanks.
This is the correct syntax for MySQL:
update productprice pp join
product p
on p.id = pp.id
set pp.enddate = '2016-12-31'
where p.code = '9301940252';
Given your error and the fact that the question originally had Postgres and MySQL as a tag, perhaps you want Postgres syntax:
update productprice pp
set enddate = '2016-12-31'
from product p
where p.id = pp.id and p.code = '9301940252';

Updating a CTE table fail cause of derived or constant field

I'm using MS-SQL 2012
WITH C1
(
SELECT ID, 0 as Match, Field2, Count(*)
FROM TableX
GROUP BY ID, Fields2
)
UPDATE C1 SET Match = 1
WHERE ID = (SELECT MATCHING_ID FROM AnotherTable WHERE ID = C1.ID)
This TSQL statement gives me the following error:
Update or insert of view or function 'C1' failed because it contains a derived or constant field.
Ideally I would like to create a "fake field" named Match and set its default value to 0. Then with the update I would like to Update ONLY the records that have an existing entry on the "AnotherTable".
Any thoughts what am I doing wrong?
Thanks in advanced.
Try doing a Left Outer Join like
SELECT x.ID, ISNULL(a.Matching_ID, 0) as Match, x.Field2, Count(*)
FROM TableX x
LEFT OUTER JOIN AnotherTable a on x.ID = a.ID
GROUP BY x.ID, ISNULL(a.Matching_ID, 0), x.Fields2
without the need of a C1
If I am understanding correctly, the problem is that you are trying to update the CTE table. If you update the table directly you should be fine.
Does this modified version help?
SELECT t.ID
, CASE WHEN (EXISTS (SELECT MATCHING_ID FROM AnotherTable WHERE ID = t.ID)) THEN 1 ELSE 0 END
,t.Field2
,Count(*)
FROM TableX t
GROUP BY ID, Fields2

Updating with Nested Select Statements

I have a table that holds 3 fields of data: Acct#, YMCode, and EmployeeID. The YMCode is an Int that is formatted 201308, 201307, etc. For each Acct#, I need to select the EmployeedID used for the YMCode 201308 and then update all of the other YMCodes for the Acct# to the EmployeedID used in 201308.
so for each customer account in the table...
Update MyTable
Set EmployeeID = EmployeeID used in YMCode 201308
Having a hard time with it.
Put it in a transaction and look at the results before committing, but I think this is what you want:
UPDATE b
SET EmployeeID = a.EmployeeID
FROM MyTable a
INNER JOIN MyTable b
ON a.[Acct#] = b.[Acct#]
where a.YMCode =
(SELECT MAX(YMCode) from MyTable)
To get max YMCode, just add select statement at the end.

Subquery in update doesn't see already updated records

I have a few thousand records with a duplicate sortorder (which causes duplicate entries in other queries), so I'm trying to set a correct sort order for all those records.
First I set them all to -1 so the sortorder would start from 0, and then I execute this query:
UPDATE op.customeraddress SET sortorder = (SELECT MAX(ca.sortorder) + 1
FROM op.customeraddress AS ca
WHERE ca.customerid = customeraddress.customerid)
WHERE id IN (<subquery for IDs>)
The problem is that the MAX() in the subquery always seems to return the same value - it doesn't know about an earlier update.
The query works fine if I manually apply it record by record.
Any ideas on how to do this without having to resort to looping?
This should do it:
with new_order as
(
select ctid as rid,
row_number() over (partition by customerid order by sortorder) as rn
from customeraddress
)
update customeraddress ca
set sortorder = new_order.rn
where ca.ctid = new_order.rid;
and ca.id IN (<subquery for IDs>);
No need to reset the sortorder before running this, it will renumber all customeraddresses for a one customerid according to the old order.
You need PostgreSQL 9.1 for the above solution (writeable CTEs)
For previous version this should do it:
update customeraddress ca
set ca.sortorder = t.sortorder
from
(
select ctid as rid,
row_number() over (partition by customerid order by sortorder) as rn
from customeraddress
) t
where ca.ctid = t.rid
and ca.id IN (<subquery for IDs>);
You could use a sequence:
CREATE TEMPORARY SEQUENCE sort_seq;
UPDATE op.customeraddress SET sort_order = (
SELECT nextval('sort_seq')
FROM op.customeraddress AS ca
WHERE ca.customerid = customeraddress.customerid
) WHERE id IN ...

Difficult query (DB2)

Suppose I have a table called spitems with the following fields:
spitemid (unique key)
modifiedon (timestamp)
parentid
a number of other unsignificant fields
What I want to retrieve, is the spitem rows with the highest modifiedon day for each parentid.
However, be aware that the modifiedon timestamp is not unique, so it is possible that for one parent id, there are two spitemids with the same modifiedon timestamp. In that case, I need one of these two spitemids listed, I don't care which one.
So to be clear: the list I return should contain all the parentids once and only once.
update
meeting over, here is my shot:
select *
from table
join where spitmid in
(select max(spitmid)
from table
join
(select parentid, max(modifiedon) as d from table group by parentid) inlist
on table.parentid = inlist.parentid and table.modifiedon = inlist.d
group by parentid, datemodified
)
old entry
not sure if this is different on DB2, here it is for sql server.
select *
from table
join (select parentid, max(modifiedon) as d from table group by parentid) as toplist on
table.parentid = toplist.parentid and table.modifiedon = toplist.d
hmm... this will return more than one for the dups... can't fix it now, have to go to a meeting.
Based on your requirements, following should get you the latest items.
SELECT t1.*
FROM Table t1
INNER JOIN (
SELECT spitemid = MAX(t1.spitemid)
FROM Table t1
INNER JOIN (
SELECT parentid, modifiedon = MAX(modifiedon)
FROM Table
GROUP BY parentid
) t2 ON t2.parentid = t1.parentid
AND t2.modifiedon = t1.modifiedon
GROUP BY t1.parentid, t1.modifiedon
) t2 ON t2.spitemid = t1.spitemid
You can do it with two nested subqueries. The first gets max modifiedon for each parentid, and then the second gets max spitemid for each parentid/modifiedon group.
SELECT *
FROM spitems
WHERE spitemid IN
(
SELECT parentid, modifiedon, max(spitemid) spitemid
FROM (
SELECT parentid, MAX(modifiedon) modifiedon
FROM spitems
GROUP BY parentid
) A
GROUP BY parentid, modifiedon
)
A common table expression will give you the opportunity to number the rows before you issue the final SELECT.
WITH items AS
(
SELECT spitemid, parentid, modifiedon,
ROWNUMBER() OVER (PARTITION BY parentid ORDER BY modifiedon DESC) AS rnum
FROM yourTable
)
SELECT spitemid, parentid, modifiedon FROM items WHERE rnum = 1
;
SELECT sr.receiving_id, sc.collection_id FROM stock_collection as sc, stock_requisation as srq, stock_receiving as sr WHERE (sc.stock_id = '" & strStockID & "' AND sc.datemm_issued = '" & strMM & "' AND sc.qty_issued >= 0 AND sc.collection_id = srq.requisition_id AND srq.active_status = 'Active') OR (sr.stock_id = '" & strStockID & "' AND sr.datemm_received = '" & strMM & "' AND sr.qty_received >= 0)