I am trying to merge an inner join so that I can use 3 different tables,
where TBL1 is the destination table where the records will be inserted,
TBL2 where all the records to insert in table 1 TBL1 live
and the third and last table TBL3 where a condition will be made by rfc,
where if tbl3.rfc = tbl2.rfc load the data to
TBL1. My query that I am doing is the following:
MERGE INTO TBL1 concent
USING (SELECT inter.rfc,
arch.name_contr, arch.rfc,arch.taxpayer_situation,
arch.oficio_global,arch.presumed_publication,arch.definitive_publication
FROM TBL2 arch
INNER JOIN TBL3 inter
ON inter.rfc = arch.rfc )
ON (concent.rfc = arch.rfc) WHEN MATCHED THEN UPDATE SET concent.name_contr = arch.name_contr, concent.taxpayer_situation = arch.taxpayer_situation, concent..oficio_global = arch.oficio_global, concent.presumed_publication = arch.presumed_publication, concent.definitive_publication = arch.definitive_publication, concent.id_arch = arch.id_arch WHEN NOT MATCHED THEN INSERT (concent.id_concent,concent.id_arch,conce.snapshot_date,concent.rfc,concent.name_contr,
concent.taxpayer_situation,concent.oficio_global,concent.presumed_publication,
concent.definitive_publication,concent.baja_logica,concent.last_update) VALUES (arch.id_arch, arch.id_arch,'04/05/2021',arch.rfc,arch.name_contr,
arch.taxpayer_situation,arch.oficio_global,arch.presumed_publication,
archi.definitive_publication,'01','05/05/2021');
The error it marks is: Command line error: 8 Column: 27 Error report - Error SQL: ORA-00904: "ARCH"."RFC":
invalid identifier 00904. 00000 - "%s: invalid identifier" *Cause:
*Action:
database
The scope of table aliases arch and inter is limited to that subquery only. If you want to specify columns from that subquery on the level of parent merge, you need to give alias to that subquery in using clause, for example v_using:
MERGE INTO TBL1 concent
USING (SELECT inter.rfc as inter_rfc
arch.name_contr, arch.rfc,arch.taxpayer_situation,
arch.oficio_global,arch.presumed_publication,arch.definitive_publication
FROM TBL2 arch
INNER JOIN TBL3 inter
ON inter.rfc = arch.rfc ) v_using
ON (concent.rfc = v_using.rfc) WHEN MATCHED THEN UPDATE SET concent.name_contr = v_using.name_contr, concent.taxpayer_situation = v_using.taxpayer_situation,...
Related
I'm trying to update a set of records in a table with values from within results of a subquery. When I run this query, I get error:
Msg 4104, Level 16, State 1, Line 75
The multi-part identifier be_prsn.prsn_id could not be bound.
Code:
UPDATE be_org
SET org_id = 322
WHERE be_prsn.prsn_id IN (SELECT prsn.prsn_id
FROM be_prsn prsn
JOIN be_mbr mbr ON mbr.prsn_id = prsn.prsn_id
JOIN be_empt_hist empt ON empt.mbr_id = mbr.mbr_id
LEFT JOIN be_org org ON empt.org_id = org.org_id
OUTER APPLY
(SELECT
acct.acct_id, pln.pln_sys_cd,
COUNT(pyrl.pyrl_id) AS NumPyrl
FROM
be_mbr_acct acct
JOIN
be_pstn_hist pstn ON acct.pln_id = pstn.pln_id
JOIN
be_pln pln ON acct.pln_id = pln.pln_id
LEFT JOIN
be_pyrl pyrl ON pyrl.pstn_hist_id = pstn.pstn_hist_id
WHERE
acct.mbr_id = mbr.mbr_id
AND pstn.empt_hist_id = empt.empt_hist_id
AND EXISTS (SELECT 1 FROM be_cntrb cntrb
WHERE cntrb.pyrl_id = pyrl.pyrl_id
AND cntrb.rvrs_in = 0)
GROUP BY
acct.acct_id, pln.pln_sys_cd) acct
WHERE
prsn.prsn_id = 7286);
You update attribute org_id of table be_org. So actually an attribute from another table be_prsn (I assume that's what you want to express) isn't meaningful in this context. If you wanted to include another table in your where-condition, you would have to join that other table with be_org.
you have be_prsn alias in where's nested select and use be_prsn.prsn_id on parent level. there you have only be_org
You should do join
I have 3 tables in that 2 tables are master table and 3rd is transaction table. i need to get count from transaction table for each value in other two table without loosing rows in mater table
i need result like below
Table layout for understanding
This is the code i have tried,
select s.status_name, e.machine_group_name, qty = COALESCE(COUNT(e.id),0)
from tbl_status s
left outer JOIN tbl_transaction as e ON e.status_name = s.status_name
group by e.machine_group_name, s.status_name
This is solution i have figured:
select m.machine_group_name, s.status_name, qty = COUNT(e.id) from
tbl_machine_group as m
cross join tbl_status as s
left outer join tbl_transaction as e on e.status_name = s.status_name
and e.machine_group_name = m.machine_group_name
group by m.machine_group_name, s.status_name
order by machine_group_name
select
MC_Group_Name
,Status_Name
,count(1) as [Count of Transaction]
from
tbl_Transaction tbl_3
left join tbl_Machine_Group tbl_1
on tbl_3.MC_Group_Name = tbl_1.MC_Group_Name
left join tbl_Status tbl_2
on tbl_3.Status_Name = tbl_2.Status_Name
group by
MC_Group_Name
,Status_Name
What would the syntax be to convert this MS Access query to run in SQL Server as it doesn't have a DistinctRow keyword
UPDATE DISTINCTROW [MyTable]
INNER JOIN [AnotherTable] ON ([MyTable].J5BINB = [AnotherTable].GKBINB)
AND ([MyTable].J5BHNB = [AnotherTable].GKBHNB)
AND ([MyTable].J5BDCD = [AnotherTable].GKBDCD)
SET [AnotherTable].TessereCorso = [MyTable].[J5F7NR];
DISTINCTROW [MyTable] removes duplicate MyTable entries from the results. Example:
select distinctrow items
items.item_number, items.name
from items
join orders on orders.item_id = items.id;
In spite of the join getting you the same item_number and name multiple times when there is more than one order for it, DISTINCTROW reduces this to one row per item. So the whole join is merely for assuring that you only select items for which exist at least one order. You don't find DISTINCTROW in any other DBMS as far as I know. Probably because it is not needed. When checking for existence, we use EXISTS of course (or IN for that matter).
You are joining MyTable and AnotherTable and expect for some reason to get the same MyTable record multifold for one AnotherTable record, so you use DISTINCTROW to only get it once. Your query would (hopefully) fail if you got two different MyTable records for one AnotherTable record.
What the update does is:
update anothertable
set tesserecorso = (select top 1 j5f7nr from mytable where mytable.j5binb = anothertable.gkbinb and ...)
where exists (select * from mytable where mytable.j5binb = anothertable.gkbinb and ...)
But this uses about the same subquery twice. So we'd want to update from a query instead.
The easiest way to get one result record per <some columns> in a standard SQL query is to aggregate data:
select *
from anothertable a
join
(
select j5binb, j5bhnb, j5bdcd, max(j5f7nr) as j5f7nr
from mytable
group by j5binb, j5bhnb, j5bdcd
) m on m.j5binb = a.gkbinb and m.j5bhnb = a.gkbhnb and m.j5bdcd = a.gkbdcd;
How to write an updateble query is different from one DBMS to another. Here is the final update statement for SQL-Server:
update a
set a.tesserecorso = m.j5f7nr
from anothertable a
join
(
select j5binb, j5bhnb, j5bdcd, max(j5f7nr) as j5f7nr
from mytable
group by j5binb, j5bhnb, j5bdcd
) m on m.j5binb = a.gkbinb and m.j5bhnb = a.gkbhnb and m.j5bdcd = a.gkbdcd;
The DISTINCTROW predicate in MS Access SQL removes duplicates across all fields of a table in join statements and not just the selected fields of query (which DISTINCT in practically all SQL dialects do). So consider selecting all fields in a derived table with DISTINCT predicate:
UPDATE [AnotherTable]
SET [AnotherTable].TessereCorso = main.[J5F7NR]
FROM
(SELECT DISTINCT m.* FROM [MyTable] m) As main
INNER JOIN [AnotherTable]
ON (main.J5BINB = [AnotherTable].GKBINB)
AND (main.J5BHNB = [AnotherTable].GKBHNB)
AND (main.J5BDCD = [AnotherTable].GKBDCD)
Another variant of the query.. (Too lazy to get the original tables).
But like the query above updates 35 rows =, so does this one
UPDATE [Albi-Anagrafe-Associati]
SET
[Albi-Anagrafe-Associati].CRegDitte = [055- Registri ditte].[CRegDitte],
[Albi-Anagrafe-Associati].NIscrTribunale = [055- Registri ditte].[NIscrTribunale],
[Albi-Anagrafe-Associati].NRegImprese = [055- Registri ditte].[NRegImprese]
FROM [055- Registri ditte]
WHERE EXISTS(
SELECT *
FROM [055- Registri ditte]-- [Albi-Anagrafe-Associati]
WHERE ([055- Registri ditte].GIBINB = [Albi-Anagrafe-Associati].GKBINB)
AND ([055- Registri ditte].GIBHNB = [Albi-Anagrafe-Associati].GKBHNB)
AND ([055- Registri ditte].GIBDCD = [Albi-Anagrafe-Associati].GKBDCD))
Update [AnotherTable]
Set [AnotherTable].TessereCorso = MyTable.[J5F7NR]
From [AnotherTable]
Inner Join
(
Select Distinct [J5BINB],[5BHNB],[J5BDCD]
,(Select Top 1 [J5F7NR] From MyTable) as [J5F7NR]
,[J5BHNB]
From MyTable
)as MyTable
On (MyTable.J5BINB = [AnotherTable].GKBINB)
AND (MyTable.J5BHNB = [AnotherTable].GKBHNB)
AND (MyTable.J5BDCD = [AnotherTable].GKBDCD)
I have a multiple row update query that is not working like I expect it to. The JOIN condition is adhered to in the SELECT statement, but not in the UPDATE statement.
In other words: I changed 1 row, the SELECT query shows only 1 result (as expected). I convert the query to an UPDATE statement and run it - all rows in the table are changed to the same value - the JOIN condition is totally ignored.
I thought it was due to a table variable, so I used a temp table and get the same results. I verified my JOIN condition is comparing the same datatype (it's an INNER JOIN). I'm at a loss as to why this will not work
SELECT
(o.SubTotal - o.OrderDiscounts) AS OrderSubTotal,
t.CommRate * (o.SubTotal - o.OrderDiscounts) AS CommDue,
'MODIFIED' AS "Status"
FROM
bvc_Order o
INNER JOIN
#tbl t ON o.OrderNumber = t.OrderNumber
Converted to an UPDATE statement:
UPDATE AffiliateComm
SET [OrderSubtotal] = (o.SubTotal - o.OrderDiscounts),
[CommDue] = t.CommRate * (o.SubTotal - o.OrderDiscounts),
[Status] = 'MODIFIED'
FROM
bvc_Order o
INNER JOIN
#tbl t ON o.OrderNumber = t.OrderNumber
I've done the same query with a table variable - (select works, update always updates all rows & ignores JOIN condition) no joy.
Stranger still, if I put a WHERE clause on the end, it is IGNORED!
As in
WHERE o.OrderNumber = t.OrderNumber
I've done queries like these before and never had this problem.
The output of the SELECT query (as an example when 1 row needs changing)
OrderSubTotal CommDue Status
----------------------------------
1285.20 38.56 MODIFIED
WHEN I run the update query:
(1 row(s) affected) <-This is the temp table (or variable) having 1 row inserted as it should CORRECT
(5 row(s) affected) <- This is the INCORRECT number of rows affected by the UPDATE (should be 1)
Is there a setting in SQL Server 2012 that is wrong? If you inner join a table with 1 row, it's not possible to have MORE than 1 row as a result set, right?
I'm baffled.
Presumably, you intend something like this:
UPDATE ac
SET [OrderSubtotal] = (o.SubTotal - o.OrderDiscounts),
[CommDue] = t.CommRate*(o.SubTotal - o.OrderDiscounts),
[Status] = 'MODIFIED'
FROM AffiliateComm ac INNER JOIN
bvc_Order o
ON ac.OrderNumber = o.OrderNumber INNER JOIN
#tbl t
ON o.OrderNumber = t.OrderNumber ;
In other words, AffiliateComm needs to be joined into the other tables, somehow. Otherwise, all rows in AffiliateComm will be updated, I believe with the same value. I made up an AffiliateId for the above query.
In your update:
UPDATE AffiliateComm
SET [OrderSubtotal]=(o.SubTotal - o.OrderDiscounts), [CommDue]=t.CommRate*(o.SubTotal - o.OrderDiscounts),[Status]='MODIFIED'
FROM bvc_Order o
INNER JOIN #tbl t
ON o.OrderNumber = t.OrderNumber
You tell sql server to update a table called AffiliateComm. However, this table is not included in your join.
Not knowing the schema of this table, i can only guess at whata right, possibly something like:
UPDATE a
SET [OrderSubtotal]=(o.SubTotal - o.OrderDiscounts), [CommDue]=t.CommRate*(o.SubTotal - o.OrderDiscounts),[Status]='MODIFIED'
FROM AffiliateComm A
INNER JOIN bvc_Order o
ON o.OrderNumber = a.OrderNumber
INNER JOIN #tbl t
ON o.OrderNumber = t.OrderNumbe
I want to update a column in a table making a join on other table e.g.:
UPDATE table1 a
INNER JOIN table2 b ON a.commonfield = b.[common field]
SET a.CalculatedColumn= b.[Calculated Column]
WHERE
b.[common field]= a.commonfield
AND a.BatchNO = '110'
But it is complaining :
Msg 170, Level 15, State 1, Line 2
Line 2: Incorrect syntax near 'a'.
What is wrong here?
You don't quite have SQL Server's proprietary UPDATE FROM syntax down. Also not sure why you needed to join on the CommonField and also filter on it afterward. Try this:
UPDATE t1
SET t1.CalculatedColumn = t2.[Calculated Column]
FROM dbo.Table1 AS t1
INNER JOIN dbo.Table2 AS t2
ON t1.CommonField = t2.[Common Field]
WHERE t1.BatchNo = '110';
If you're doing something silly - like constantly trying to set the value of one column to the aggregate of another column (which violates the principle of avoiding storing redundant data), you can use a CTE (common table expression) - see here and here for more details:
;WITH t2 AS
(
SELECT [key], CalculatedColumn = SUM(some_column)
FROM dbo.table2
GROUP BY [key]
)
UPDATE t1
SET t1.CalculatedColumn = t2.CalculatedColumn
FROM dbo.table1 AS t1
INNER JOIN t2
ON t1.[key] = t2.[key];
The reason this is silly, is that you're going to have to re-run this entire update every single time any row in table2 changes. A SUM is something you can always calculate at runtime and, in doing so, never have to worry that the result is stale.
Try it like this:
UPDATE a
SET a.CalculatedColumn= b.[Calculated Column]
FROM table1 a INNER JOIN table2 b ON a.commonfield = b.[common field]
WHERE a.BatchNO = '110'
Answer given above by Aaron is perfect:
UPDATE a
SET a.CalculatedColumn = b.[Calculated Column]
FROM Table1 AS a
INNER JOIN Table2 AS b
ON a.CommonField = b.[Common Field]
WHERE a.BatchNo = '110';
Just want to add why this problem occurs in SQL Server when we try to use alias of a table while updating that table, below mention syntax will always give error:
update tableName t
set t.name = 'books new'
where t.id = 1
case can be any if you are updating a single table or updating while using join.
Although above query will work fine in PL/SQL but not in SQL Server.
Correct way to update a table while using table alias in SQL Server is:
update t
set t.name = 'books new'
from tableName t
where t.id = 1
Hope it will help everybody why error came here.
MERGE table1 T
USING table2 S
ON T.CommonField = S."Common Field"
AND T.BatchNo = '110'
WHEN MATCHED THEN
UPDATE
SET CalculatedColumn = S."Calculated Column";
UPDATE mytable
SET myfield = CASE other_field
WHEN 1 THEN 'value'
WHEN 2 THEN 'value'
WHEN 3 THEN 'value'
END
From mytable
Join otherTable on otherTable.id = mytable.id
Where othertable.somecolumn = '1234'
More alternatives here.
Seems like SQL Server 2012 can handle the old update syntax of Teradata too:
UPDATE a
SET a.CalculatedColumn= b.[Calculated Column]
FROM table1 a, table2 b
WHERE
b.[common field]= a.commonfield
AND a.BatchNO = '110'
If I remember correctly, 2008R2 was giving error when I tried similar query.
I find it useful to turn an UPDATE into a SELECT to get the rows I want to update as a test before updating. If I can select the exact rows I want, I can update just those rows I want to update.
DECLARE #expense_report_id AS INT
SET #expense_report_id = 1027
--UPDATE expense_report_detail_distribution
--SET service_bill_id = 9
SELECT *
FROM expense_report_detail_distribution erdd
INNER JOIN expense_report_detail erd
INNER JOIN expense_report er
ON er.expense_report_id = erd.expense_report_id
ON erdd.expense_report_detail_id = erd.expense_report_detail_id
WHERE er.expense_report_id = #expense_report_id
Another approach would be to use MERGE
;WITH cteTable1(CalculatedColumn, CommonField)
AS
(
select CalculatedColumn, CommonField from Table1 Where BatchNo = '110'
)
MERGE cteTable1 AS target
USING (select "Calculated Column", "Common Field" FROM dbo.Table2) AS source ("Calculated Column", "Common Field")
ON (target.CommonField = source."Common Field")
WHEN MATCHED THEN
UPDATE SET target.CalculatedColumn = source."Calculated Column";
-Merge is part of the SQL Standard
-Also I'm pretty sure inner join updates are non deterministic..
Similar question here where the answer talks about that
http://ask.sqlservercentral.com/questions/19089/updating-two-tables-using-single-query.html
I think, this is what you are looking for.
UPDATE
Table1
SET
Table1.columeName =T1.columeName * T2.columeName
FROM
Table1 T1
INNER JOIN Table2 T2
ON T1.columeName = T2.columeName;
I had the same issue.. and you don't need to add a physical column.. cuz now you will have to maintain it..
what you can do is add a generic column in the select query:
EX:
select tb1.col1, tb1.col2, tb1.col3 ,
(
select 'Match' from table2 as tbl2
where tbl1.col1 = tbl2.col1 and tab1.col2 = tbl2.col2
)
from myTable as tbl1
Aaron's approach above worked perfectly for me. My update statement was slightly different because I needed to join based on two fields concatenated in one table to match a field in another table.
--update clients table cell field from custom table containing mobile numbers
update clients
set cell = m.Phone
from clients as c
inner join [dbo].[COSStaffMobileNumbers] as m
on c.Last_Name + c.First_Name = m.Name
Those who are using MYSQL
UPDATE table1 INNER JOIN table2 ON table2.id = table1.id SET table1.status = 0 WHERE table1.column = 20
Try:
UPDATE table1
SET CalculatedColumn = ( SELECT [Calculated Column]
FROM table2
WHERE table1.commonfield = [common field])
WHERE BatchNO = '110'