Calculating the percentage of different types of customer feedback in each quarter - sql

The problem statement is: I have a table (order_t) which has customer feedback (one column) and quarter number (as another column).
Using a CTE, I need to calculate the percentage of number of customer feedback in each category as well as the total number of customer feedback in each quarter.
After this happens, I need the percentage of different types of customer feedback (like good, bad, ok, very good, very bad) but using CTE.
How can I solve this statement?
I try to solve customer feedback as
WITH total_feedback AS
(
SELECT *
COUNT(CUSTOMER_FEEDBACK), QUARTER NUMBER
FROM
table1
GROUP BY
2
)
But I'm unable to calculate the first half portion, i.e. percentage of different types of customer feedback in each quarter using CTE.
How can I do that?
Find the file of the data

What you could do, and I'll keep the example as close to the code you provided as possible, is the following - using 2 CTE's:
WITH total_feedback AS (
SELECT COUNT(CUSTOMER_FEEDBACK) AS total_feedback, QUARTER_NUMBER
FROM table1
GROUP BY 2
),
category_feedback AS (
SELECT COUNT(CUSTOMER_FEEDBACK) AS feedback_count, CUSTOMER_FEEDBACK, QUARTER_NUMBER
FROM table1
GROUP BY 2, 3
)
SELECT
category_feedback.CUSTOMER_FEEDBACK,
category_feedback.QUARTER_NUMBER,
(feedback_count / total_feedback.total_feedback) * 100 AS feedback_percentage
FROM category_feedback
INNER JOIN total_feedback
ON category_feedback.QUARTER_NUMBER = total_feedback.QUARTER_NUMBER

Related

I want NAV price as per (Today date minus 1) date

I have two tables. One is NAV where product daily new price is updated. Second is TDK table where item wise stock is available.
Now I want to get a summery report as per buyer name where all product wise total will come and from table one latest price will come.
I have tried below query...
SELECT dbo.TDK.buyer, dbo.NAV.Product_Name, sum(dbo.TDK.TD_UNITS) as Units, sum(dbo.TDK.TD_AMT) as 'Amount',dbo.NAV.NAValue
FROM dbo.TDK INNER JOIN
dbo.NAV
ON dbo.TDK.Products = dbo.NAV.Product_Name
group by dbo.TDK.buyer, dbo.NAV.Product_Name, dbo.NAV.NAValue
Imnportant: Common columns in both tables...
Table one NAV has column as Products
Table two TDK has column as Product_Name
If I have NAValue 4 records for one product then this query shows 4 lines with same total.
What I need??
I want this query to show only one line with latest NAValue price.
I want display one more line with Units*NAValue (latest) as "Latest Market Value".
Please guide.
What field contains the quote date? I am assuming you have a DATIME field, quoteDate, in dbo.NAV table and my other assumption is that you only store the Date part (i.e. mid-night, time = 00:00:00).
SELECT
t.buyer,
n.Product_Name,
sum(t.TD_UNITS) as Units,
sum(t.TD_AMT) as 'Amount',
n.NAValue
FROM dbo.TDK t
INNER JOIN dbo.NAV n
ON t.Products = n.Product_Name
AND n.quoteDate > getdate()-2
group by t.buyer, n.Product_Name, n.NAValue, n.QuoteDate
GetDate() will give you the current date and time. Subtracting 2 would get it before yesterday but after the day before yesterday.
Also, add n.quoteDate in your select and group by. Even though you don't need it, in case that one day you have a day of bad data with double record in NAV table, one with midnight time and another with 6 PM time.
Your code looks like SQL Server. I think you just want APPLY:
SELECT t.buyer, n.Product_Name, t.TD_UNITS as Units, t.TD_AMT as Amount, n.NAValue
FROM dbo.TDK t CROSS APPLY
(SELECT TOP (1) n.*
FROM dbo.NAV n
WHERE t.Products = n.Product_Name
ORDER BY ?? DESC -- however you define "latest"
) n;

MS Access Query to records with same data in different fields in the same row

