I Want to write a subquery to Sum a column - sql

This query returns the results below.
Select BookTitle,TotalNumberInStock
From CurrentStock
Where (Year<2000 OR Year >2010);
Table 1
BookTitle TotalNumberInStock
The Tower 2
Orange Goblins 1
The future of Metal 3
Chronicles of the Banjo 2
Opera 4
Advanced SQL 5
The GAA 4
I want to write a subquery that sums the TotalNumber In Stock so I used this statement:
Select Sum(TotalNumberInstock)
From
(
Select BookTitle,TotalNumberInStock
From CurrentStock
Where (Year<2000 OR Year >2010)
);
I get an error saying:
Incorrect syntax near ';'.
What is wrong with this code?

you need to give an alias name to your sub query (aka derived table)
select Sum(TotalNumberInstock)
From (Select BookTitle,TotalNumberInStock From CurrentStock
Where (Year<2000 OR Year >2010)) x ;
this correction makes your query work, but you don't need such complexity to have your desired result. you can simply get what you want by this query
select sum(totalNumberInStock)
from CurrentStock
where year < 2000 or year > 2010

I'm not sure why you need a sub query.
select sum(totalNumberInStock)
from CurrentStock
where year < 2000 or year > 2010

This should do the trick:
Select BookTitle,SUM(TotalNumberInStock)
From CurrentStock
Where (Year < 2000 and YEAR > 2010)
GROUP BY BookTitle

Related

SQL/ Return MIN values of multiple rows

I'm trying to get the minimum value of open, across multiple rows of year. This is from app.mode.com and the site only says SQL, not sure which version
SELECT year, open
FROM tutorial.aapl_historical_stock_price
WHERE open =
(
select MIN(open)
FROM tutorial.aapl_historical_stock_price
)
When I use the code above, the result is
Table result vs actual output
Year
Open
2000
0
2000
0
2000
0
What I'm trying to get is
Year
Open
2002
0
2001
0
2000
0
Can someone help point me what I'm doing wrong?
select year and get the min by grouping each year as following:
select
year
, min(open) as <desired_alias>
from your_table
group by 1
order by 1 desc;

Is there a way in Teradata convert rows into columns without changing query for new values

I am looking to convert rows to column for a requirement like sum of sales per year. A table like this can be transposed as follows:
Sales Year
100 2,005
200 2,005
300 2,006
100 2,007
200 2,006
300 2,007
'2005' '2006' '2007'
300 500 400
The query I used is
SELECT * FROM test1 PIVOT (SUM("s") FOR "y" IN ( '2005', '2006', '2007' ) ) AS Temp_pivot
However if a new year appears, say 2008 I need to modify the query.
Can I get the output for additional years without modifying the query. Can we do it without procedure or dynamic SQL?
Best Regards
Vaidy
It looks like you can use a sub-query in the IN clause, so what about something like:
SELECT *
FROM test1 PIVOT (
SUM("s") FOR "y" IN (
SELECT year_of_calendar
FROM sys_calendar.calendar
WHERE year_of_calendar >= 2005
-- '2005', '2006', '2007'
)
) AS Temp_pivot
I haven't tested it out, but give it a try and let me know.
TD Manual - Pivot
Thanks for the inputs.
Ravioli, I tried the subquery option but it says "select failed. 3669 more than one value was returned by a subquery".
Any other thoughts?
Best Regards
Vaidy

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 EXTRACT(YEAR FROM MYDATE) not a GROUP BY expression

I have table MYTABLE with columns mydate and quantity of VARCHAR2 type.
|mydate| |quantity|
10/15/2010 15
01/20/2010 20
05/16/2005 30
04/29/2005 50
03/30/2008 5
I want to get:
|year| |quantity|
2010 35
2005 80
2008 5
I try:
SELECT
to_char(mydate,'yyyy') YEAR,
SUM(to_number(quantity))
FROM MYTABLE
GROUP BY
to_char(mydate,'yyyy');
But I get an error
ORA-00979: not a GROUP BY expression
What did I do wrong?
You must put all columns of the SELECT in the GROUP BY or use functions on them which compress the results to a single value (like MIN, MAX or SUM).
A simple example to understand why this happens: Imagine you have a database like this:
FOO BAR
0 A
0 B
and you run SELECT * FROM table GROUP BY foo. This means the database must return a single row as result with the first column 0 to fulfill the GROUP BY but there are now two values of bar to chose from. Which result would you expect - A or B? Or should the database return more than one row, violating the contract of GROUP BY?
Try this
select extract(year from mydate),sum(to_number(quant)) from mytable
group by extract(year from mydate);
SQLFiddle Example

SQL: Can GROUP BY contain an expression as a field?

I want to group a set of dated records by year, when the date is to the day. Something like:
SELECT venue, YEAR(date) AS yr, SUM(guests) AS yr_guests
FROM Events
...
GROUP BY venue, YEAR(date);
The above is giving me results instead of an error, but the results are not grouping by year and venue; they do not appear to be grouping at all.
My brute force solution would be a nested subquery: add the YEAR() AS yr as an extra column in the subquery, then do the grouping on yr in the outer query. I'm just trying to learn to do as much as possible without nesting, because nesting usually seems horribly inefficient.
I would tell you the exact SQL implementation I'm using, but I've had trouble discovering it. (I'm working through the problems on http://www.sql-ex.ru/ and if you can tell what they're using, I'd love to know.) Edited to add: Per test in comments, it is probably not SQL Server.
Edited to add the results I am getting (note the first two should be summed):
venue | yr | yr_guests
1 2012 15
1 2012 35
2 2012 12
1 2008 15
I expect those first two lines to instead be summed as
1 2012 50
Works Fine in SQL Server 2008.
See working Example here: http://sqlfiddle.com/#!3/3b0f9/6
Code pasted Below.
Create The Events Table
CREATE TABLE [Events]
( Venue INT NOT NULL,
[Date] DATETIME NOT NULL,
Guests INT NOT NULL
)
Insert the Rows.
INSERT INTO [Events] VALUES
(1,convert(datetime,'2012'),15),
(1,convert(datetime,'2012'),35),
(2,convert(datetime,'2012'),12),
(1,convert(datetime,'2008'),15);
GO
-- Testing, select newly inserted rows.
--SELECT * FROM [Events]
--GO
Run the GROUP BY Sql.
SELECT Venue, YEAR(date) AS yr, SUM(guests) AS yr_guests
FROM Events
GROUP BY venue, YEAR(date);
See the Output Results.
VENUE YR YR_GUESTS
1 2008 15
1 2012 50
2 2012 12
it depends of your database engine (or SQL)
to be sure (over different DB Systems & Versions), make a subquery
SELECT venue, theyear, SUM(guests) from (
SELECT venue, YEAR(date) AS theyear, guest
FROM Events
)
GROUP BY theyear
you make a subtable of
venue, date as theyear, guest
aaaa, 2001, brother
aaaa, 2001, bbrother
bbbb, 2001, nobody
... and so on
and then
count them