SQL construct for particular output. Can one query give me this - sql

Afternoon. I am using SQLServer 2008r2, I have this SQL:
SELECT dateName(mm,wfi.created) AS theMonth
, datePart(yyyy,wfi.created) AS theYear
, count(wf.WebFormsIndexID) AS numOfForms
FROM WebFormsInstances as wfi
LEFT OUTER JOIN WebFormsIndex as wf on wfi.webFormsIndexID = wf.WebFormsIndexID
where year(wfi.created) = year(getDate())
group by datePart(yyyy,wfi.created), datePart(mm,wfi.created), dateName(mm,wfi.created)
order by theYear,datePart(mm,wfi.created)
which gives me total number of all forms submitted by the month:
January 2015 799
February 2015 1282
March 2015 1450
...
There are around 50 different forms. The form name is wf.formName How can I restructure this so I can get total numbers for each individual form for each month. Something like:
myFormName1 January 2015 220
myFormName2 January 2015 179
I can figure out how to do this in two queries but would ideally like to do it in one? The objective is a report, form names down the page, months across the page with total number of forms in play for each month.

SELECT
wf.formName
dateName(mm,wfi.created) AS theMonth,
datePart(yyyy,wfi.created) AS theYear,
count(wf.WebFormsIndexID) AS numOfForms
FROM WebFormsInstances as wfi
LEFT OUTER JOIN WebFormsIndex as wf on wfi.webFormsIndexID = wf.WebFormsIndexID
where year(wfi.created) = year(getDate())
group by wf.formName, datePart(yyyy,wfi.created), datePart(mm,wfi.created)
order by wf.formName, datePart(yyyy,wfi.created), datePart(mm,wfi.created)

Related

Issue with Joining Tables in SQL

SQL newbie here, using Zoho Analytics to do some reporting, specifically with prorated forecasting of lead generation. I successfully created some tables that contain lead goals, and joined them onto matching leads based off of the current month. The problem I am having is I would like to be able to access my prorated goals even if I filter so that there are no leads that have been created yet. This will make more sense in the picture I attached, with an RPM gauge that cannot pull the target or maximum because no leads match the filter criteria. How do I join the tables (with maybe an ifnull statement?) so that even if no lead ID's match, I can still output my goals? Thanks so much in advance.
RPM Gauge With prorated target and monthly goal
RPM gauge settings, distinct count of Lead Id's
Base table with goal used in Query table
Query table, forgive me I am new
Sorry for what I am sure is a fundamental misunderstanding of how this works, I have had to teach myself everything I know about SQL, and I am apparently not a terribly great teacher.
Thanks!
I have tried using a right join, and an ifnull statement but it did not improve matters.
Edit- Sorry for the first post issues- here is the code and tables not in image form
Lead Table Example-
ID
Lead Created Time
Lead Type
12345
11/21/2022
Charge
12346
10/17/2020
Store
12347
08/22/2022
Enhance
I purposefully left out an entry that would match my filter criteria, as for the first few days of the month this often comes up. Ideally I would still like to get the prorated and total goals returned.
The table the query is pulling from to determine the prorated numbers-
Start Date
End Date
Prorating decimal
Charge
Enhance
Store
Service
Charge[PR]
Enhance[PR]
Store[PR]
Service[PR]
Total Leads
Total Leads[PR]
Jan 01 2022
Jan 31 2022
.1
15
12
15
20
1.5
1.2
1.5
2.0
62
6.2
Feb 01 2022
Feb 28 2022
.1
15
12
15
20
1.5
1.2
1.5
2.0
62
6.2
Mar 01 2022
Mar 31 2022
.1
15
12
15
20
1.5
1.2
1.5
2.0
62
6.2
^For simplicity's sake I did not change the goals month to month, but they would in reality.
Idea for a successful data table, [PR] meaning prorated-
Sum of Lead Id's
Storage Goal
Storage Goal[PR]
Charge Goal
Charge Goal [PR]
14
10
1
15
2
1
10
1
15
2
0
10
1
15
2
The SQL Query that I have that returns the blank gauge when no leads match my criteria(Created this month, and lead type=Store)
SELECT
"Leads"."Id",
"SSS - 2022 Leads Forecast [Job Type]".*
FROM "Leads"
RIGHT JOIN "SSS - 2022 Leads Forecast [Job Type]" ON ((GETDATE() >= "Start Date")
AND (GETDATE() <= "End Date"))
Thanks so much to everyone who helped me reformat, first time poster so still learning the ropes. Let me know if I can provide more context or better info.
Figured this out! I used subqueries, filtering manually in the query instead of through the analytics widget, and did a distinct count to return zero instead of null, as well as coalescing for the dollar amount to return zero. (Not applicable in the below example) Below I have an example of some of the queries I used, as well as the resulting data table that is giving me the result that I want.
SELECT
( SELECT count(*)
FROM ( SELECT DISTINCT "Leads"."Id"
FROM "Leads"
WHERE "Lead Type" = 'Charge'
AND month_name("Created Time") = month_name(GETDATE())
AND year("Created Time") = year(GETDATE())
) AS 'test1'
) AS 'Charge Leads',
( SELECT count(*)
FROM ( SELECT DISTINCT "Leads"."Id"
FROM "Leads"
WHERE "Lead Type" = 'Store'
AND month_name("Created Time") = month_name(GETDATE())
AND year("Created Time") = year(GETDATE())
) AS 'test2'
) AS 'Store Leads',
( SELECT count(*)
FROM ( SELECT DISTINCT "Leads"."Id"
FROM "Leads"
WHERE "Lead Type" = 'Enhance'
AND month_name("Created Time") = month_name(GETDATE())
AND year("Created Time") = year(GETDATE())
) AS 'test3'
) AS 'Enhance Leads',
( SELECT count(*)
FROM ( SELECT DISTINCT "Leads"."Id"
FROM "Leads"
WHERE "Lead Type" = 'Service'
AND month_name("Created Time") = month_name(GETDATE())
AND year("Created Time") = year(GETDATE())
) AS 'test4'
) AS 'Service Leads',
"SSS - 2022 Leads Forecast [Job Type]".*
FROM "SSS - 2022 Leads Forecast [Job Type]"
WHERE ((GETDATE() >= "Start Date")
AND (GETDATE() <= "End Date"))
I am 100% sure that there is a more efficient way to do this, but it works and that was the most pressing thing.
Here is the resulting data table, which is exactly what I needed-
Charge Leads
Store Leads
Enhance Leads
Service Leads
Start Date
End Date
[PR] Charge
[PR] Enhance
[PR] Store
[PR] Service
[PR] Total Leads
[Total] Charge
[Total] Enhance
[Total] Store
[Total] Service
[Total] Total Leads
Prorating Decimal
7
0
5
35
01 Dec 2022
31 Dec 2022
64
34
17
56
171
152
81
40
134
407
.419
The [PR] are the prorated goals, so where we should be at this point in the month, and [Total] is the total goal for the month.

