show one row and sum values - sql

I have a query to select invoices and their items from database. I have posted example down below with two invoices having 3 invoice items (I'm using linked servers from MSSQL to Oracle DB).
Example with cID 1616251758086 got 3 positions with same "Stawka VAT" so I would like to show only one row with "Stawka VAT" = 0.23000 but values in "Netto", "VAT", "Brutto" should be summed (commented code with SUM works fine but still shows 3 rows, each one with whole sum).
Example with cID 1616251238669 got 3 positions with different "Stawka VAT" values so it should show output like already does.
I tried bunch of things but with no proper result.
CURRENT CODE:
SELECT
invo.cID, -- ID dokumentu
cProcessID, -- Dane faktury ERP
cERPNumber, -- Dane z pola cProcessID
cERPStatus, -- Wartość zmienia się na 200 po pobraniu danych
invo.cType as 'Typ dok',
cINumberExternal as 'Nr dok',
(CASE WHEN invo.cType = 'creditmemo' THEN cReferencingInvoiceNr ELSE '' END) as 'Korekta',
cIDateExternal as 'Data wyst',
cDeliveryDate as 'Data dok',
cDateOfReceipt AS 'Data wpływu',
ISNULL(invo_items.cText, '') as 'Treść',
invo_items.cCurrency as 'Waluta',
ISNULL(cCurrencyRate, '') as 'Kurs',
invo_items.cIItemNumber as 'Pozycja faktury',
invo_items.cTaxRate as 'Stawka VAT',
invo_items.cNetTotalAmount as 'Netto',
invo_items.cTaxAmount as 'VAT',
invo_items.cNetTotalAmount+invo_items.cTaxAmount as 'Brutto',
--SUM(invo_items.cNetTotalAmount) OVER(Partition by invo_items.ciid, invo_items.cTaxRate) as 'Netto',
--SUM(invo_items.cTaxAmount) OVER(Partition by invo_items.ciid, invo_items.cTaxRate) as 'VAT',
--SUM(invo_items.cNetTotalAmount+invo_items.cTaxAmount) OVER(Partition by invo_items.ciid,invo_items.cTaxRate) as 'Brutto',
cBaselineDate as 'Termin płatności',
invo.cVendorID as 'VendorID',
cVendorVatnumber as 'VendorNIP',
CONCAT(kh.cname, '', kh.cname2) as 'VendorName',
kh.cStreet as 'Ulica',
kh.cCity as 'Miasto',
kh.cCountry as 'Kraj'
FROM ORACLE_OTTO..xxxxxx.INVOICES as invo
JOIN ORACLE_OTTO..xxxxxx.VENDORMASTERDATA as kh on kh.cvendorid = invo.cvendorid
JOIN ORACLE_OTTO..xxxxxx.INVOICEITEMS as invo_items on invo.cid = invo_items.ciid
WHERE invo.cID in ('1616251758086', '1616251238669')
CURRENT OUTPUT:
cID
Pozycja faktury
Stawka VAT
Netto
VAT
Brutto
1616251758086
1
0.23000
4.0000
0.9200
4.9200
1616251758086
2
0.23000
1500.0000
345.0000
1845.0000
1616251758086
3
0.23000
20981.0000
4825.6300
25806.6300
1616251238669
1
0.23000
465.2100
107.0000
572.2100
1616251238669
2
0.08000
112.2800
8.9800
121.2600
1616251238669
3
0.05000
152.6400
7.6300
160.2700
EXPECTED OUTPUT:
cID
Pozycja faktury
Stawka VAT
Netto
VAT
Brutto
1616251758086
1,2,3
0.23000
22485.0000
5171.5500
27656.5500
1616251238669
1
0.23000
465.2100
107.0000
572.2100
1616251238669
2
0.08000
112.2800
8.9800
121.2600
1616251238669
3
0.05000
152.6400
7.6300
160.2700

Maybe using a common table expression would help?
with cte as (
select .... -- your query from the question
)
select
cte.cID,
cte.cIItemnumber as 'Pozycja faktury',
cte.cTaxRate as 'Stawka VAT',
SUM(cte.cNetTotalAmount) as 'Netto',
SUM(cte.cTaxAmount) as 'VAT',
SUM(cte.cNetTotalAmount+cte.cTaxAmount) as 'Brutto'
from cte
group by cte.cID, cte.CIItemnumber,cte.cTaxRate
Did not try this out of course, but you will get my drift... :)

