How to use ORDER BY in a Stored Procedure - sql

I have the following code:
use Northwind
go
create procedure CalcStatistics
#year int = 0
as
if exists
(select * from sysobjects
where name = 'Statistics' and type = 'U')
drop table Statistics
select YEAR(ORDERS.OrderDate) As [Year],
DATEPART(qq, OrderDate) As [Q],
SUM (Freight) As [Freight],
into Statistics
from ORDERS, ORDERDETAILS
where ORDERS.OrderID = ORDERDETAILS.OrderID
AND YEAR(ORDERS.OrderDate) = #year
group by YEAR(ORDERS.OrderDate),
DATEPART(qq, OrderDate)
order by YEAR(ORDERS.OrderDate)
exec CalcStatistics 1997
select *
from Statistics
I would like to make it so that the query prints the year and quarter of that year in ascending order, but when I try the old fashioned "order by DATEPART(qq, OrderDate)" it doesn't seem to affect the outcome of the query. How do I solve this, and why does my method not work?

I would like to make it so that the query prints the year and quarter of that year in ascending order,
Based on this statement, you need two keys in the ORDER BY. One method uses the aliases, instead of the expressions. This is simpler:
order by [Year], [Q]
Another trick when using dates is to order by the MIN() (or MAX()) of the dates:
order by MIN(ORDERS.OrderDate)
EDIT:
I think I see the problem. You are putting this data into a table called statistics, not looking at the results from the query itself. Then you are presumably running a query like this:
select s.*
from statistics s;
If so, the results are not in order. The results from a SQL query are unordered unless the query specifies the ordering. So:
select s.*
from statistics s
order by [Year], [Q];

Related

Truncate year, group by year and count another column in SQL

I want to use the following sql code to get Year information from MyDate and count unique CustomerId but get error.
SELECT YEAR(MyDate) AS MyYear, COUNT(DISTINCT CustomerId) AS MyCustomerCount
FROM MyTable
GROUP BY MyYear
However the following code works.
SELECT YEAR(MyDate), COUNT(DISTINCT CustomerId)
FROM MyTable
GROUP BY YEAR(MyDate)
Why can't alias be used in this scenario?
Simply because this is how it was defined in SQL standard.
Syntax rules
Group by clause is defined as:
However Order by clause is defined as bellow
So here you can see alias exists after order by clause then we can use it normally but not after group by clause.

How to aggregate in SQL by having clause

The below is the query I'm using, I would like to add two more columns in the select statement which I have and noted them in the group by clause but the total results are different. The below script gives me the correct total count but I want to see the totals also for a column called transaction, and a column called employee. The total count should still be the same.
SELECT SUB.YEAR, SUM(SUB.TOTAL_COUNT), SUM(SUB.TOTAL_SPENT)
FROM (
SELECT YEAR, COUNT(*) AS TOTAL_COUNT, SUM($SPENTX) AS TOTAL_SPENT, CUSTOMERID
FROM TABLE A
WHERE YEAR = 2017
GROUP BY YEAR, CUSTOMERID
HAVING SUM($SPENTX)<=1000
) SUB
GROUP BY SUB.YEAR

How to order Order Date by Order Count SQL?

This might be a silly newbie question, but I am trying to figure out how to order something.
How would you construct an SQL statement so that in a table ORDERING with an ORDERDATE attribute I can see how many orders placed on each date?
I know that the following query makes it so it is organized by the date but I want to know how many duplicates for each date in order to find how many orders placed in a day.
SELECT *
FROM ORDERING
ORDER BY ORDERDATE DESC;
Count is an aggregate function, so you have to GROUP BY the attribute you want to aggregate.
SELECT ORDERDATE,COUNT(*)
FROM ORDERING
GROUP BY ORDERDATE
ORDER BY ORDERDATE DESC;
en making questiuons.
SELECT ORDERDATE,COUNT(*)
FROM ORDERING
GROUP BY ORDERDATE
HAVING COUNT(*)>1

SQL Query to pull the last four dates

I am using SQL Server 2012 and trying to pull the 4 most recent order dates in a OrderDate column for certain members. I am not sure how to code for this. Any help will be greatly appreciated.
Order by date in descending order, and limit the number of rows to 4, like this:
select top 4 order_date from orders order by order_date desc
Optimizer will figure out that you have a limit, and optimize your query to avoid sorting the entire table. If order_date column is indexed, query optimizer would use index to get you four dates without going to the table itself.
It should be something similar to this:
select top 4 o.OrderDate
from Members m
inner join Orders o
on m.ID = o.MemberID
where <your certain members criteria>
order by o.OrderDate desc
I'd do something like this (you didn't provide table structure, so this is just pseudo-code).
Create empty table TempOrders to store top orders for each member
Open Cursor to go through all member Ids
For each #MemberId insert into TempOrders select top 4 * from orders where MemberId = #MemberId order by OrderDate desc
your result is in TempOrders table

Combining SQL Where Clauses

This is my code
SELECT sum(qty) as "sumqty", shipdate, groupnumber
from test
where (shipdate = #5/30/2014# and groupnumber = "A30") OR ( shipdate #5/31/2014# and groupnumber ="A31")
group by shipdate, groupnumber
order by sum(qty) desc;
Is there a way to shorten the where clause? Because I want to add more shipdate and groupnumber combinations.
If I understand you correctly, your question isn't about your current query, but about scaling the query to include more combinations of shipdate and groupnumber. Obviously, if you only have a few more such combinations to add, then it's not a big deal to just add them. However, if you need to add many more such combinations, then consider using a join.
You haven't said which database server and version you're using, so I'll have to try to be general.
Create a temporary table with shipdate and groupnumber columns
Use a WHERE EXISTS clause:
SELECT sum(qty) as "sumqty", shipdate, groupnumber
from test
where exists (
select shipdate,groupnumber
from #Temp_Table as tt
where tt.shipdate = test.shipdate and tt.groupnumber = test.groupnumber)
group by shipdate, groupnumber
order by sum(qty) desc;
Remove all occurrences of "test." prefix because there is a single table in the query.
You can use short alias names of selected fields.
I would create a stored procedure, and then pass the different shipdates and group numbers into that, the query would then become
SELECT sum(qty) as "sumqty", shipdate, groupnumber
from test
where (shipdate = #ShipDate and groupnumber = #GroupNumber)
group by shipdate, groupnumber
order by sum(qty) desc;
If you need to get a result set for multiple sets of ShipDate/GroupNumber combinations you can just UNION or UNION ALL the results, depending on your requirements.
Please note this is not the only way of solving this problem, if you find that you need to query for lots of combinations a common table expression or even dynamic SQL might perform better