T-SQL UPDATE query not giving expected results - tsql

I have an UPDATE query in SQL Server Management Studio 2012 that is not giving me the expected results. I believe it is because I had to add the IJDATE field to the SELECT and GROUP BY and therefore it is not summing correctly. I am trying to update the current month/year for each vendor. Is there a better way to write this UPDATE query?
UPDATE S
SET S.PurchaseDlr = I.PurchaseDlr
FROM (SELECT
IJVEND,
IJDATE,
SUM(IJQTY * IJCOST) AS PurchaseDlr
FROM
dbo.S2K_IJ
WHERE
IJTYPE IN ('I','ID')
GROUP BY
IJVEND,
IJDATE) I
INNER JOIN PurchaseDollars S on I.IJVEND = S.Vendor AND S.MonthNum = MONTH(I.IJDATE) AND S.Year = YEAR(I.IJDATE)

You are grouping by date, but it looks like you want to group by month and year:
UPDATE S
SET S.PurchaseDlr = I.PurchaseDlr
FROM (SELECT
IJVEND,
MONTH(IJDATE) AS Month,
YEAR(IJDATE) AS Year,
SUM(IJQTY * IJCOST) AS PurchaseDlr
FROM
dbo.S2K_IJ
WHERE
IJTYPE IN ('I','ID')
GROUP BY
IJVEND,
MONTH(IJDATE),
YEAR(IJDATE)) I
INNER JOIN PurchaseDollars S
ON I.IJVEND = S.Vendor
AND S.MonthNum = I.Month
AND S.Year = I.Year

Related

Update PgSQL Self JOIN With Custom Values

I'm trying to use UPDATE SELF JOIN and could not seem to get the correct SQL query.
Before the query, I execute this SQL query to get the values:
SELECT DISTINCT ON (purpose) purpose FROM user_assigned_customer
sales_manager
main_contact
representative
administrator
By the time I run this query, it overwrites all the purpose columns:
UPDATE user_assigned_customer SET purpose = (
SELECT 'main_supervisor' AS purpose FROM user_assigned_customer AS assigned_user
LEFT JOIN app_user ON app_user.id = assigned_user.app_user_id
WHERE app_user.role = 'supervisor'
AND user_assigned_customer.purpose IS NULL
AND assigned_user.id = user_assigned_customer.id
)
The purpose column is now only showing when running the first query:
main_supervisor
Wondering if there is a way to query to update SQL Self JOIN with a custom value.
I think I got it with a help of a friend.
UPDATE user_assigned_customer SET purpose = 'main_supervisor'
FROM user_assigned_customer AS assigned_user
LEFT JOIN app_user ON app_user.id = assigned_user.app_user_id
WHERE app_user.role = 'supervisor'
AND user_assigned_customer.purpose IS NULL
AND assigned_user.id = user_assigned_customer.id

Update all using alias from an aggregate value derived from a Join

SELECT activities.id, max(symbols.bought_at) AS bought_at
FROM "activities"
JOIN holdings ON trackable_id = holdings.id AND trackable_type = 'Holding'
JOIN symbols on symbols.holding_id = holdings.id
GROUP BY activities.id"
I have a SQL that looks like the above. This works fine. However, I want to update all activities' created_at to the alias bought_at. I get an error that bought_at is not a column. Is it possible to do so in Postgres?
you can use that query as the source for an UPDATE statement:
update activities
set created_at = t.bought_at
from (
SELECT activities.id, max(symbols.bought_at) AS bought_at
FROM activities
JOIN holdings ON trackable_id = holdings.id AND trackable_type = 'Holding'
JOIN symbols on symbols.holding_id = holdings.id
GROUP BY activities.id
) t
where activities.id = t.id;
This assumes that activities.id is the primary key of that table.

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'

SQL query that joins results created by a query