This one should do your job:
SELECT
invo.cID,
STUFF((
SELECT ', ' + CAST(i_qry.cIItemNumber AS varchar)
FROM ORACLE_OTTO..xxxxxx.INVOICEITEMS i_qry
WHERE invo.cid = i_qry.ciid
FOR XML PATH('')
), 1, 2, '') AS [Pozycja faktury],
invo_items.cTaxRate AS [Stawka VAT],
SUM(invo_items.cNetTotalAmount) AS [Netto],
SUM(invo_items.cTaxAmount) AS [VAT],
SUM(invo_items.cNetTotalAmount + invo_items.cTaxAmount) AS [Brutto]
FROM
ORACLE_OTTO..xxxxxx.INVOICES as invo
JOIN ORACLE_OTTO..xxxxxx.VENDORMASTERDATA as kh on kh.cvendorid = invo.cvendorid
JOIN ORACLE_OTTO..xxxxxx.INVOICEITEMS as invo_items on invo.cid = invo_items.ciid
GROUP BY
invo.cID, invo_items.cTaxRate
In this case I assume that ORACLE_OTTO..xxxxxx.INVOICESITEMS.cIItemNumber is a number. In case it is a char/varchar, just remove the CAST around it.

Related

How to get the result in below format in SQL Server?

I have a table called recipes with following data.
page_no title
-----------------
1 pancake
2 pizza
3 pasta
5 cookie
page_no 0 is always blank, and missing page_no are blank, I want output as below, for the blank page NULL values in the result.
left_title right_title
------------------------
NULL pancake
Pizza pasta
NULL cookie
I have tried this SQL statement, but it's not returning the desired output:
SELECT
CASE WHEN id % 2 = 0
THEN title
END AS left_title,
CASE WHEN id %2 != 0
THEN title
END AS right_title
FROM
recipes
You are quite close. You just need aggregation:
select max(case when id % 2 = 0 then title end) as left_title,
max(case when id % 2 = 1 then title end) as right_title
from recipes
group by id / 2
order by min(id);
SQL Server does integer division, so id / 2 is always an integer.
Using CTE.. this should be give you a good CTE overview
DECLARE #table TABLE (
pageno int,
title varchar(30)
)
INSERT INTO #table
VALUES (1, 'pancake')
, (2, 'pizza')
, (3, 'pasta')
, (5, 'cookie')
;
WITH cte_pages
AS ( -- generate page numbers
SELECT
0 n,
MAX(pageno) maxpgno
FROM #table
UNION ALL
SELECT
n + 1 n,
maxpgno
FROM cte_pages
WHERE n <= maxpgno),
cte_left
AS ( --- even
SELECT
n,
ROW_NUMBER() OVER (ORDER BY n) rn
FROM cte_pages
WHERE n % 2 = 0),
cte_right
AS ( --- odd
SELECT
n,
ROW_NUMBER() OVER (ORDER BY n) rn
FROM cte_pages
WHERE n % 2 <> 0)
SELECT
tl.title left_title,
tr.title right_title --- final output
FROM cte_left l
INNER JOIN cte_right r
ON l.rn = r.rn
LEFT OUTER JOIN #table tl
ON tl.pageno = l.n
LEFT OUTER JOIN #table tr
ON tr.pageno = r.n

Mapping of Multi-valued column from one table to another table using join in DB2

