Aggregating two rows, SQL - sql

This is an example of what I'm working on
table
Forgive the picture, I couldn't figure out the table feature
This is my code
select o.id order_id, m.id, m.override_pay_amt
from orders o
left join movement_order mo
on o.id = mo.order_id
and mo.company_id = 'TMS'
left join movement m
on mo.movement_id = m.id
and m.company_id ='TMS'
where o.status != 'V' and o.company_id = 'TMS' and (o.id = '6008227' or o.id = '6000006')
order by o.id
I can't figure out how to combine order_id 6008227 in to one row.
I've tried:
select o.id order_id, m.id, sum(m.override_pay_amt) pay
from orders o
left join movement_order mo
on o.id = mo.order_id
and mo.company_id = 'TMS'
left join movement m
on mo.movement_id = m.id
and m.company_id ='TMS'
where o.status != 'V' and o.company_id = 'TMS' and (o.id = '6008227' or o.id = '6000006')
group by o.id
order by o.id
but when I do this, it makes me group by m.id and nothing changes in the table.
What am I missing?

Related

JOIN two SELECT without UNION

It needs to download the ID, name and surname of those who have registered by the deadline and have an identity card (with the relevant conditions) or passport (with the relevant conditions). ID card and passport are two separate tables.
I have made the SQL queries in UNION format and it works:
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
join persons.id_card idd on d.id_card_id = idd.id
join persons.id_card_to_registration ir on idd.id = ir.id_card
join registrations.registration r on ir.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and ir.status in (0,5)
UNION
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
join persons.passport pass on d.passport_id = pass.id
join persons.passport_country pc on pc.id = pass_country_id
join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on pr.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true);
I would now like to do this SQL in one query without union and unfortunately it doesn't work for me - I tried to do it like this:
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
left join persons.id_card idd on d.id_card_id = idd.id
left join persons.id_card_to_registration ir on idd.id = ir.id_card
left join persons.passport pass on d.passport_id = pass.id
left join persons.passport_country pc on pc.id = pass_country_id
left join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on ir.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and (ir.status in (0,5) or ir.status is null)
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true)
And it doesn't return any records to me. I would like some advice on what error I have made. And is it possible to create such a query without union?
The SQL in clause may help to filter by each condition. This may be the way to avoid the union clause, please let me know if this works for you:
select distinct p.id, p.name, p.surname from persons.person p
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and ((p.id in
(select distinct p2.id from persons.person p2
d.person_id from persons.documents d on d.person_id = p2.id
join persons.id_card idd on d.id_card_id = idd.id
join persons.id_card_to_registration ir on idd.id = ir.id_card
join registrations.registration r on ir.registration_id = r.id
where p2.registration_id = r.id
and ir.status in (0,5)
)
) or (
(p.id in
(select distinct p3.id from persons.person p3
d.person_id from persons.documents d on d.person_id = p3.id
join persons.passport pass on d.passport_id = pass.id
join persons.passport_country pc on pc.id = pass_country_id
join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on pr.registration_id = r.id
where p3.registration_id = r.id
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true);
)
)
))
I think you'll have better performance if you can convert the query to use EXISTS.
SELECT DISTINCT p.id, p.name, p.surname
FROM persons.person p
WHERE p.created_at >= '2022-01-01'
AND p.created_at <= '2022-03-30'
AND(EXISTS (SELECT *
FROM persons.documents d
JOIN persons.id_card idd
ON d.id_card_id = idd.id
JOIN persons.id_card_to_registration ir
ON idd.id = ir.id_card
JOIN registrations.registration r
ON ir.registration_id = r.id
WHERE p.id = d.person_id
AND p.registration_id = r.id
AND ir.status IN (0,5))
OR EXISTS (SELECT *
FROM persons.documents d
JOIN persons.passport pass
ON d.passport_id = pass.id
JOIN persons.passport_country pc
ON pc.id = pass_country_id
JOIN persons.passport_to_registration pr
ON pass.id = pr.passport_id
JOIN registrations.registration r
ON pr.registration_id = r.id
WHERE p.id = d.person_id
AND p.registration_id = r.id
AND pc.zone IN (0,1)
OR (pc.zone IS NULL
AND pass.safe = TRUE)))

Nested query WHERE procedure code IN and AND