I have two tables:
TWMWR and TWMWRemark. I have two competing criteria so I am trying to run the query separately and then join them. I am trying to find all the records in TWMWR that meet the following criteria:
PSWMS.TWMREMARK.TXT_REMARK LIKE '%Essential Equipment: N%'
AND PSWMS.TWMREMARK.TP_REMARK = '%CIS%'
then I want to take the list of WR (the records) and join that with another table to find the records that meet the following criteria:
PSWMS.TWMREMARK.ID_OPER = 'IXM0Q74'
AND PSWMS.TWMREMARK.TP_REMARK = 'CLM'
AND PSWMS.TWMREMARK.TXT_REMARK LIKE '%SOC%'
They have to be done separately. Can anyone help? I have pasted what I have tried below. I am using mySql developer.
SELECT PSWMS.TWMWR.CD_WR,
PSWMS.TWMWR.TP_JOB,
PSWMS.TWMWR.TS_OPER_RECORDED,
PSWMS.TWMWR.ID_CUSTOMER,
PSWMS.TWMREMARK.TS_REMARK,
PSWMS.TWMREMARK.ID_OPER,
PSWMS.TWMREMARK.TP_REMARK AS TP_REMARK1,
PSWMS.TWMREMARK.TXT_REMARK
FROM PSWMS.TWMWR
INNER JOIN PSWMS.TWMREMARK
ON PSWMS.TWMWR.CD_WR = PSWMS.TWMREMARK.CD_WR
WHERE PSWMS.TWMWR.TP_JOB = 'CLMDPD'
AND PSWMS.TWMWR.TS_OPER_RECORDED >= '21, Oct 2013'
AND PSWMS.TWMREMARK.ID_OPER = 'IXM0Q74'
AND PSWMS.TWMREMARK.TP_REMARK = 'CLM'
AND PSWMS.TWMREMARK.TXT_REMARK LIKE '%SOC%'
GROUP BY PSWMS.TWMWR.CD_WR,
PSWMS.TWMWR.TP_JOB,
PSWMS.TWMWR.TS_OPER_RECORDED,
PSWMS.TWMWR.ID_CUSTOMER,
PSWMS.TWMREMARK.TS_REMARK,
PSWMS.TWMREMARK.ID_OPER,
PSWMS.TWMREMARK.TP_REMARK,
PSWMS.TWMREMARK.TXT_REMARK
INNER JOIN
SELECT PSWMS.TWMWR.CD_WR
FROM PSWMS.TWMWR
INNER JOIN PSWMS.TWMREMARK
ON PSWMS.TWMWR.CD_WR = PSWMS.TWMREMARK.CD_WR
WHERE PSWMS.TWMWR.TP_JOB = 'CLMDPD'
AND PSWMS.TWMWR.TS_OPER_RECORDED >= '21, Oct 2013'
AND PSWMS.TWMREMARK.TXT_REMARK LIKE '%Essential Equipment: N%'
AND PSWMS.TWMREMARK.TP_REMARK = '%CIS%' AS WR
ON PSWMS.TWMWR.CD_WR = WR.CD_WR, PSWMS.TWMREMARK.CD_WR = WR.CD_WR

How to select first and last records between certain date parameters?