I am creating a report using SQL in DB2 and I have a field in one of the tables which stores multiple values. Now, I need to reference another table to get the description of these multiple values as shown.
Table A
Item_No| R_code
---------------
X R01,R03,R04
Y R02,R03
Z R04
Table B
R_code| Description
------------------
R01 Missing info
R02 Invalid info
R03 Invalid Account
R04 Missing Address
How do I get the following result if I join Table A and Table B
Final Result
Item_no| R_code | Description
---------------------------
X R01,R03,R04 Missing info,Invalid Account,Missing Address
Y R02,R03 Invalid info,Invalid Account
Z R04 Missing Address
WITH unpivot (lvl, item_no, r_code, tail) AS (
SELECT 1, item_no,
CASE WHEN LOCATE(',',r_code) > 0
THEN TRIM(LEFT(r_code, LOCATE(',',r_code)-1))
ELSE TRIM(r_code)
END,
CASE WHEN LOCATE(',',r_code) > 0
THEN SUBSTR(r_code, LOCATE(',',r_code)+1)
ELSE ''
END
FROM tableA
UNION ALL
SELECT lvl + 1, item_no,
CASE WHEN LOCATE(',', tail) > 0
THEN TRIM(LEFT(tail, LOCATE(',', tail)-1))
ELSE TRIM(tail)
END,
CASE WHEN LOCATE(',', tail) > 0
THEN SUBSTR(tail, LOCATE(',', tail)+1)
ELSE ''
END
FROM unpivot
WHERE lvl < 100 AND tail != ''),
get_desc AS
(
SELECT item_no, up.r_code, tb.description
FROM unpivot up
INNER JOIN tableB tb
ON up.item_no = tb.item_no
)
SELECT item_no,
LISTAGG(r_code, ', ' ) WITHIN GROUP(ORDER BY r_code ASC) AS r_code,
LISTAGG(description, ', ') WITHIN GROUP(ORDER BY description ASC) AS description
FROM get_desc

Summary table with row/column totals using SQL pivot

I need help with SQL for generating pivot table with row/column totals calculated ..I have 2 tables as given below
Table ProbCat
==============
probcat | probdesc
1 minor
2 high
3 showstopper
Table ProbSummary
===================
prodcat | noofproblems | stage
1 5 Dev
2 1 Dev
3 6 QA
3 6 Prod
and I would like to generate a pivot table with row/column total percentages as shown below. I have tried combination of 'pivot' and 'group by' but could not get the row & column total accurately
Probelm Summary view:
ProbCategory CategoryDesc Dev Qa Prod Total(%)
______________________________________________________
1 Minor 5 0 0 5(100*(5/18))
2 High 1 0 0 1(100*(1/18))
3 Showstopper 0 6 6 12(100*(6/18))
Total NA 6(%) 6(%) 6(%)
Just like others mentioned, your summary/total calculation should be done on the presentation layer. But here is my attempt to getting your output minus the last summary line:
;WITH Q1
AS (
SELECT pvt.probcat
,pvt.probdesc
,ISNULL(pvt.[Dev], 0) AS 'Dev'
,ISNULL(pvt.[QA], 0) AS 'QA'
,ISNULL(pvt.[Prod], 0) AS 'Prod'
FROM (
SELECT pc.probcat
,pc.probdesc
,ps.noofproblems
,ps.stage
FROM Probcat pc
LEFT JOIN ProbSummary ps ON pc.probcat = ps.probcat
) t
PIVOT(max(noofproblems) FOR stage IN (
[Dev]
,[QA]
,[Prod]
)) pvt
),
q2 as
(SELECT q1.*
,sum(q1.Dev + q1.QA + q1.Prod) AS Total
FROM q1
GROUP BY q1.probcat
,q1.probdesc
,q1.Dev
,q1.QA
,q1.Prod
)
select q2.probcat
,q2.probdesc
,q2.Dev
,q2.QA
,q2.Prod
,cast(q2.Total as varchar(10)) + ' (' +
cast(cast((cast(q2.Total as decimal(5,2))/cast(d.CrossSum as decimal(5,2)))*100
as decimal(5,2)) as varchar(10))
+ '% )' as FinalTotal
from q2
CROSS APPLY (
SELECT sum(q1.Dev + q1.QA + q1.Prod) AS CrossSum
FROM q1
) d
ORDER BY q2.probcat
SQL Fiddle Demo
with x as
(select p.probcat as probcategory, p.probdesc as categotydesc,
case when s.stage = 'Dev' and s.noofproblems > 0 then s.noofproblems else 0 end as Dev,
case when s.stage = 'QA' and s.noofproblems > 0 then s.noofproblems else 0 end as QA,
case when s.stage = 'Prod' and s.noofproblems > 0 then s.noofproblems else 0 end as Prod
from Probcat p join Probsummary s on p.probcat = s.prodcat)
select probcategory,categotydesc,Dev,QA,Prod, Dev+QA+Prod as Total
from x
this should give what you need except the Total row at the bottom.
Here's a PIVOT query you can work with.. your example has prodcat in one table and probcat in the other.. not sure if that was typo in second table so i just with with probcat for both. should be easy to fix it it gives you an error
;
WITH ProbCatSummary AS
(
SELECT pc.probcat,
pc.probdesc,
SUM(ps.noofproblems) AS noofproblems
FROM ProbCat pc
JOIN ProbSummary ps ON pc.probcat = ps.probcat
GROUP BY pc.probcat,
pc.probdesc
)
SELECT p.*,
[Total (%)] = CONVERT(VARCHAR,[Dev] + [QA] + [Prod])
+ ' (' + CONVERT(VARCHAR,
CAST(ROUND((([Dev] + [QA] + [Prod]) * 100.0 / SUM(ps.noofproblems) OVER()),2) AS DECIMAL(8,2))
)
+ ')'
FROM (
SELECT probcat, probdesc, ISNULL([Dev],0)[Dev], ISNULL([QA],0)[QA], ISNULL([Prod],0)[Prod]
FROM (SELECT pc.probcat, probdesc, stage, noofproblems
FROM ProbCat pc
JOIN ProbSummary ps ON pc.probcat = ps.probcat) AS s
PIVOT (SUM(noofproblems) FOR stage IN ([Dev], [QA], [Prod])) AS p
) p JOIN ProbCatSummary ps ON p.probcat = ps.probcat