Would like to take the following Query and alter it so that it brings back ONLY records where each patient (based on MRN) has BOTH ProcedureCodeList IN ('115-1','117-1','311-1') AND ProcedureCodeList = '119-103'
SELECT P.SiteID, O.ProcedureCodeList, P.MRN, PINFO.LastName, PINFO.FirstName, PINFO.[State] AS Species, PINFO.City AS Breed, O.ProcedureDescList, RF.FieldName, RF.FieldValue, R.ContentText
, R.LastSignDate
FROM ReportFinding RF
INNER JOIN Report R
ON RF.ReportID = R.ReportID
INNER JOIN [Order] O
ON R.ReportID = O.ReportID
INNER JOIN Visit V
ON O.VisitID = V.VisitID
INNER JOIN Patient P
ON P.PatientID = V.PatientID
INNER JOIN PersonalInfo PINFO
ON P.PersonalInfoID = PINFO.PersonalInfoID
WHERE
O.ProcedureCodeList IN ('115-1','117-1','119-103')
ORDER BY R.LastSignDate DESC
There are a couple of ways to solve this. One way is to create two subqueries and join them on the MRN.
SELECT a.SiteID, a.ProcedureCodeList, a.MRN, a.LastName, a.FirstName, a.Species, a.Breed, a.ProcedureDescList, a.FieldName, a.FieldValue, a.ContentText, a.LastSignDate
FROM
(SELECT P.SiteID, O.ProcedureCodeList, P.MRN, PINFO.LastName, PINFO.FirstName, PINFO.[State] AS Species, PINFO.City AS Breed, O.ProcedureDescList, RF.FieldName, RF.FieldValue, R.ContentText, R.LastSignDate
FROM ReportFinding RF
INNER JOIN Report R ON RF.ReportID = R.ReportID
INNER JOIN [Order] O ON R.ReportID = O.ReportID
INNER JOIN Visit V ON O.VisitID = V.VisitID
INNER JOIN Patient P ON P.PatientID = V.PatientID
INNER JOIN PersonalInfo PINFO ON P.PersonalInfoID = PINFO.PersonalInfoID
WHERE O.ProcedureCodeList IN ('115-1','117-1','119-103')) as a
JOIN
(SELECT P.MRN
FROM [Order]
INNER JOIN Visit V ON O.VisitID = V.VisitID
INNER JOIN Patient P ON P.PatientID = V.PatientID
WHERE O.ProcedureCodeList = '119-103') as b ON a.MRN = b.MRN
ORDER BY a.LastSignDate
The PersonalInfo table is not needed in the second query. I don't think ReportFinding and Report are either, based on your JOINs. It depends on what these tables are actually doing.
Another way starts with the original query and adds the following to the WHERE clause (before the ORDER BY):
AND P.MRN IN
(SELECT P.MRN
FROM [Order]
INNER JOIN Visit V ON O.VisitID = V.VisitID
INNER JOIN Patient P ON P.PatientID = V.PatientID
WHERE O.ProcedureCodeList = '119-103')
I would look at the execution plans of both solutions to know which is the better one in this case.

TSQL Update table timing out

The sql in the stored procedure has several updates. I have fixed one and the one left is still timing out.
The table being updated has over 600000 records. The select statement in the sql runs fast when tested alone so it has to be the update part.
UPDATE tblPackage
SET IsUpdated = 1,
ShippingCost = (
SELECT SUM(SC.ShippingCost)
FROM tblShippingCost SC
WHERE SC.PackageID = P.PackageID)
FROM tblShippingCost SC
INNER JOIN tblPackage P ON P.PackageID = SC.PackageID
INNER JOIN tblRunPackage RP ON RP.PackageID = P.PackageID
INNER JOIN tblRun R ON R.RunID = RP.RunID
INNER JOIN tblOrderItem OI ON OI.OrderItemID = R.OrderItemID
INNER JOIN tblOrder O ON O.OrderID = OI.OrderID
WHERE
O.InvoiceID IS NULL
AND SC.PackageID = P.PackageID
I welcome any and all suggestions.
Thanks!
You have joined tblshippingcost an extra time, this will not give the wrong result. But it will take more time joining and calculating. Try removing that part from your update like this:
UPDATE tblPackage
SET
IsUpdated = 1,
ShippingCost = (
SELECT SUM(SC.ShippingCost)
FROM tblShippingCost SC
WHERE SC.PackageID = P.PackageID
)
FROM
tblPackage P
INNER JOIN
tblRunPackage RP ON RP.PackageID = P.PackageID
INNER JOIN
tblRun R ON R.RunID = RP.RunID
INNER JOIN
tblOrderItem OI ON OI.OrderItemID = R.OrderItemID
INNER JOIN
tblOrder O ON O.OrderID = OI.OrderID
WHERE
O.InvoiceID IS NULL
try this
UPDATE tblPackage
SET IsUpdated = 1,
ShippingCost = SUM(SC.ShippingCost)
FROM tblShippingCost SC
INNER JOIN tblPackage P ON P.PackageID = SC.PackageID
INNER JOIN tblRunPackage RP ON RP.PackageID = P.PackageID
INNER JOIN tblRun R ON R.RunID = RP.RunID
INNER JOIN tblOrderItem OI ON OI.OrderItemID = R.OrderItemID
INNER JOIN tblOrder O ON O.OrderID = OI.OrderID
WHERE
O.InvoiceID IS NULL
AND SC.PackageID = P.PackageID

How to UPDATE a table on SQL Server with multiple Joins on the updated table? (FROM FROM JOIN)