Can I query a aggregated query and a specific row's query when using subqueries?

I am new to SQL and I wanted to return the results of a specific value and the average of similar values. I have gotten the average part working but I'm not sure how to do the specific value part.
For more context, I have a list of carbon emissions by companies. I wanted the average of a industry based on a company's industry(working perfectly below), but I am not sure how to add the specific companies info.
Here's my query:
SELECT
year, AVG(carbon) AS AVG_carbon,
-- carbon as CompanyCarbon, <--my not working attempt
FROM
"company"."carbon" c
WHERE
LOWER(c.ticker) IN (SELECT LOWER(g4.ticker)
FROM "company"."General" g4
WHERE industry = (SELECT industry
FROM "company"."General" g3
WHERE LOWER(g3.ticker) = 'ibm.us'))
GROUP BY
c.year
ORDER BY
year ASC;
The current result is:
year avg_carbon
--------------------------------
1998 7909.0000000000000000
1999 19465.500000000000
2000 19478.000000000000
2001 182679.274509803922
2002 179821.156862745098
My desired output is:
year avg_carbon. Carbon
---------------------------------------
1998 7909.0000000000000000 343
1999 19465.500000000000 544
2000 19478.000000000000 653
2001 182679.274509803922 654
2002 179821.156862745098 644
(adding the carbon column based on "IBM" carbon
Here's my Carbon table:
ticker year carbon
-----------------------
hurn.us 2016 6282
hurn.us 2015 6549
hurn.us 2014 5897
hurn.us 2013 5300
hurn.us 2012 5340
ibm.us 2019 1496520
ibm.us 2018 1438365
Based on my limited knowledge, I think my where the statement is causing the problem. Right now I took at a company, get a list of tickers/identifiers of the same industry then create an average for each year.
I tried to just call the carbon column but I think because it's processing the list of tickers, it's not outputting the result I want.
What can I do? Also if I'm making any other mistakes you see above please let me know.
Sample data nd output do not match. So I can't say for sure but this might be the answer you are looking for.
select year, AVG(carbon) AS AVG_carbon,
max(case when lower(ticker) = 'ibm.us' then carbon else 0 end) as CompanyCarbon
from "company"."carbon" c
GROUP BY c.year
order by year ASC;
This will select max(carbon) for any year as CompanyCarbon if lower(ticker) = 'ibm.us'. Average will be calculated as you did.
To select only rows having positive value in CompanyCarbon column:
select year, AVG_carbon, CompanyCarbon
from
(
select year, AVG(carbon) AS AVG_carbon,
max(case when lower(ticker) = 'ibm.us' then carbon else 0 end) as CompanyCarbon
from "company"."carbon" c
GROUP BY c.year
order by year ASC;
)t where carbon > 0
Similar to the answer that Kazi provided you can use the FILTER syntax on an aggregate which makes it a bit more readable than the case/when IMO.
SELECT
year,
AVG(carbon) as avg_carbon,
MAX(carbon) FILTER (WHERE ticker = 'ibm.us') as company_carbon
FROM company_carbon
GROUP BY year
ORDER by year;

Showing Purchase Counts for ALL months - Including 0 purchase months

I want to join a complete calendar table, with per user purchasing data to show, for each user, any purchase counts for every month from 2014 to 2017. Some users may not have a purchase until 2016, but I would still want to have the results show 0's for each month up to the first purchase date, as well as any 0's in between months as well.
I can't get the 0 months to be included! I think it's because I'm doing this across many unique users, but it felt like the below code should work.
select
c.fscl_yr_num
,c.fscl_month_num
,t.user_id
,sum(nvl(t.trans_counter, 0))
from
appca.d_cal c
left join
transaction_data t
on c.cal_dt = t.trans_dt
and t.trans_type = 'Purchase'
and c.fscl_yr_num in (2014, 2015, 2016, 2017)
group by
c.fscl_yr_num
,c.fscl_month_num
,t.user_id
order by
t.user_id
,c.fscl_yr_num
,c.fscl_month_num
;
Try
SUM(NVL(t.trans_counter,0))

How do I average the last 6 months of sales within SQL based on period AND year?

How do I average the last 6 months of sales within SQL?
Here are my tables and fields:
IM_ItemWhseHistoryByPeriod.FISCALCALPERIOD,
IM_ItemWhseHistoryByPeriod.FISCALCALYEAR,
And I need to average these fields
IM_ItemWhseHistoryByPeriod.DOLLARSSOLD,
IM_ItemWhseHistoryByPeriod.QUANTITYSOLD,
The hard part I'm having is understanding how to average the last whole 6 months, ie. fsicalcalperiod 2-6(inside fiscalcalyear 2017).
I'm hoping for some help on what the SQL command text should look like since I'm very new to manipulating SQL outside of the UI.
Sample Data
My Existing SQL String:
SELECT IM_ItemWhseHistoryByPeriod.ITEMCODE,
IM_ItemWhseHistoryByPeriod.DOLLARSSOLD,
IM_ItemWhseHistoryByPeriod.QUANTITYSOLD,
IM_ItemWhseHistoryByPeriod.FISCALCALPERIOD,
IM_ItemWhseHistoryByPeriod.FISCALCALYEAR
FROM MAS_AME.dbo.IM_ItemWhseHistoryByPeriod
IM_ItemWhseHistoryByPeriod
ScaisEdge Attempt #1
if fiscalyear and fiscalperiod are number you could use
select avg(IM_ItemWhseHistoryByPeriod.DOLLARSSOLD) ,
avg(IM_ItemWhseHistoryByPeriod.QUANTITYSOLD)
from my_table
where IM_ItemWhseHistoryByPeriod.FISCALCALYEAR = 2017
and IM_ItemWhseHistoryByPeriod.FISCALCALPERIOD between 2 and 6
or for each item code
select itemcode, avg(IM_ItemWhseHistoryByPeriod.DOLLARSSOLD) ,
avg(IM_ItemWhseHistoryByPeriod.QUANTITYSOLD)
from my_table
where IM_ItemWhseHistoryByPeriod.FISCALCALYEAR = 2017
and IM_ItemWhseHistoryByPeriod.FISCALCALPERIOD between 2 and 6
group by itemcode
Try the following solution and see if it works for you:
select avg(DOLLARSSOLD) as AvgDollarSod,
avg(QUANTITYSOLD) as AvgQtySold
from IM_ItemWhseHistoryByPeriod
where FISCALCALYEAR = '2017
and FISCALCALPERIOD between 2 and 6

sql query grouping with condition

there is a table with employee numbers(column) and monthy payments(column)with paramcode(column) as basic, vda etc.. and amounts(column) corresponding to each paramcode.
empno. month paramcode amount
1 jan basic 788
1 feb vda 232
1 march pf 12
now this is actual question
Write a query to display sum of BASIC + VDA + HRA for an employee Payment where the employee has been paid PF in the payment
(do not use sub queries , Joins and Set operators)
My answer is
SELECT EmployeeNumber,paramcode, SUM(ActualAmount) AS S FROM pay
WHERE ParamCode IN ('BASIC','VDA','HRA','pf')
GROUP BY GROUPING SETS((EmployeeNumber,ParamCode))
ORDER BY EmployeeNumber
but i want to eliminate the employee numbers with param code as 'pf'
If I understood you right use SQL except tag like this except ParamCode in ('pf')
You are actually adding 'PF' in ParamCode, this is the correct query:
SELECT EmployeeNumber,paramcode, SUM(ActualAmount) AS S FROM pay
WHERE ParamCode IN ('BASIC','VDA','HRA')
GROUP BY GROUPING SETS((EmployeeNumber,ParamCode))
ORDER BY EmployeeNumber