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
Related
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.
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
I am querying a table for some basic information, file number, case type, status, etc. In addition I need a column for every single one of 138 case status types that will display the date the case had that status. Here is a sample:
SELECT FileNum,
CaseType,
CurrentCaseStatus,
(SELECT TOP 1 EventDt FROM caseStatusHistory WHERE CaseID = c.caseID AND CaseStatus = 'CS001' ORDER BY EventDt DESC) AS [Charge - Phone],
(SELECT TOP 1 EventDt FROM caseStatusHistory WHERE CaseID = c.caseID AND CaseStatus = 'CS002' ORDER BY EventDt DESC) AS [Charge - Written],
-- 136 more just like the live above
FROM Case c
I can query another table for all the case status types:
SELECT Code, Description
FROM caseStatus
WHERE Code BETWEEN 'CS001' AND 'CS138'
ORDER BY Code
How can I dynamically create each of those columns instead of having to manually write 138 select statements?
That's going to be terribly slow -- 138 correlated subqueries. I think you can achieve the same result with an OUTER JOIN and a GROUP BY with MAX and CASE:
Select c.filenum,
c.casetype,
c.currentcasestatus,
max(case when csh.CaseStatus = 'CS001' then EventDt end) as [Charge - Phone],
max(case when csh.CaseStatus = 'CS002' then EventDt end) as [Charge - Written]
from case c
left join casestatushistory csh on c.caseid = csh.caseid
group by c.filenum,
c.casetype,
c.currentcasestatus
BTW, I would suggest just writing the statement out -- it won't take that long and it will out perform a dynamic sql approach. I'm not completely sure how you'd get your column names with dynamic sql either unless Phone and Written are in another column.
Try using a PIVOT. The SQL below should work -
--Select the pivot data into a temp table
SELECT c.caseID,
c.FileNum,
c.CaseType,
c.CurrentCaseStatus,
csh.EventDt,
cs.Description
INTO #StatusDates
FROM [Case] c
LEFT JOIN caseStatusHistory csh
ON csh.caseID = c.caseID
LEFT JOIN caseStatus cs
ON cs.Code = csh.CaseStatus
--From the pivot data, get the list of field names (assumes description field is the source for the field name)
DECLARE #statusDescriptions VARCHAR(MAX)
SET #statusDescriptions = ''
SELECT #statusDescriptions = COALESCE(#statusDescriptions+'[','') + Description
FROM (
SELECT DISTINCT Description
FROM #StatusDates
WHERE Description IS NOT NULL
) x
SET #statusDescriptions = REPLACE(#statusDescriptions, '[', '],[') + ']'
SET #statusDescriptions = SUBSTRING(#statusDescriptions, 3, LEN(#statusDescriptions))
--Create a SQL statement to pivot the data into the fields.
DECLARE #sql VARCHAR(MAX)
SET #SQL = '
SELECT *
FROM #StatusDates
PIVOT(MIN(EventDt)
FOR Description IN (' + #statusDescriptions + '))
AS PVTTable '
PRINT #sql
EXEC(#sql)
DROP TABLE #StatusDates
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
So I'm having a table like
Now I need to get this packed into a datagridview when a choice is made in a combobox filled with the uv ='owner'.
If I make a choice of the uv eg MG. I get a list of all his files/dosno he worked in and the times he spend working on the file.
I do this with this query :
SELECT kbpres.uv,
dbo.doss.dosno,
SUM(dbo.kbpres.uur) AS somuur,
SUM(dbo.kbpres.minuut) AS somminuut,
CAST (( SUM(dbo.kbpres.uur) + SUM(dbo.kbpres.minuut) / 60 ) AS VARCHAR(4)
) +
'u ' + CAST (( SUM(dbo.kbpres.minuut) % 60 ) AS VARCHAR(2)) + 'm' AS
[derivedColumn],
doss.behdr
FROM dbo.kbpres
INNER JOIN dbo.doss
ON dbo.kbpres.ino = dbo.doss.ino
WHERE ( dbo.kbpres.uv LIKE #cboBeheerder )
GROUP BY kbpres.uv,
dbo.doss.dosno,
doss.behdr
(Allthough I would only like to group by UV, and have to add the dosno and behdr as well ??)
The problem is now, how can I count the correct cost, as it is per record different.
for MG it would be :
10 * 60 for dosno 88888
20 * 76 for 66666
60*10 + (28hours+10minutes * 10) + 10*2 for 12345
Any idea if this is even possible ??
SELECT dosno,
SUM(uur)*60 + SUM(minuut) AS Time,
(SUM(uur)*60 + SUM(minuut)) * cost AS TotalCost
FROM dbo.kbpres k
INNER JOIN dbo.doss d ON k.ino = d.ino
GROUP BY dosno,k.ino,d.ino,cost
WHERE k.uv = 2
As cost seems to be a function of uv and dosno try
SELECT dosno,SUM(Time) AS Time,SUM(TotalCost) AS TotalCost FROM
(
SELECT dosno,
uur*60 + minuut AS Time,
(uur*60 + minuut) * cost AS TotalCost
FROM dbo.kbpres k
INNER JOIN dbo.doss d ON k.ino = d.ino
GROUP BY dosno,k.ino,d.ino,cost
WHERE k.uv = 2
) t
GROUP BY dosno