I need a Query to extract the first instance and last instance only between date parameters.
I have a Table recording financial information with financialyearenddate field linked to Company table via companyID. Each company is also linked to programme table and can have multiple programmes. I have a report to pull the financials for each company
on certain programme which I have adjusted to pull only the first and last instance (using MIN & MAX) however I need the first instance.
after a certain date parameter and the last instance before a certain date parameter.
Example: Company ABloggs has financials for 1999,2000,2001,2004,2006,2007,2009 but the programme ran from 2001 to 2007 so I only want
the first financial record and last financial record between those years i.e. 2001 & 2007 records. Any help appreciated.
At the moment I am using 2 queries as I needed the data in a hurry but I need it in 1 query and only where financial year end dates are between parameters and only where there are minimum of 2 GVA records for a company.
Query1:
SELECT
gva.ccx_companyname,
gva.ccx_depreciation,
gva.ccx_exportturnover,
gva.ccx_financialyearenddate,
gva.ccx_netprofitbeforetax,
gva.ccx_totalturnover,
gva.ccx_totalwages,
gva.ccx_statusname,
gva.ccx_status,
gva.ccx_company,
gva.ccx_totalwages + gva.ccx_netprofitbeforetax + gva.ccx_depreciation AS GVA,
gva.ccx_nofulltimeequivalentemployees
FROM
(
SELECT
ccx_companyname,
MAX(ccx_financialyearenddate) AS LatestDate
FROM Filteredccx_gva AS Filteredccx_gva_1
GROUP BY ccx_companyname
) AS min_1
INNER JOIN Filteredccx_gva AS gva
ON min_1.ccx_companyname = gva.ccx_companyname AND
min_1.LatestDate = gva.ccx_financialyearenddate
WHERE (gva.ccx_status = ACTUAL)
Query2:
SELECT
gva.ccx_companyname,
gva.ccx_depreciation,
gva.ccx_exportturnover,
gva.ccx_financialyearenddate,
gva.ccx_netprofitbeforetax,
gva.ccx_totalturnover,
gva.ccx_totalwages,
gva.ccx_statusname,
gva.ccx_status,
gva.ccx_company,
gva.ccx_totalwages + gva.ccx_netprofitbeforetax + gva.ccx_depreciation AS GVA,
gva.ccx_nofulltimeequivalentemployees
FROM
(
SELECT
ccx_companyname,
MIN(ccx_financialyearenddate) AS FirstDate
FROM Filteredccx_gva AS Filteredccx_gva_1
GROUP BY ccx_companyname
) AS MAX_1
INNER JOIN Filteredccx_gva AS gva
ON MAX_1.ccx_companyname = gva.ccx_companyname AND
MAX_1.FirstDate = gva.ccx_financialyearenddate
WHERE (gva.ccx_status = ACTUAL)
Can't you just add a where clause using the first and last date parameters. Something like this:
SELECT <companyId>, MIN(<date>), MAX(<date>)
FROM <table>
WHERE <date> BETWEEN #firstDate AND #lastDate
GROUP BY <companyId>
declare #programme table (ccx_companyname varchar(max), start_year int, end_year int);
insert #programme values
('ABloggs', 2001, 2007);
declare #companies table (ccx_companyname varchar(max), ccx_financialyearenddate int);
insert #companies values
('ABloggs', 1999)
,('ABloggs', 2000)
,('ABloggs', 2001)
,('ABloggs', 2004)
,('ABloggs', 2006)
,('ABloggs', 2007)
,('ABloggs', 2009);
select c.ccx_companyname, min(ccx_financialyearenddate), max(ccx_financialyearenddate)
from #companies c
join #programme p on c.ccx_companyname = p.ccx_companyname
where c.ccx_financialyearenddate >= p.start_year and c.ccx_financialyearenddate <= p.end_year
group by c.ccx_companyname
having count(*) > 1;
You can combine your two original queries into a single query by including the MIN and MAX aggregates in the same GROUP BY query of the virtual table. Also including COUNT() and HAVING COUNT() > 1 ensures company must have at least 2 dates. So query should look like:
SELECT
gva.ccx_companyname,
gva.ccx_depreciation,
gva.ccx_exportturnover,
gva.ccx_financialyearenddate,
gva.ccx_netprofitbeforetax,
gva.ccx_totalturnover,
gva.ccx_totalwages,
gva.ccx_statusname,
gva.ccx_status,
gva.ccx_company,
gva.ccx_totalwages + gva.ccx_netprofitbeforetax + gva.ccx_depreciation AS GVA,
gva.ccx_nofulltimeequivalentemployees
FROM
(SELECT
ccx_companyname,
ccx_status,
MIN(ccx_financialyearenddate) AS FirstDate,
MAX(ccx_financialyearenddate) AS LastDate,
COUNT(*) AS NumDates
FROM Filteredccx_gva AS Filteredccx_gva_1
WHERE (ccx_status = ACTUAL)
GROUP BY ccx_companyname, ccx_status
HAVING COUNT(*) > 1
) AS MinMax
INNER JOIN Filteredccx_gva AS gva
ON MinMax.ccx_companyname = gva.ccx_companyname AND
(MinMax.FirstDate = gva.ccx_financialyearenddate OR
MinMax.LastDate = gva.ccx_financialyearenddate)
WHERE (gva.ccx_status = MinMax.ccx_status)
ORDER BY gva.ccx_companyname, gva.ccx_financialyearenddate