Display unique combinations with sums for all of one column

EDIT: Sorry for the vagueness here. Actual question: Is there a better more efficient way to get SQL to get the sums for me?
I might be making this harder than I need to, but here is the situation:
I am creating a demographics listing for the heads of the departments where I work. They want to see the typical demographic information. (Age, Gender, Ethnicity, Service member, First time with us, Major, Degree Level etc.)
However when I was doing this I realized that the US census board can change ethnicity on us at any point, so the report would have to be updated at that time, also things like Major and Degree Level could be added or removed based on the Dept of Education.
So I was looking for a way to write a way to display data from a Table but do sums based on that the number of people with the same area in that table. Sounds weird, and I could be making this out to be way worse than I need to. (I am at 1948 lines of code and not even close to being done so far, all of this lines are basically copy/ paste with slight variations)
My statement for pulling the data is perfect. It works and displays exactly how I want it to for the year ranges I want. (Only posting the first year, not the second or fifth as it is just the date range that changes) NOTE: THis is not the complete SELECT state, as the complete isn't needed for this. The column listings are needed, but you all don't really care about where the data comes from or how I am filtering it
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #StartDateLast DATETIME
DECLARE #EndDateLast DATETIME
DECLARE #StartDateFive DATETIME
DECLARE #EndDateFive DATETIME
DECLARE #State VARCHAR(2)
/*Current Year*/
SET #StartDate = '01/01/2013'
SET #EndDate = '12/31/2013'
CREATE TABLE #Demographics /*Table where the data will be processed andultimately displayed from */
(
demo_id INT IDENTITY(1,1) NOT NULL,
header VARCHAR(100),
subheader VARCHAR(100),
value_year1 NUMERIC,
percent_year1 DECIMAL(10,2),
value_year2 NUMERIC,
percent_year2 DECIMAL(10,2),
value_year5 NUMERIC,
percent_year5 DECIMAL(10,2)
)
SELECT s.ID
,g.Name AS [gender]
, FLOOR(DATEDIFF(DAY,s.dob,GETDATE())/365.25) AS Age
, st.Abbreviation
, eg.Name
,f_ss.Name AS [StudentStatus]
,CASE
WHEN EnrollmentStatus.EnrollmentLevel = 'Full Time' THEN 'FT'
WHEN EnrollmentStatus.EnrollmentLevel = 'Part Time' THEN 'PT'
ELSE 'Unknown' END [Enrollment]
,FirstTime.result AS FirstTime
,major.[Abbreviation] AS [Abbreviation]
,major.Major
,mb.Name AS [ServiceBranch]
,FirstDegree.FirstDegree
INTO #DemoTemp1
FROM dbo.Student s
INNER JOIN studentdegree sd ON s.id = sd.StudentID
JOIN dbo.Gender g ON g.id = s.GenderID
INNER JOIN dbo.address ad ON s.AddressID = ad.ID
INNER JOIN dbo.state st ON ad.StateID = st.ID
LEFT JOIN dbo.EthnicGroup eg ON eg.ID = s.EthnicGroupID
LEFT JOIN dbo.MilitaryBranch mb ON mb.ID = s.MilitaryBranchID
JOIN Prospect p ON s.ID = p.StudentID
So I grab the data, and then I dump it into 3 temp tables, and then pull from them to display and store off from another temp table that is defined above as #Demographics.
Here is how the Result-set data should ultimately be displayed:
demo_id| header | subheader | value_year1| percent_year1
1 Gender:| Male | 15195 | 62.00
2 | Female | 9150 | 37.00
3 | Not Disclosed | 23 | 0.00
4 Age: | Under 18 | 2 | 0.00
5 | 18-20 | 142 | 0.00
6 | 21-25 | 1757 | 7.00
7 | 26-30 | 3815 | 15.00
Here is the Insert from the temp tables into the #Demographics table looks right now, and it is the area that I think ultimately should be changed to so that I am not writing out 1050 combinations of degree's, Majors, ages, and what not.
Age and Gender are easy, its the Combination of Degree level and Major that's killing me. There are roughly 750 combinations I need to account for in total.
When I get to things like the Degree/ Majors, it looks like this combo:
INSERT INTO #Demographics
SELECT
''
,'Graduate Certificate in Project Management'
,(SELECT SUM(CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management' THEN 1 ELSE 0 END) FROM #DemoTemp1 dt1)
,(SELECT ((SUM(CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management THEN 1 ELSE 0 END)*100) / COUNT(dt1.ID)) FROM #DemoTemp1 dt1)
FROM #DemoTemp1 dt1 WHERE dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management GROUP BY (CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management THEN 1 ELSE 0 END)
I have been taking this and editting it multiple times for every Degree level (dt1.abbreviation) and Major (dt1.major)
How do I basically take the dt1.Abbreviation + ' ' + dt1.major combination and get SQL to spit out the sums of the students in that without coding for every combination myself. With the result set I posted above as the desired format
EDIT: This is what I am using now. I am just tweaking the PERC/ Y2P/ Y5P columns to show an actual percentage and not a decimal
SELECT DISTINCT(dt.Abbreviation + ' ' + m.Name) [Program]
,YearOne.Counts
,YearOne.Perc
,YearTwo.Counts [y2c]
,YearTwo.Perc [y2p]
,YearFive.Counts [y5c]
,YearFive.perc [y5p]
FROM degree d
INNER JOIN degreetype dt ON d.DegreeTypeID = dt.ID
INNER JOIN dbo.Majors m ON d.MajorID = m.id
OUTER APPLY (SELECT count(*) Counts
,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt2.id)FROM #DemoTemp1 dt2)AS float)as decimal(10,2))*100 Perc
--,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
FROM #DemoTemp1 dt1
WHERE dt1.[DegreeType]+' '+ dt1.Major = dt.name +' '+ m.name
) YearOne
OUTER APPLY (SELECT count(*) Counts
,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt3.id)FROM #DemoTemp2 dt3)AS float)as decimal(10,2))*100 Perc
--,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
FROM #DemoTemp2 dt2
WHERE dt2.[DegreeType]+' '+ dt2.Major = dt.name +' '+ m.name
) YearTwo
OUTER APPLY (SELECT count(*) Counts
,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt4.id)FROM #DemoTemp5 dt4)AS float)as decimal(10,2))*100 Perc
--,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
FROM #DemoTemp5 dt5
WHERE dt5.[DegreeType]+' '+ dt5.Major = dt.name +' '+ m.name
) YearFive
WHERE 1=1
AND d.Archived = 0
GROUP BY (dt.Abbreviation + ' ' + m.Name), YearOne.Counts, YearOne.Perc,YearTwo.Counts,YearTwo.Perc,YearFive.Counts ,YearFive.perc
HAVING YearOne.Counts > 0
You could change your first query to something like this. It is the same thing and a lot simpler.
SELECT
'Gender'
,'Male'
, count(*)
, (COUNT(*) * 100) / COUNT(dt1.ID)
FROM #DemoTemp1 dt1
WHERE dt1.gender = 'Male'
GROUP BY dt1.gender
You could do something similar in the second one. No need to hit the same table over and over to get aggregate data.
OK. After all the back and forth I think I finally understand what you are asking.
Does something like this work for you second query?
SELECT
''
, dt1.Abbreviation + ' ' + dt1.major
, count(*)
, (count(*) * 100) / COUNT(dt1.ID))
FROM #DemoTemp1 dt1
GROUP BY dt1.Abbreviation + ' ' + dt1.major

