So I'm extremely new to using SQL. This syntax formatting is offensive but I am editing it in notepad and can't figure out a better alternative. I want it in the .dqy format but I don't know how else to edit. So if you have a suggestion please advise..
A general description: There is that SUM(CASE WHEN ...) portion of code below that I'm trying to get to work. I'm making an exception report, and I want another column that is the conditional average based on my concatenated value exclusive of that entry. IE, in Excel this is an easy formula (Column I):
=+IFERROR(AVERAGEIFS(H:H,C:C,[#Cust],A:A,"<>"&[#[Order Number]]),0)
Except I want to have it pull as part of the query.
Here is a picture of the output:
Here is my SQL. Again I know formatting stinks if there is a different program than notepad that I can edit a .dqy in please advise. Also, what do those 3's mean in the 6th line of my code. I took a query from something else and have been modifying it into this project.
XLODBC
1
DRIVER=SQL Server;
SERVER=*OMIT*;
UID=*OMIT*;
Trusted_Connection=Yes;
APP=Microsoft Office 2010;
WSID=*OMIT*;
DATABASE=*OMIT*
SELECT DISTINCT RMORHP.ORHORDNUM AS 'Order Number',
RMORHP.ORHCRTDTE AS 'Order Create Date',
CONCAT(RMORHP.ORHCUSCHN, '-', RMORHP.ORHCUSNUM) AS 'Cust',
RMORHP.ORHCUSCHN AS 'Chain ID',
RMORHP.ORHCUSNUM AS 'Cust ID',
RMCUSP.CUSCUSNAM AS 'Customer',
RMORHP.ORHCRTUSR AS 'Created By',
RMORHP.ORHORDQTY AS 'Units Ordered',
SUM(CASE
WHEN RMCUSP.CUSCUSNAM = RMCUSP.CUSCUSNAM
THEN RMORHP.ORHORDQTY
END)
GROUP BY RMCUSP.CUSCUSNAM AS 'Total Units'
FROM BIDW_DataLake.erms.RMORHP RMORHP,
BIDW_DataLake.eRMS.RMCUSP RMCUSP
WHERE (RMORHP.ORHCRTDTE BETWEEN ? AND ?)
AND RMCUSP.CUSCUSCHN = RMORHP.ORHCUSCHN
AND RMCUSP.CUSCUSNUM = RMORHP.ORHCUSNUM
AND RMCUSP.CUSDFTDCN = 505
enter
START date "yyyymmdd" enter END date "yyyymmdd"
3 3
Order Number Create Date Cust Chain ID Cust ID Customer Created By
It looks like you are trying to get the average order quantity for other order a customer has made during a given date range. To say it another way: The average of a given customer's orders not including the order in the current row.
If that's correct, you might try replacing the SQL portion of your query with this:
SELECT R1.ORHORDNUM AS 'Order Number',
R1.ORHCRTDTE AS 'Order Create Date',
CONCAT(RMORHP.ORHCUSCHN, '-', RMORHP.ORHCUSNUM) AS 'Cust',
R1.ORHCUSCHN AS 'Chain ID',
R1.ORHCUSNUM AS 'Cust ID',
RMCUSP.CUSCUSNAM AS 'Customer',
R1.ORHCRTUSR AS 'Created By',
R1.ORHORDQTY AS 'Units Ordered',
(SELECT AVG(R2.HORDQTY)
FROM BIDW_DataLake.erms.RMORHP R2
WHERE R2.ORHCUSNUM = R1.ORHCUSNUM
AND R2.ORHORDNUM <> R1.ORHORDNUM) as 'Total Units'
FROM BIDW_DataLake.erms.RMORHP R1,
BIDW_DataLake.eRMS.RMCUSP RMCUSP
WHERE (RMORHP.ORHCRTDTE BETWEEN ? AND ?)
AND RMCUSP.CUSCUSCHN = R1.ORHCUSCHN
AND RMCUSP.CUSCUSNUM = R1.ORHCUSNUM
AND RMCUSP.CUSDFTDCN = 505
The Total Units column is what is known as a correlated subquery. Consider researching that.
What makes this a bad answer:
I have no way of testing it, and I'm not 100% certain of the
MS-Query syntax where Excel connects with SQL Server.
MS-Query may not support correlated subqueries in this way.
I don't quite understand how the parameterized portion of the query works. That is, clearly it looks like the query is meant to ask for a start and end date and put those where the question marks go. I'm trusting that it works as-is. (Though, I suspect this is where your "3 3" is coming from.
So, probably vote this answer down and thrash me soundly for giving a bad answer, but maybe you will get something from it. I just thought it was too much to try to put in a comment.
I din't totally understand the example but for a general case you can use:
AVG(CASE WHEN [condition1] and [condition2] THEN [the value you want to average] Else NULL END).
This shoud return the average if the column fir all the rows that meet your conditions.
Related
I'm trying to modify a report that shows health assessments using SQL. On the report, I would like to add a section for comments that were added to the health assessments. I was able to add the comment section, and with a suggestion provided here, I used SUBSTRING to limit the number of characters displayed on the report to 1000 as opposed to 8000.
The issue I'm experiencing now is with limiting the number of characters displayed for the option 'Other' as shown below. I used SUBSTRING (ex: SUBSTRING(HltNutrition.Comment, 1, 1000)) for all of the assessments and have included the Nutrition assessment as an example (which is working correctly) along with the snippet of code featuring the 'Other' (Chronic) option (which is not working correctly). I replaced 3 with 1 and although this did not produce an error, it did not have the intended effect for 'Other' as SUBSTRING([HealthAssessName].Comment, 1, 1000).
Any assistance is appreciated. Thank you in advance.
-- Nutrition
INSERT INTO #ChronicCondition(IdApplicant, ExamDate, Condition, TreatmentNeeded, TreatmentReceived, Status, Comment)
SELECT #Enroll.IdApplicant,
HltNutrition.ExamDate,
'Nutrition',
HltNutrition.TrtNeed,
HltNutrition.TrtStatus,
HltNutrition.Status,
SUBSTRING (HltNutrition.Comment, 1, 1000)
FROM #Enroll
JOIN HltNutrition ON HltNutrition.IdApplicant = #Enroll.IdApplicant
WHERE HltNutrition.Overweight = 1
-- Chronic
INSERT INTO #ChronicCondition(IdApplicant, ExamDate, Condition, TreatmentNeeded, TreatmentReceived, Status, Comment)
SELECT #Enroll.IdApplicant,
HltChronic.ExamDate,
CASE ChronicCondition.Id
WHEN 3 THEN 'Other' + ISNULL(' - ' + hltChronic.ConditionOther, '')
ELSE ChronicCondition.Condition
END,
HltChronic.TrtNeed,
HltChronic.TrtStatus,
hltChronic.Status,
SUBSTRING (HltChronic.Comment, 1, 1000)
FROM #Enroll
JOIN hltChronic ON hltChronic.idApplicant = #Enroll.idApplicant
JOIN ChronicCondition ON ChronicCondition.Id = hltChronic.Condition
Thank you for the assistance, I walked through the concern with the senior developer and found that the SUBSTRING function was not the cause of the issue. The problem I was encountering was due to data entry that was used for testing the report. The code I added is actually correct and the problem has been resolved.
Thanks again for any assistance that was provided.
I am working on trying to fix a problem in the below code.
The first 3000 or so records for the ADJ_CARDHOLDER_ID column are coming up blank/empty when running the query.
All other columns seem to be populating correctly.
I believe this is being caused by the group by which is needed for the sum aggregate.
Is there another way I can go about this which prevents the ADJ_CARDHOLDER_ID column from coming up blank?
Select ADJ_CARDHOLDER_ID,
I_SERVICE_DT,
I_PRODUCT_I,
sum(Claim_Count) as 'Total Claim Count'
--into #temp_claims
from reporting.dbo.vcbt
where YEAR (I_SERVICE_DT) = Cast(Datepart(yyyy,GETDATE())as varchar(4))
and O_CLAIM_ITEM_RESP_STATUS_CD <> 'x'
and PLAN_ID not in('PH13-800W', 'PH13-OGBW', 'PH13-800WL', 'PH13-OGBWL', 'PH13-OGBWA', 'PH13-OGBWM', 'PH13-800WM', 'PH13-800WA')
Group by ADJ_CARDHOLDER_ID, I_PRODUCT_I, I_SERVICE_DT
order by ADJ_CARDHOLDER_ID, I_SERVICE_DT, I_PRODUCT_I
For this code I need the sum of the serv1 - serv8 where the student is receiving "Speech Language Therapy". I can not for the life of me figure out how to get those. If I say where serv1 equals 'SLT' then it will show up as null for serv 2. If I do it for serv2 it will show up as another service like DD for serv1.
My sum isn't working I would like to sum all of the services up by school but I'll take what anyone is willing to help me with. Any help is appreciated
SELECT SPE_Student_Profile_VW.school_code,
SPE_Student_Profile_VW.organization_name AS [[[School Name]]]]]]],
SPE_Student_Profile_VW.sis_number,
SPE_Student_Profile_VW.primary_disability_code,
SPE_Student_Profile_VW.secondary_disability_code,
SPE_Student_Profile_VW.tertiary_disability_code,
SPE_Student_Profile_VW.serv1,
SUM (SPE_Student_Profile_VW.mins1),
SPE_Student_Profile_VW.serv2,
SPE_Student_Profile_VW.mins2,
SPE_Student_Profile_VW.serv3,
SPE_Student_Profile_VW.mins3,
SPE_Student_Profile_VW.serv4,
SPE_Student_Profile_VW.mins4,
SPE_Student_Profile_VW.serv5,
SPE_Student_Profile_VW.mins5,
SPE_Student_Profile_VW.serv6,
SPE_Student_Profile_VW.mins6,
SPE_Student_Profile_VW.serv7,
SPE_Student_Profile_VW.mins7,
SPE_Student_Profile_VW.serv8,
SPE_Student_Profile_VW.mins8
FROM DBO.SPE_Student_Profile_VW SPE_Student_Profile_VW
WHERE ( SPE_Student_Profile_VW.serv1 = 'Speech Language Therapy'
AND SPE_Student_Profile_VW.school_code = '47')
GROUP BY SPE_Student_Profile_VW.school_code,
SPE_Student_Profile_VW.organization_name,
SPE_Student_Profile_VW.sis_number,
SPE_Student_Profile_VW.primary_disability_code,
SPE_Student_Profile_VW.secondary_disability_code,
SPE_Student_Profile_VW.tertiary_disability_code,
SPE_Student_Profile_VW.serv1,
SPE_Student_Profile_VW.mins1,
SPE_Student_Profile_VW.serv2,
SPE_Student_Profile_VW.mins2,
SPE_Student_Profile_VW.serv3,
SPE_Student_Profile_VW.mins3,
SPE_Student_Profile_VW.serv4,
SPE_Student_Profile_VW.mins4,
SPE_Student_Profile_VW.serv5,
SPE_Student_Profile_VW.mins5,
SPE_Student_Profile_VW.serv6,
SPE_Student_Profile_VW.mins6,
SPE_Student_Profile_VW.serv7,
SPE_Student_Profile_VW.mins7,
SPE_Student_Profile_VW.serv8,
SPE_Student_Profile_VW.mins8
the column you are trying to sum should not be in the group by clause, all the others should.
What I mean is the SELECT clause has this:
SUM (SPE_Student_Profile_VW.mins1),
and the GROUP BY has this part which should not be there:
SPE_Student_Profile_VW.mins1,
because it is the column he is trying to sum and you can't group by a column that you are aggregating with a function and that is why SUM isn't working
not sure of what is required but from what I get, you can probably get what you need if you add another
OR
in your
WHERE
Something like
WHERE (SPE_Student_Profile_VW.serv1 = 'Speech Language Therapy'
AND SPE_Student_Profile_VW.school_code = '47') OR
(SPE_Student_Profile_VW.serv2 = 'Speech Language Therapy'
AND SPE_Student_Profile_VW.school_code = '47') OR
SPE_Student_Profile_VW.serv3 = 'Speech Language Therapy'
AND SPE_Student_Profile_VW.school_code = '47'
and so on.
Thanks.
In Group by clause use all columns which you are used in select statement.Except the column you are calculating sum in select statement.
Thanks.
I'm trying to avoid using straight up SQL in my Rails app, but need to do a quite large version of this:
SELECT ds.product_id,
( SELECT SUM(units) FROM daily_sales WHERE (date BETWEEN '2015-01-01' AND '2015-01-08') AND service_type = 1 ) as wk1,
( SELECT SUM(units) FROM daily_sales WHERE (date BETWEEN '2015-01-09' AND '2015-01-16') AND service_type = 1 ) as wk2
FROM daily_sales as ds group by ds.product_id
I'm sure it can be done, but i'm struggling to write this as an active record statement. Can anyone help?
If you must do this in a single query, you'll need to write some SQL for the CASE statements. The following is what you need:
ranges = [ # ordered array of all your date-ranges
Date.new(2015, 1, 1)..Date.new(2015, 1, 8),
Date.new(2015, 1, 9)..Date.new(2015, 1, 16)
]
overall_range = (ranges.first.min)..(ranges.last.max)
grouping_sub_str = \
ranges.map.with_index do |range, i|
"WHEN (date BETWEEN '#{range.min}' AND '#{range.max}') THEN 'week#{i}'"
end.join(' ')
grouping_condition = "CASE #{grouping_sub_str} END"
grouping_columns = ['product_id', grouping_condition]
DailySale.where(date: overall_range).group(grouping_columns).sum(:units)
That will produce a hash with array keys and numeric values. A key will be of the form [product_id, 'week1'] and the value will be the corresponding sum of units for that week.
Simplify your SQL to the following and try converting it..
SELECT ds.product_id,
, SUM(CASE WHEN date BETWEEN '2015-01-01' AND '2015-01-08' AND service_type = 1
THEN units
END) WK1
, SUM(CASE WHEN date BETWEEN '2015-01-09' AND '2015-01-16' AND service_type = 1
THEN units
END) WK2
FROM daily_sales as ds
group by ds.product_id
Every rail developer sooner or later hits his/her head against the walls of Active Record query interface just to find the solution in Arel.
Arel gives you the flexibility that you need in creating your query without using loops, etc. I am not going to give runnable code rather some hints how to do it yourself:
We are going to use arel_tables to create our query. For a model called for example Product, getting the Arel table is as easy as products = Product.arel_table
Getting sum of a column is like daily_sales.project(daily_sales[:units].count).where(daily_sales[:date].gt(BEGIN_DATE).where(daily_sales[:date].lt(END_DATE). You can chain as many wheres as you want and it will be translated into SQL ANDs.
Since we need to have multiple sums in our end result you need to make use of Common Table Expressions(CTE). Take a look at docs and this answer for more info on this.
You can use those CTEs from step 3 in combination with group and you are done!
I want to generate a report in Crystal Reports and I am very new to it. I am unaware of how to manipulate the Crystal Report. I made a SQL query which gives me all the required output from the Oracle(10g) database. But I need to convert it to be used inside Crystal Reports.
This is the SQL query which gives me required output:
SELECT
ins.ins_name,ins.ins,crdi.ct, crdi.bn,
sum(DECODE(cardh.crd_st, 'PO', 1, 0)) POCount,
sum(DECODE(cardh.crd_st, 'CN', 1, 0)) CNCount
FROM
crdh, crdi, ins
WHERE
crdh.crd_st IN ('PO','CN')
and crdi.bn in (select unique bn from crdh)
and crdh.bn = crdi.bn
and crdi.ins = ins.ins
GROUP BY
ins.ins, crdi.bn, ins.ins_name, crdi.ct
ORDER BY
ins.ins, crdi.bn;
When I implemented the above query I got the following error:
a) When I put the above query in Database|Show SQL Query..., the following part of the query is removed:
sum(DECODE(cardh.crd_st, 'PO', 1, 0)) POCount,
sum(DECODE(cardh.crd_st, 'CN', 1, 0)) CNCount
GROUP BY ins.ins, crdi.bn, ins.ins_name,crdi.ct
b) When I added a group for ins.ins, Crystal reports adds a lots of spaces in the report.
c) How can I print the value of POCount and CNCount in the crystal report?
I am also adding the screenshot of the output for better understanding.
There can be multiple BN for one INS and for one BN there are multiple CNs and POs. Like INS 3 has two BN ('123456','789012') and there are 3 POs and 0 CN in BN '123456', but there is only one CN in BN '789012'. I hope this is helpful to replier.
Please help me to get a report same as the output of the above mentioned query. Thanks in advance.
I got the following result :
Dont implement sum in query instead implement it in crystal. so change the query like this.
SELECT ins.ins_name,ins.ins,crdi.ct, crdi.bn,
cardh.crd_st,cardh.crd_st
FROM crdh, crdi, ins
Add above query in crystal report command when you make a connection to the report.
Now for your report to display in the required format.
Create a formula #PO
if cardh.crd_st= 'PO'
then 1
else 0
Create formula for CN
if cardh.crd_st='CN'
then 1
else 0
Place above formula in detail
Create a group by ins.ins_name
Place all your columns in group footer and at the same time take sum for the formulas #po and CN
As you are using where condition in query to get that condition in CR. Implement your where clause in Select Expert ---> Record Selection Formula, If you are not comfortable then try implement the where clause in query itself.
Let me know how it goes.