The title is a bit confusing but I'll explain my problem here:
So i have a database table with millions of lines of spending data broken up into different time fields (period1 - period14). Now what i need to do is write a query that will return the records where the spending in one period is equal to the spending in a different period within the same record. So basically that means if i have a reecord where the spending in period1 is $100 and then the spending in period5 is also $100, it will add that record to a new table. I tried something like the code below but since I'm very new to access it is rather complex/inefficient and also doesn't do what i need it to.
INSERT INTO Contracts
SELECT *
FROM SPENDDETAIL
WHERE (SPENDDETAIL.Period1 = SPENDDETAIL.Period2 OR SPENDDETAIL.Period3 [...] OR SPENDDETAIL.Period14)
AND (SPENDDETAIL.Period1 <> 0 OR SPENDDETAIL.Period2 <> 0 [...] OR SPENDDETAIL.Period14 <> 0);
Any help much appreciated, thanks!
Oh also i know this code snippet would only return the records where the period1 spend equals the spend from any of the other periods it was just a beginning attempt at making the query do what i need it to.
Something along these lines might get you started:
SELECT Id, Value, COUNT(*) FROM
(SELECT Id AS Id, 1 AS Period, Period1 AS Value FROM SPENDDETAIL
UNION ALL
SELECT Id AS Id, 2 AS Period, Period2 AS Value FROM SPENDDETAIL
UNION ALL
SELECT Id AS Id 3 AS Period, Period3 AS Value FROM SPENDDETAIL
etc...) x
GROUP BY Id, Value
HAVING COUNT(*) > 1
Where Id is some unique identifier for each row of the data (assuming there is such a thing).
This will give you a list of Ids and matching values.

Subtracting 2 values from a query and sub-query using CROSS JOIN in SQL

I have a question that I'm having trouble answering.
Find out what is the difference in number of invoices and total of invoiced products between May and June.
One way of doing it is to use sub-queries: one for June and the other one for May, and to subtract the results of the two queries. Since each of the two subqueries will return one row you can (should) use CROSS JOIN, which does not require the "on" clause since you join "all" the rows from one table (i.e. subquery) to all the rows from the other one.
To find the month of a certain date, you can use MONTH function.
Here is the Erwin document
This is what I got so far. I have no idea how to use CROSS JOIN in this situation
select COUNT(*) TotalInv, SUM(ILP.ProductCount) TotalInvoicedProducts
from Invoice I, (select Count(distinct ProductId) ProductCount from InvoiceLine) AS ILP
where MONTH(inv_date) = 5
select COUNT(*) TotalInv, SUM(ILP.ProductCount) TotalInvoicedProducts
from Invoice I, (select Count(distinct ProductId) ProductCount from InvoiceLine) AS ILP
where MONTH(inv_date) = 6
If you guys can help that would be great.
Thanks
The problem statement suggests you use the following steps:
Construct a query, with a single result row giving the values for June.
Construct a query, with a single result row giving the values for May.
Compare the results of the two queries.
The issue is that, in SQL, it's not super easy to do that third step. One way to do it is by doing a cross join, which yields a row containing all the values from both subqueries; it's then easy to use SELECT (b - a) ... to get the differences you're looking for. This isn't the only way to do the third step, but what you have definitely doesn't work.
can't you do something with subqueries? I haven't tested this, but something like the below should give you 4 columns, invoices and products for may and june.
select (
select 'stuff' a, count(*) as june_invoices, sum(products) as products from invoices
where month = 'june'
) june , (
select 'stuff' a, count(*) as may_invoices, sum(products) as products from invoices
where month = 'may'
) may
where june.a = may.a

Obtain maximum row_number inside a cross apply