How to implement a SQL Server query which has several join conditions

I am trying to implement this query but I can’t figure out why I am not getting the result.
Here are the descriptions:
Lets say I have a table call: TableAct
Acct# Date WithdrawAmt DepositAmt
!24455 2012-11-19-00.00.00 1245.77 200.50
125577 2011-02-12-00.00.00 100.98 578.00
Another table TableCustomerOrd:
ID# COrder# CustID Ord_Description VendorType
124455 7712AS 123 1AAA Permanent
125577 9914DL 346 1BBB Partial
... UK1234 111 2HJ5 Permanent'
,,, FR0912 567 5LGY Partial
Then TableCustomerDtls:
CustID Descriptions Delivery Address ZipCode
123 1AAA_BLUESHARE SUCCESSFUL 222 Main St 97002
346 1BBB_CHASE DECLINE 40 West Side 97122
111 2HJ5_CITIBANK SUCCESSFUL ……. …….
567 5LGY_VANGURD DECLINED ---- -----
And table DelivaryFlight:
FlightOrder# FlightCustID FlightDt
7712AS 123 2011-9-29-00.00.00
9914DL 346 2010-11-2-00.00.00
UK1234 111 2012-4-1-00.00.00
FR0912 567 2012-9-11-00.00.00
I want to update TableAct on the following conditions:
TableAct. Acct# = TableCustomerOrd.ID#, AND:
TableCustomerOrd. CustID = TableCustomerDtls.CustID and at the same time, TableCustomerOrd.Ord_Descriptions field should match with TableCustomerDtls. Descriptions field anything before “_” . Therefore ‘1AAA’, ‘2HJ5’ etc. AND:
DelivaryFlight.FlightOrder# = TableCustomerOrd.COrder#, AND: DelivaryFlight.FlightCustID = TableCustomerOrd. CustID. Also TableCustomerDtls. Delivery = ‘SUCCESSFUL’ AND:
DelivaryFlight.FlightOrder# = TableCustomerOrd. COrder#
AND DelivaryFlight.FlightCustID = TableCustomerOrd. CustID
Also TableCustomerDtls. Delivery = ‘DECLINED
Then I want to compare: elivaryFlight.FlightDt > DelivaryFlight.FlightDt.
Basically I need to match table DelivaryFlight columns FlightOrder#, FlightCustID with TableCustomerOrd.
Moreover TableCustomerDtls column Delivery to ck for delivary status such as ‘DECLINED’.
And ‘SUCCESSFUL’ condition and compare ‘SUCCESSFUL’ FlightDt with ‘DECLINED’ FlightDt.
Here's my query but please help me to understand, I am sure this could be done in a better way.
The query is not working:
Update
Set …
FROM TableAct AC
Join TableCustomerOrd CustOd
ON AC.Acct# = CustOd.ID#
Join TableCustomerDtls CDtls
ON CDtls. CustID = CustOd. CustID
AND (CustOd.Ord_Descriptions =
Left(CDtls.Descriptions, LEN(rtrim(CDtls.Descriptions))))
JOIN DelivaryFlight DF
ON DF.FlightOrder# = CustOd.COrder#
AND DF.FlightCustID = CustOd.CustID
AND CDtls.Delivery = ‘SUCCESSFUL’
JOIN DelivaryFlight DF2
ON DF2.FlightOrder# = DF.COrder#
AND DF2.FlightCustID = DF.CustID
AND CDtls.Delivery = ‘DECLINED’
WHERE DelivaryFlight. FlightDt > DelivaryFlight. FlightDt
AND DepositAmt > 100
Your Help will be monumental 'cause my project due end of this week.
Thank you
If I have a complex query like this, I start by creating a "simple" select which produces only the rows to be updated.
It should also return both the update values and the pk for the updated table
It is then (relatively) straight forward to (inner) join this with the table to be updated and do the update remebering to only update matching rows by including
WHERE tblTobeUpdated.pk = SimpleSelect.pk
Hope this helps
I don't have the time to look at this in depth but I suspect you at least want to fix:
WHERE DelivaryFlight. FlightDt > DelivaryFlight. FlightDt
This is a condition that can never be met.
You probably want:
WHERE DF. FlightDt > DF2. FlightDt
it is also useful with these complex queires for an update to be able to see the records that would be updated, so I usually do something like this:
Update
Set …
--Select *
FROM TableAct AC
Then instead of running the update, I run just highlight and run the part that starts with select to see the results and don't test the update until I am sure I am selecting the records I want to select and that the values I will be replacing are correct.
Try breaking your query down, heres a query I wrote today, test each part separately
SELECT
Employee
, Reference
, Payroll
, [Hours] / 60
[Hours]
, [Days]
FROM
(
SELECT
Employee
, Reference
, Payroll
, SUM( Duration ) AS [Hours]
, AvailableID
FROM
(
SELECT
RequirerID
, Duration
, RTRIM( COALESCE(MA.MemberLastName, '')
+ ' ' + COALESCE(MA.MemberFirstName, '')
+ ' ' + COALESCE(MA.MemberInitial, '')) Employee
, COALESCE(MA.Detailref1, '') Reference
, COALESCE(MA.PayrollRef, '') Payroll
, Available.AvailableId
FROM
(
SELECT DISTINCT
RequirerID
, ShiftDate
, CAST(ShiftStart - ShiftEnd - ShiftBreak AS DECIMAL(19,2)) ShiftDuration
, Id RequirementRecordID
FROM
Requirements
WHERE
Requirements.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = #ParamCompanyID)
)
R
INNER JOIN
ShiftConfirmed
INNER JOIN
Available
INNER JOIN
MemberDetails MA
ON Available.AvailableID = MA.ID
ON ShiftConfirmed.AvailableRecordID = Available.ID
ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
WHERE
R.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
)
ShiftDay
Group By
Employee
, Reference
, Payroll
, AvailableId
) Shifts
INNER JOIN
(
SELECT
COUNT( * ) AS [Days]
, AvailableID
FROM
(
SELECT DISTINCT
R.ShiftDate
, Available.AvailableId
FROM
(
SELECT DISTINCT
ShiftDate
, Id RequirementRecordID
FROM
Requirements
WHERE
Requirements.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = #ParamCompanyID)
)
R
INNER JOIN
ShiftConfirmed
INNER JOIN
Available
INNER JOIN
MemberDetails MA
ON Available.AvailableID = MA.ID
ON ShiftConfirmed.AvailableRecordID = Available.ID
ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
WHERE
R.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
)
ShiftDay
Group By
AvailableId
) D
ON Shifts.AvailableID = D.AvailableID
WHERE [Hours] > 0
ORDER BY
Employee