How to UPDATE a table on SQL Server with multiple Joins on the updated table?
In MySQL you can define a Alias for updated table, but how does it works with TSQL.
UPDATE recert.ou --#1-- In MSSQL/TSQL no alias allowed
SET parent_id = o2.ID
FROM recert.ou as O
JOIN recert.country C ON C.ID = O.country_id
JOIN recert.ou P ON O.parent_id = P.ID and p.country_id <> O.country_id
JOIN recert.ou o2 on o2.name = p.name and c.ID = o2.country_id
JOIN recert.country as c2 on c2.ID = o2.country_id
WHERE O.ID = o2.ID
-
RESULT: *The table 'o' is ambiguous.*
This works on Sql Fiddle.
UPDATE o
SET parent_id = o2.ID
FROM recert O
JOIN c C ON C.ID = O.country_id
JOIN recert P ON O.parent_id = P.ID and p.country_id <> O.country_id
JOIN recert o2 on o2.name = p.name and c.ID = o2.country_id
JOIN c c2 on c2.ID = o2.country_id
WHERE O.ID = o2.ID
I suppose the problem arose because you tried to re-alias an alias, but I'm not sure.
You can move everything into the WHERE clause:
UPDATE o --#1-- In MSSQL/TSQL no alias allowed
SET parent_id = o2.ID
FROM c, o, o o2, C c2
Where o.country_id = c.id and o.parent_id = p.id and p.country_id <> O.country_id and
o2.name = p.name and c.ID = o2.country_id and c2.ID = o2.country_id
This is not my favorite style of joins, but it should suffice for your purposes.
However, in TSQL, I would really do the following. Create a query that returns the new update value for each id. Then write a query with the following format:
with toupdate as (<the query>)
update o
set o.parent_id = toupdate.id
from toupdate
where o.id = toupdate.id
You just need to remove the alias name for o table
UPDATE o
SET parent_id = o2.ID
FROM o
JOIN c C ON C.ID = o.country_id
JOIN o P ON o.parent_id = P.ID and p.country_id <> o.country_id
JOIN o o2 on o2.name = p.name and c.ID = o2.country_id
JOIN c c2 on c2.ID = o2.country_id
WHERE o.ID = o2.ID
self joined update
update #table1 set column1= b.column2
from #table1 #table1, #table1 b where #table1.Id=b.Id

Two If selection while a select query

SELECT o.id, o.id as oid, o.id as orderId, o.cid, o.date, o.state,
o.price, o.currency, o.lastChange, o.url AS permalink, o.period,
o.bloggerId, o.bloggerShare, o.offerValidity, o.rebate, o.cid,
o.reason, o.bidReason, o.bidDate, o.bidPeriod, o.rate,
o.lastChange2, o.permalinkDate, o.cancelDate, o.bidValidDate,
o.acceptDate, o.approveDate, o.archived, o.bloggerPrice,
o.customerPrice, o.cancelReason, o.listPrice, o.adFormat,
o.lastPayDate, o.startDate, o.endDate, o.customerBidDate,
o.zoneId, c.campaignStartDate, c.campaignEndDate,
c.type as campaignType, c.test, c.test1, c.special, c.packageId,
c.fixPrice, c.type, c.priceBidding, c.textCreation, o.hiddenField,
o.startDate, p.url as producturlold, p.pressurl, p.companyurl,
p.blogurl, p.mediaurl, p.short,
p.description as productDescription, p.description2, p.image,
c.teaser, c.kind, c.title, mc.country as campaignCountry,
c.minlen, c.productPrice, c.currency as campaignCurrency,
c.productTitle, c.url, c.producturl, c.pressurl, c.companyurl,
c.blogurl, c.mediaurl, c.description, c.image, c.teaser,
c.productReturn, c.testProduct, c.mid as customerId, c.adText,
c.fixAdText, c.requiresBlog, c.bidStop, c.accountingPeriod,
c.actionCodeType, c.actionCodesDescription, ac.code,
ac2.code as massCode, b.title as blogtitle, b.url as bloggerurl,
b.pis as pis, b.uniqueVisitors as uvs, b.pisCounter as pisCounter,
b.uvsCounter as uvsCounter, b.aPI as aPI, b.aUV as aUV,
b.id as blogId, p.title as productTitleOld,
b.lastChange as blogLastChange, b.trRank, r1.rate as orderRate,
r2.Rate as memberRate, b.reviews
FROM rates r1, rates r2, orders o
left join blog b on (o.blogId = b.id)
left join codes ac on (ac.orderId = o.id), campaign c
left join product p on (c.productId = p.id)
left join codes ac2 on (ac2.campaignId = c.id and
c.actionCodeType = 2),
person mc
where o.cid = c.id
and mc.mid = c.mid
and o.id = '223704'
and o.state <> 0
and r1.currency = o.currency
and r2.currency = 'EUR'
and r1.date = FROM_UNIXTIME(o.date, '%Y-%m-%d')
and r2.date = r1.date
I wnat to test if memberRate and orderRate is Null it should continue how can i do that? Any idea?
Tack this on the end should do the trick:
--Within the WHERE clause
AND r2.Rate IS NOT NULL
AND r1.Rate IS NOT NULL
I'm not sure I understand what you are asking, but add and memberRate is not null and orderRate is not null to the end of your query and you will skip all results where either of those two fields are null.