I need help with this Question.
. Write a script that has one line out output that says either “March sales are greater than April sales” or “April sales are greater than March sales”, depending on which is true. You will need to sum up the sales (consider it the litem price minus the discount for those sales in that month) and then use an if/else. So i figured to do it like this
Use MyGuitarShop;
DECLARE #AprilSales MONEY;
DECLARE #MarchSales MONEY;
SET #AprilSales = (SELECT MONTH(Orders.OrderDate) as SalesMonth,
SUM(OrderItems.ItemPrice-OrderItems.DiscountAmount) AS TotalSales
FROM Orders,OrderItems
WHERE MONTH(Orders.OrderDate) = 4
GROUP BY MONTH(Orders.OrderDate));
SET #MarchSales = (SELECT MONTH(Orders.OrderDate) as SalesMonth,
SUM(OrderItems.ItemPrice-OrderItems.DiscountAmount) AS TotalSales
FROM Orders,OrderItems
WHERE MONTH(Orders.OrderDate) = 3
GROUP BY MONTH(Orders.OrderDate));
SELECT #AprilSales, #MarchSales
FROM Orders, OrderItems
IF #AprilSales > #MarchSales
BEGIN
PRINT 'April sales are greater than March sales.'
END;
ELSE --#MarchSales > #AprilSales
PRINT 'March sales are greater than April sales.';
But i Get this error
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Related
I'm running a points system for companies where every employee that works for that company is worth some points.
Every month the points for the companies are calculated.
This works so far, however In the 9th month of this year I would like to give double points for each acquired employee in that month.
I don't know how to do that.
I have this query now:
SELECT company, (employees *2) as "Points"
FROM data
WHERE month = '10'
GROUP BY company
But as you can see I give 2 points for each employee that works for that company in that month.
But for month 9 I want to give double points and add them to current points in current month(10)
I have this SQLfiddle as example: http://sqlfiddle.com/#!9/2cb812/7
Expected result:
company Points
__________________
company 1 26 + (extra points from month 9)
company 2 32 + (extra points from month 9)
company 3 44 + (extra points from month 9)
So it's all about the August/September delta 2018. If you run the query for any month before September 2018 (June 2018, May 2012, whatever), you just want to get the current month's points. If you run the query for any month after August 2018 (December 2018, March 2022, ...) you want the 2018 bonus points added.
Group by company and use conditional aggregation (an aggregation function on a condition) in order to calculate this.
We must look at the requested month (e.g. 10/2018) and August 2018 and September 2018.
SET #yearmonth = '201810';
SELECT
company,
SUM(
CASE WHEN yearmonth = #yearmonth THEN employees * 2 ELSE 0 END +
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201809' THEN employees * 4 ELSE 0 END -
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201808' THEN employees * 4 ELSE 0 END
) AS points
FROM data
WHERE yearmonth in ('201808', '201809', #yearmonth)
GROUP BY company
ORDER BY company;
The WHERE clause is superfluous, as the months are checked inside the SUM function, but it may speed up the query.
Rextester demo: https://rextester.com/ELOWTL44361
As shown in the image:
Here I need to perform cumulative based on a condition:
I have
Column 1: Sales Date
Column 2: Warranty End Date
Column 3: Qty of Sales
Column 4: Cumulative Sales Qty
Now for Column 5: Under warranty which gives a wrong value here
when the warranty dates complete 365days(expires) I need to subtract the sales happened for that expiry date in the under warranty count column similar the count starts reducing for the following days when the warranty expires.
For eg in the figure:
JAN 1,2014 have 246 as cumulative sales when it reaches JAN 1 2015, I need to subtract that '246' from '96502' which is the cumulative sales till JAN 1 2015.So should be 96256
How can we achieve the logic in SQL for 'Under warranty count' column
My Query:
SELECT a."sales_year",
a."sales_billing_date",
a."warranty_end_date",
a."sum_val",
a."order_qty",
CASE
WHEN Sum(Days_between (a."warranty_end_date", a."sales_billing_date"))
< 365
THEN a."sum_val"
ELSE ( ( a."sum_val" ) - ( b."sum_val" ) )
END AS "Under_Warranty"
FROM "_SYS_BIC"."pal/cv_pal_tbf_sales" a,
"_SYS_BIC"."pal/cv_pal_tbf_sales" b
GROUP BY a."sales_year",
a."sales_billing_date",
a."warranty_end_date",
a."order_qty",
b."sum_val",
a."sum_val";
Assuming that SALES_BILLING_DATE AND WARRANTY_END_DATE are 1 year apart throughout the table, you can do a self join by matching above two columns from each instance of the table and doing the subtraction on the UNDER_WARRANTY amount.
SELECT A.SALES_YEAR, A.SALES_BILLING_DATE, A.WARRANTY_END_DATE, A.SUM_VAL, A.ORDER_QTY,
(A.UNDER_WARRANTY - B.UNDER_WARRANTY) AS UNDER_WARRANTY_NEW
FROM
YOUR_TABLE A
INNER JOIN
YOUR_TABLE B
ON A.SALES_BILLING_DATE = B.WARRANTY_END_DATE;
To retain 2014 entries in the output, try the below query. Changed to left join with the same ON condition and if there is no match then the UNDER_WARRANTY amount remains unchanged.
SELECT A.SALES_YEAR, A.SALES_BILLING_DATE, A.WARRANTY_END_DATE, A.SUM_VAL, A.ORDER_QTY,
CASE WHEN B.WARRANTY_END_DATE IS NOT NULL THEN (A.UNDER_WARRANTY - B.UNDER_WARRANTY) ELSE A.UNDER_WARRANTY END AS UNDER_WARRANTY_NEW
FROM
YOUR_TABLE A
LEFT JOIN
YOUR_TABLE B
ON A.SALES_BILLING_DATE = B.WARRANTY_END_DATE;
DECLARE
v_in auto_service.vin%TYPE;
v_first auto_service.service_date%TYPE;
v_last auto_service.service_date%TYPE;
v_max auto_service.price%TYPE;
v_total auto_service.price%TYPE;
v_n NUMBER;
CURSOR c_auto
IS
SELECT vin,
COUNT(*) AS no,
MIN(SERVICE_DATE) AS FIRSTprice,
MAX(SERVICE_DATE) AS lastprice,
max(price) as maxprice,
sum(price) as totalprice
FROM auto_service
GROUP BY vin;
BEGIN
OPEN c_auto;
FETCH c_auto INTO v_in,v_n,v_first,v_last,v_total,v_max;
IF c_auto%notfound THEN
dbms_output.put_line('No output');
ELSE
dbms_output.put_line('vin No firstprice lastprice maximumprice totalprice');
LOOP
dbms_output.put_line(rpad(v_in,10) || rpad(v_n,10) || rpad(v_first,10) || rpad(v_last,12) || rpad(v_max,15) || rpad(v_total,5));
FETCH c_auto INTO v_in,v_n,v_first,v_last,v_max,v_total;
EXIT
WHEN c_auto%notfound;
END LOOP;
END IF;
CLOSE c_auto;
END;
To find
the number of services, the first service date and the price for the first service,the last service date and the price for the last service, the maximum price and the service date for the maximum price, and the prices for all services
I got all the other things except price for the first service date and last date of all VIN.
select q.*,
(
select sum(price)
from auto_service x
where x.vin = q.vin
and x.service_date = q.FIRST_DATE
) as FIRST_PRICE,
(
select sum(price)
from auto_service x
where x.vin = q.vin
and x.service_date = q.LAST_DATE
) AS LAST_PRICE
from
(
SELECT vin,
COUNT(*) AS no,
MIN(SERVICE_DATE) AS FIRST_DATE,
MAX(SERVICE_DATE) AS LAST_DATE,
max(price) as maxprice,
sum(price) as totalprice
FROM auto_service
GROUP BY vin
) q
Notice that I renamed the columns you named as FIRSTprice and lastprice to first_date and last_date, since this name is more related to what the column does actually contain.
in second place: i used "select sum(price)" in the subqueries only to handle the possibility that the same car has been serviced twice on the same day. if this should happen, without the sum(), the subquery would extract more than a value and would give you a runtime error. This much less likely to happen if if the date field contains also the time part, not only the date, but it could still happen if your DB contains bad data.
it is up to you if you want to keep that sum() call or if you prefer the db to reveal errors if there are duplicate rows you don't expect
I am using the following query to create a report. My problem comes from the fact that I need to use COUNT(market) for the year to date (total) of each 'market' then I also need a COUNT of 'market' for only the user imputed month ($mon). I cannot find any reference to using a WHERE on only a single selected field, everything else works as intended giving me the market with the percentages and year to date totals.
I need to make the line "COUNT(market) AS Saves" only count markets who's month field equals $mon and everything else to stay as is.
SELECT market,
COUNT(market) AS Saves,
COUNT(market) / (SELECT COUNT(*) FROM savedata2013) * 100 AS Percent,
COUNT(market) AS YTD
FROM savedata2013, ticket_info
GROUP BY market
ORDER BY COUNT(market) DESC';
Example Data:
market - Saves(June) - Percent - YTD
Los Angeles - 530 - 16.5154 - 564
San Jose - 390 - 12.1523 - 415
Irvine - 371 - 11.5373 - 394
You can use an if statement inside a sum, something like...
select sum(if(field='$mon',1,0)) as something....
I've created a SQLFiddle based on what I think your database might look like, and then run the following query.
So, the DB I used is defined as a market and an enteredDate. You probably have a lot more information in your ticket_info, but it shouldn't be relevant.
create table ticket_info (market varchar(20),
enteredDate DateTime);
And the query is:
SELECT market,
sum(if(monthname(enteredDate)='June',1,0)) AS `Saves(June)`,
sum(if(monthname(enteredDate)='June',1,0))/ (SELECT count(*) FROM ticket_info WHERE year(enteredDate) = 2013) AS Percent,
sum(if(year(enteredDate)=2013,1,0)) AS YTD
FROM ticket_info
GROUP BY market
ORDER BY `Saves(June)` DESC;
The percent will be null if there are no tickets entered for the year, but this should be an edge condition.
Link to SQLFiddle
You can probably resolve the problem like this, using CASE statement:
SELECT market,
COUNT
(
CASE market
WHEN month = $mon
THEN market
ELSE NULL
END
) AS Saves,
COUNT(market) / (SELECT COUNT(*) FROM savedata2013) * 100 AS Percent,
COUNT(market) AS YTD
FROM savedata2013, ticket_info
GROUP BY market
ORDER BY COUNT(market) DESC';
I have the following table SEASONS with time periods defining a booking prices for each period day;
ID, STARTDATE, ENDDATE, PRICE
6, 2012-06-01, 2012-06-30, 20
7, 2012-07-01, 2012-07-31, 35
8, 2012-08-01, 2012-08-31, 30
9, 2012-09-01, 2012-09-30, 25
This table defines pricing periods (start and end dates of pricing period with price of booking for each day in that particular pricing period). The question is how to create a query which will return the total price of booking for all days in some given booking period? For example, how to calculate (SELECT?) the total (SUM) booking price for period from 2012-06-10 to 2012-08-20 ?
(Of course one can easily calculate it manually = 21(days in Jun)x20 + 31(days in Jul)x35 + 20(days in Aug)x30 = 2105) How SELECT statement returning that total booking price should look like?
Use DATEDIFF function:
SELECT SUM(DATEDIFF(ENDDATE,STARTDATE) * PRICE) AS TOTAL_PRICE
FROM SEASONS
WHERE STARTDATE <= '2012-06-10' AND ENDDATE >= '2012-08-20'
Also, we can add a check for booking start/end since they fall somewhere in the middle and you don't need to include all the period...
So:
SET #START='2012-06-10';
SET #END='2012-08-20';
SELECT SUM(
DATEDIFF(
IF(YEAR(ENDDATE)=YEAR(#END) AND MONTH(ENDDATE)=MONTH(#END), #END, ENDDATE),
IF(YEAR(STARTDATE)=YEAR(#START) AND MONTH(STARTDATE)=MONTH(#START), #START, STARTDATE)
)
) AS TOTAL_SUM
FROM SEASONS
WHERE STARTDATE <= #END AND ENDDATE >= #START
Just for other readers, as a result from previous answer the final query is:
SET #START='2012-06-10';
SET #END='2012-08-20';
SELECT SUM(
(DATEDIFF(
IF(enddate>=#END,#END,enddate),
IF(startdate<=#START,#START,startdate)
)+1)*price ) AS TOTAL_SUM
FROM seasons WHERE startdate<=#END AND enddate>=#START
1 should be added to date difference in order both starting and ending date to be included in pricing range and, of course, it should be multiplied with price.
#poncha thank you very much, I already created a procedure which loops through all dates in booking period fetching multiple prices and summing them as a solution but I knew there should be a simpler and more efficient solution