I am having trouble in calculating the maximum of a row_number in my sql case.
I will explain it directly on the SQL Fiddle example, as I think it will be faster to understand: SQL Fiddle
Columns 'OrderNumber', 'HourMinute' and 'Code' are just to represent my table and hence, should not be relevant for coding purposes
Column 'DateOnly' contains the dates
Column 'Phone' contains the phones of my customers
Column 'Purchases' contains the number of times customers have bought in the last 12 months. Note that this value is provided for each date, so the 12 months time period is relative to the date we're evaluating.
Finally, the column I am trying to produce is the 'PREVIOUSPURCHASES' which counts the number of times the figure provided in the column 'Purchases' has appeared in the previous 12 months (for each phone).
You can see on the SQL Fiddle example what I have achieved so far. The column 'PREVIOUSPURCHASES' is producing what I want, however, it is also producing lower values (e.g. only the maximum one is the one I need).
For instance, you can see that rows 4 and 5 are duplicated, one with a 'PREVIOUSPURCHASES' of 1 and the other with 2. I don't want to have the 4th row, in this case.
I have though about replacing the row_number by something like max(row_number) but I haven't been able to produce it (already looked at similar posts at stackoverflow...).
This should be implemented in SQL Server 2012.
Thanks in advance.
I'm not sure what kind of result set you want to see but is there anything wrong with what's returned with this?
SELECT c.OrderNumber, c.DateOnly, c.HourMinute, c.Code, c.Phone, c.Purchases, MAX(o.PreviousPurchases)
FROM cte c CROSS APPLY (
SELECT t2.DateOnly, t2.Phone,t2.ordernumber, t2.Purchases, ROW_NUMBER() OVER(PARTITION BY c.DateOnly ORDER BY t2.DateOnly) AS PreviousPurchases
FROM CurrentCustomers_v2 t2
WHERE c.Phone = t2.Phone AND t2.purchases<=c.purchases AND DATEDIFF(DAY, t2.DateOnly, c.DateOnly) BETWEEN 0 AND 365
) o
WHERE c.OrderNumber = o.OrderNumber
GROUP BY c.OrderNumber, c.DateOnly, c.HourMinute, c.Code, c.Phone, c.Purchases
ORDER BY c.DateOnly

sql to calculate daily totals minues the previous day's totals

I have a table that has a date, item, and quantity.
I need a sql query to return the totals per day, but the total is the quantity minus the previous day totals. The quantity accumulates as the month goes on. So the 1st could have 5 the 2nd have 12 and the 3rd has 20.
So the 1st adds 5
2nd adds 7 to make 12
3rd adds 8 to make 20.
I've done something like this in the past, but can not find it or remember. I know i'll need a correlated sub-query.
TIA
--
Edit 1
I'm using Microsoft Access.
Date is a datetime field,
item is a text, and
quantity is number
--
Edit 2
Ok this is what i have
SELECT oos.report_date, oos.tech, oos.total_cpe, oos_2.total_cpe
FROM oos INNER JOIN (
SELECT oos_2.tech, Sum(oos_2.total_cpe) AS total_cpe
FROM oos_2
WHERE (((oos_2.report_date)<#10/10/2010#))
GROUP BY oos_2.tech
) oos_2 ON oos.tech = oos_2.tech;
How do i get the oos.report_date into where i says #10/10/2010#. I thought I could just stick it in there like mysql, but no luck. I'm gonna continue researching.
Sum them by adding one to the date and making the value negative, thus taking yesterday's total from today's:
SELECT report_date, tech, Sum(total_cpe) AS total_cpe
FROM (
SELECT oos.report_date, oos.tech, oos.total_cpe
FROM oos
UNION ALL
SELECT oos.report_date+1, oos.tech, 0-oos.total_cpe
FROM oos
)
WHERE (report_date < #10/10/2010#)
GROUP BY report_date, tech
ORDER BY report_date, tech
Ok, I figured it out.
SELECT o.report_date, o.tech, o.total_cpe,
o.total_cpe - (
SELECT IIf(Sum(oos.total_cpe) is null, 0,Sum(oos.total_cpe)) AS total_cpe
FROM oos
WHERE (((oos.tech)=o.tech) AND ((oos.report_date)<o.report_date))
) AS total
FROM oos o;