Update multiple record in 1 query - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 hours ago.
Improve this question
I have my query working in single record, I want to update multiple record in 1 query
IF #object_type = '60'
BEGIN
IF #transaction_type IN ('A', 'U')
BEGIN
UPDATE D
SET D.U_R_Length = (SELECT T4.U_Factor * T4.Quantity
FROM IGE1 T1
INNER JOIN OIGE T2 ON T1.DocEntry = T2.DocEntry
INNER JOIN IBT1 T3 ON T3.BaseEntry = T1.DocEntry AND T1.LineNum = T3.BaseLinNum AND T1.BaseType = 202
INNER JOIN OIBT T4 ON T3.BatchNum = T4.BatchNum
WHERE T2.DocEntry = (#list_of_cols_val_tab_del) AND T4.BatchNum = D.DistNumber )
FROM IGE1 A
INNER JOIN OIGE B ON A.DocEntry = B.DocEntry
INNER JOIN IBT1 C ON C.BaseEntry = A.DocEntry AND A.LineNum = C.BaseLinNum AND A.BaseType = 202
INNER JOIN OBTN D ON C.BatchNum = D.DistNumber
WHERE B.DocEntry in (SELECT DocEntry FROM OIGE WHERE DocEntry = (#list_of_cols_val_tab_del))
END
END

Related

SQL Server Select Query for company that has employee role (Owner and CEO) at the same time [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
My Table Structure is shown below:
I would like to retrieve company names and person names that working for this company and their position are (CEO and Owner), it means that person must be both (CEO and owner). I've tried so far and created below query, I can select or filter only CEO or Owner.
SELECT cp.id as cp_id,
com.name,
per.name,
pos.position_name
FROM company_person as cp
INNER JOIN company as com
ON com.id = cp.company_id
INNER JOIN person as per
ON per.id = cp.person_id
INNER JOIN position as pos
ON pos.id = cp.position_id
This is a classic Relational Division With Remainder question.
There are a number of solutions. Here is a standard one.
SELECT
com.name,
per.name
FROM company as com
CROSS APPLY (
SELECT
cp.person_id
FROM company_person as cp
INNER JOIN position as pos ON pos.id = cp.position_id
WHERE com.id = cp.company_id
AND pos.position_name IN ('CEO', 'Owner')
GROUP BY
cp.person_id
HAVING COUNT(*) = 2
) as cp
INNER JOIN person as per ON per.id = cp.person_id;
If your list of positions is more dynamic, you can put them in a table variable or TVP, then do the following
DECLARE #input TABLE (position_name varchar(50) PRIMARY KEY);
INSERT #input ....
SELECT
com.name,
per.name
FROM company as com
CROSS APPLY (
SELECT
cp.person_id
FROM company_person as cp
INNER JOIN position as pos ON pos.id = cp.position_id
INNER JOIN #input as i ON i.position_name = pos.position_name
WHERE com.id = cp.company_id
GROUP BY
cp.person_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM #input)
) as cp
INNER JOIN person as per ON per.id = cp.person_id;
There are other solutions also, such as a double NOT EXISTS
SELECT
com.name,
per.name
FROM company as com
INNER JOIN person as per
ON NOT EXISTS (SELECT 1
FROM position as pos
INNER JOIN #input as i ON i.position_name = pos.position_name
WHERE NOT EXISTS (SELECT 1
FROM company_person as cp
WHERE cp.position_id = pos.id
AND cp.company_id = com.id
AND cp.person_id = per.id
)
);
Another option is a LEFT JOIN then check that they were all matched
SELECT
com.name,
per.name
FROM company as com
CROSS APPLY (
SELECT
p.id,
p.name
FROM person as per
CROSS JOIN position as pos
INNER JOIN #input as i ON i.position_name = pos.position_name
LEFT JOIN company_person as cp ON cp.position_id = pos.id AND cp.company_id = com.id AND per.id = cp.person_id
GROUP BY
p.id,
p.name
HAVING COUNT(*) = COUNT(cp.person_id)
) as per;

SAP B1 Link AP invoice to PO user

I am trying to generate a query that will return header information for Payment-Hold AP Invoices but also show the username that entered the originating Purchase Order.
Some of my invoices do not have a relationship history so I wouldn't expect any user details to be returned but still need the invoice header information. Others have multiple GRPO entries and are therefore returning 2-3 lines where I only need one. Below is my query.
thanks in advance.
select distinct T0."DocNum"
,T0."DocDate"
,T0."DocType"
,T0."CardCode"
,T0."CardName"
,T0."DocStatus"
,T0."GroupNum"
,T0."DocDueDate"
,T0."DocCur"
,T0."DocTotal"
,T0."DocTotalFC"
,T0."PayBlock"
,T0."PaymentRef"
--,T1."DocEntry"
--,T2."DocEntry"
--,T4."DocNum"
--,T3."ItemCode"
--,IFNULL(T4."UserSign", 0) AS "User_Code"
-- ,T4."UserSign"
,T5."U_NAME" as "Purc_User"
,IFNULL(T5."U_NAME",'') as "PURC_USER"
,'HT' as Entity
,T0."Comments"
FROM OPCH T0
left JOIN PCH1 T1 ON T1."DocEntry" = T0."DocEntry"
left JOIN PDN1 T2 on T1."BaseEntry"= T2."DocEntry" and T1."BaseLine"= T2."LineNum"
left JOIN POR1 T3 on T2."BaseEntry" = T3."DocEntry" and T2."BaseLine" = T3."LineNum"
left JOIN OPOR T4 on T4. "DocEntry" = T3."DocEntry"
left JOIN OUSR T5 on T5."USERID" = T4."UserSign"
where T0."DocStatus" = 'O'
and T0."PayBlock" = 'Y'
order by T0."DocNum"

Comparison of online sales by product category-SQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am beginner to SQL and I need to compare online sales by product category in each country in the first quarter of the last three years.
I want a query in adventureworks.How should I do that?Thanks
SELECT Co.Name AS Country
, C.Name AS Category
, YEAR(OH.OrderDate) AS [Year]
, DATEPART(QUARTER,OH.OrderDate) AS [Quater]
, SUM(OD.LineTotal) AS Sales
FROM [Sales].[SalesOrderDetail] OD
INNER JOIN [Sales].[SalesOrderHeader] OH ON OD.SalesOrderID = OH.SalesOrderID
INNER JOIN [Production].[Product] P ON OD.ProductID = P.ProductID
INNER JOIN [Production].[ProductSubcategory] SC ON P.ProductSubcategoryID = SC.ProductSubcategoryID
INNER JOIN [Production].[ProductCategory] C ON SC.ProductCategoryID = C.ProductCategoryID
INNER JOIN [Person].[BusinessEntity] Pe ON Pe.BusinessEntityID = OH.CustomerID
INNER JOIN [Person].[BusinessEntityAddress] A ON A.BusinessEntityID = Pe.BusinessEntityID
INNER JOIN [Person].[Address] AD ON AD.AddressID = A.AddressID
INNER JOIN [Person].[StateProvince] SP ON AD.StateProvinceID = SP.StateProvinceID
INNER JOIN [Person].[CountryRegion] Co ON SP.CountryRegionCode = Co.CountryRegionCode
WHERE OH.OnlineOrderFlag = 1
AND DATEPART(QUARTER,OH.OrderDate) = 1
AND OH.OrderDate >= DATEADD(YEAR, DATEDIFF(YEAR,0,GETDATE()) -3, 0)
GROUP BY Co.Name , C.Name , YEAR(OH.OrderDate), DATEPART(QUARTER,OH.OrderDate)

Replacement for "Or" to avoid twice evaluation of conditions and to improve query performace [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
"Or" decreases the performance of query because the optimizer has to evaluate both the conditions. In complex queries this becomes very expensive to evaluate two conditions because of joins and heavy tables. So what are replacements for "Or" operator. Do we use UNION every time? Then what about running the same complex query twice? And on the contrary it's also expensive.
Edit:
In the below example six tables are used and they all have more that 100000 records in each. The Or operator is between ccm.cID = 1001 and (ma.coID = 2 AND ma.cID = 1001). And to fetch records the optimizer has to evaluate both the conditions. :
SELECT dep.*
FROM dep with (NOLOCK)
JOIN ma with (NOLOCK) ON dep.mID = ma.mID
LEFT JOIN ccm with (NOLOCK) ON ccm.cID = dep.cID
LEFT JOIN ctm with (NOLOCK) ON ctm.cID = dep.cID
LEFT JOIN cptgm with (NOLOCK) ON cptgm.cID = dep.cID
WHERE ma.mtID = 3
AND dep.del = 0 AND dep.pub = 1
AND (ccm.cID = 1001 OR (ma.coID = 2 AND ma.cID = 1001))
AND ctm.tID = 2
AND cptgm.ptgID IN (SELECT ptgID FROM psptgm WHERE psID = 145214
AND ib = 1)
And if we break the query in two with having one condition at time and then combine it with a UNION the performance decreases because of the twice execution.
Not a lot you can do without knowing more about or changing the data model
Lets take it step by step and find a small optimization in this example:
First pull out the sub-query to a join, I believe this change will give you better performance on some version of SQL. Also it makes the query clearer.
SELECT dep.*
FROM dep with (NOLOCK)
JOIN ma with (NOLOCK) ON dep.mID = ma.mID
LEFT JOIN ccm with (NOLOCK) ON ccm.cID = dep.cID
LEFT JOIN ctm with (NOLOCK) ON ctm.cID = dep.cID
LEFT JOIN cptgm with (NOLOCK) ON cptgm.cID = dep.cID
JOIN psptgm with (NOLOCK) ON cptgm.ptgID = psptgm.ptgID and psptgm.ib = 1 and psptgm.psID = 145214
WHERE ma.mtID = 3
AND dep.del = 0
AND dep.pub = 1
AND (ccm.cID = 1001 OR (ma.coID = 2 AND ma.cID = 1001))
AND ctm.tID = 2
I also prefer to write it like this (I think it is clearer):
SELECT dep.*
FROM dep with (NOLOCK)
JOIN ma with (NOLOCK) ON dep.mID = ma.mID and ma.mtID = 3
LEFT JOIN ccm with (NOLOCK) ON ccm.cID = dep.cID
LEFT JOIN ctm with (NOLOCK) ON ctm.cID = dep.cID AND ctm.tID = 2
LEFT JOIN cptgm with (NOLOCK) ON cptgm.cID = dep.cID
JOIN psptgm with (NOLOCK) ON cptgm.ptgID = psptgm.ptgID and psptgm.ib = 1 and psptgm.psID = 145214
WHERE dep.del = 0
AND dep.pub = 1
AND (ccm.cID = 1001 OR (ma.coID = 2 AND ma.cID = 1001))
This makes the join only modifiers vs the where clause clearer.
Now It is easy to see the common parts of the or in the main select and pull those out (thus reducing the number of checks the or clause makes and increasing performance):
WITH prequery AS
(
SELECT dep.*
FROM dep with (NOLOCK)
LEFT JOIN ctm with (NOLOCK) ON ctm.cID = dep.cID AND ctm.tID = 2
LEFT JOIN cptgm with (NOLOCK) ON cptgm.cID = dep.cID
JOIN psptgm with (NOLOCK) ON cptgm.ptgID = psptgm.ptgID and psptgm.ib = 1 and psptgm.psID = 145214
WHERE dep.del = 0 AND dep.pub = 1
)
SELECT dep.*
FROM prequery with (NOLOCK)
JOIN ma with (NOLOCK) ON dep.mID = ma.mID and ma.mtID = 3
LEFT JOIN ccm with (NOLOCK) ON ccm.cID = dep.cID
LEFT JOIN cptgm with (NOLOCK) ON cptgm.cID = dep.cID
WHERE ISNULL(ccm.cID,0) = 1001 OR (ma.coID = 2 AND ma.cID = 1001)

Problem with result of a sql statement [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have a sql statement that repeat a record sevral time I don't know why!
This is my statement:
select floor((a.created-c.created)*24)
|| ' HOURS ' ||
mod(floor((a.created-c.created)*24*60),60)
|| ' MINUTES ' ,a.pkey as AssignedGroupResponseTime,a.pkey,d.newString as AssignedGroup
from
(
select g.created,g.issueid as groupid1, ji.pkey ,ci.newString
from changegroup g
join jiraissue ji on (ji.id = g.issueid)
join changeitem ci on (ci.groupid = g.id)
where (g.created, ji.pkey) in (
select min(g.created) ,ji.pkey
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field = 'Group'
and ci.oldString like 'Triage'
and p.pname = 'Change Management'
and pr.pname='P3'
and ji.created between '01/03/2011' and '16/08/2011'
group by ji.pkey
)) a
left join (
select ji.created, ji.id as groupid2 ,ji.pkey ,ci.newString
from jiraissue ji
join changegroup g on (g.issueid = ji.id)
join changeitem ci on (ci.groupid = g.id)
join project p on (p.id = ji.project)
where p.pname = 'Change Management'
and ci.field = 'Group'
and ci.oldString like 'Triage'
and ji.created between '01/03/2011' and '16/08/2011'
) b ON ( a.pkey = b.pkey)
left join (
select g.created, g.issueid as groupid1 ,ji.pkey ,ci.newString
from changegroup g
join jiraissue ji on (ji.id = g.issueid)
join changeitem ci on (ci.groupid = g.id)
where (g.created, ji.pkey) in (
select min(g.created) ,ji.pkey
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field='assignee'
and ci.newString is not NULL
and p.pname = 'Change Management'
and pr.pname='P3'
and ji.created between '01/03/2011' and '16/08/2011'
group by ji.pkey)) c
ON (c.pkey = a.pkey)
left join (
select g.created, g.issueid as groupid1 ,ji.pkey ,ci.newString
from changegroup g
join jiraissue ji on (ji.id = g.issueid)
join changeitem ci on (ci.groupid = g.id)
where (g.created, ji.pkey) in (
select min(g.created) ,ji.pkey
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field='assigned group'
and ci.newString is not NULL
and p.pname = 'Change Management'
and pr.pname='P3'
and ji.created between '01/03/2011' and '16/08/2011'
group by ji.pkey)) d
ON (d.pkey = c.pkey);
This is because you have duplicate keys on view b or c.
You can run separately this views and see what is wrong(duplicate key values).
In that view you have joins. Almost one join is made with a weak condition. That means you have duplicate matches for one condition.