Apologies for my lack of knowledge on this, I've researched here and elsewhere but have hit a brick wall (my brain). I'm trying to display the rates for a villa in a table like this:
SPRING SUMMER FALL WINTER MAX GUESTS
2 Rooms $343 $288 $389 $467 2
3 Rooms $456 $415 $536 $756 4
Whole Villa $809 $789 $906 $1023 6
I assume that PIVOT is the answer to my woes. I'm using SQL Server 2008 on MS Server 2008 R2
The seasons, packages and prices are stored in 3 tables like this:
CONFIGURATIONS
--------------
configurationID
configurationName
maximumGuests
SEASONS
-------
seasonID
seasonName
CONFIGURATIONSEASONRATES
------------------------
seasonID
configurationID
price
I got as far as this based on the examples I've been able to find:
SELECT 'Packages', 'Summer', 'Winter', 'Christmas', 'Tropical'
FROM
(SELECT ACCOMMODATION_configurations.configurationName, price
FROM ACCOMMODATION_configurations INNER JOIN
ACCOMMODATION_configurationSeasonRates ON
ACCOMMODATION_configurations.configurationID = ACCOMMODATION_configurationSeasonRates.configurationID INNER JOIN
ACCOMMODATION_seasons ON ACCOMMODATION_configurationSeasonRates.seasonID = ACCOMMODATION_seasons.seasonID) as somethingNice
PIVOT (sum(price) for ACCOMMODATION_configurations.configurationName IN (['Summer'],['Winter'],['Christmas'],['Tropical'])) as anyThing
But I get an error saying
The column prefix 'ACCOMMODATION_configurations' does not match with a table name or alias used in the query
I then tried replacing SELECT 'Packages' with SELECT ACCOMMODATION_configurations.configurationName but then I am told that:
SELECT ACCOMMODATION_configurations.configurationName cannot be bound
Thanks in advance for any help!
Inside of your PIVOT syntax you need to remove the ACCOMMODATION_configurations. Also remove the single quotes around the values in the FOR and you need to add the Packages column to the inner select.
So the code will be:
-- this select will display the packages and the seasons
SELECT Packages, Summer, Winter, Christmas, Tropical
FROM
(
-- add Packages to this select list
SELECT Packages, ac.configurationName, price
FROM ACCOMMODATION_configurations ac
INNER JOIN ACCOMMODATION_configurationSeasonRates sr
ON ac.configurationID = sr.configurationID
INNER JOIN ACCOMMODATION_seasons s
ON sr.seasonID = s.seasonID
) as somethingNice
PIVOT
(
sum(price)
for configurationName IN ([Summer],[Winter],[Christmas],[Tropical])
) as anyThing
Edit, based on your comment it seems like you might want:
-- this select will display the packages and the seasons
SELECT Packages, Summer, Winter, Christmas, Tropical
FROM
(
SELECT ac.configurationName as Packages, price, seasonName
FROM ACCOMMODATION_configurations ac
INNER JOIN ACCOMMODATION_configurationSeasonRates sr
ON ac.configurationID = sr.configurationID
INNER JOIN ACCOMMODATION_seasons s
ON sr.seasonID = s.seasonID
) as somethingNice
PIVOT
(
sum(price)
for seasonName IN ([Summer],[Winter],[Christmas],[Tropical])
) as anyThing
Related
I am trying to find the top 10 brands and article type on shopping page for etailer.
the logic I am using is as follows:
I am creating a table for both ]using this logic below and storing top 10
WITH CTE AS
(
SELECT shoppingpage_url,
brand,
COUNT(*) AS sp_count
FROM TABLE name
GROUP BY 1,
2
)
SELECT *,
ROW_NUMBER() OVER (PARTITION BY shoppingpage_url ORDER BY sp_count DESC)
AS Top_10_flag
FROM cte
I am doing the same for article type and joining them both.
SELECT a.shoppingpage_url,
a.top_10_flag,
brand,
article_type
FROM dev.top10_Brand a
LEFT JOIN dev.top10_Articletype b
ON a.shoppingpage_url = b.shoppingpage_url
AND a.Top_10_flag = b.Top_10_flag
The problem I am facing is for certain pages its just one brand but multiple article types.
I am missing the article types for the pages with brand counts Top_10_flag not equal to or lesser than Article type'Top_10_flag.
how do I prevent this?
sample data
-- brand data table
shoppingpage_url, brand,sp_count,Top_10_flag
url1,brandd,5,1
url2,branda,17,1
url2,brandb,8,2
url2,brandc,4,3
url3,brande,5,1
-- article type table
shoppingpage_url, article_type,sp_count,Top_10_flag
url1,articletype1,5,1
url1,articletype2,5,1
url1,articletype3,5,1
url2,articletype12,17,1
url2,articletype3,8,2
url3,articletype23,5,1
url3,articletype2,5,1
-----
the result I am getting
shoppingpage_url,Top_10_flag, brand, article_type
url1,1,brandd,articletype1
url2,1,branda,articletype12
url2,2,brandb,articletype3
url2,3,brandc,
url3,1,brande,1articletype23
---------------------------
what i want
url1,1,brandd,articletype1
url1,2,,articletype2
url1,3,,articletype3
url2,1,branda,articletype12
url2,2,brandb,articletype3
url2,3,brandc,
url3,1,brande,1articletype23
url3,2,,1articletype2
Are you looking for a full join?
SELECT COALESCE(b.shoppingpage_url, a.shoppingpage_url) as shoppingpage_url,
COALESCE(b.top_10_flag, a.top_10_flag) as top_10_flag,
b.brand, a.article_type
FROM dev.top10_Brand b FULL JOIN
dev.top10_Articletype a
ON a.shoppingpage_url = b.shoppingpage_url AND
a.Top_10_flag = b.Top_10_flag
I have a table "Bed" and a table "Component". Between those two I have a m:n relation and the table "BedComponent", where I store the Bed-ID and the Component-ID.
Every Component has a price. And now I want to write a select-statement that gives me the sum of prices for a certain bed.
This is what I have:
SELECT Bed.idBed, Bed.name, SUM(src.price) AS summe, Bed.idCustomer
FROM Bed,
(SELECT price
FROM dbo.Component AS C
WHERE (C.idComponent IN
(SELECT idComponent
FROM dbo.BedComponent AS BC
WHERE 1 = BC.idBed))) AS src
GROUP BY dbo.Bed.idBed, dbo.Bed.name, dbo.Bed.idCustomer;
This statement works. But of course I don't want to write the bed-ID hard coded into my select as it will always calculate the price for bed 1. Instead of the "1" i want to have the current bed-id.
I work with MS SQL Server
Thanks for your help.
I think you want:
select b.idBed, b.name, SUM(src.price) AS summe, b.idCustomer
from bed b join
bedcomponent bc
on b.idBed = bc.idBed join
component c
on c.idComponent = bc.idComponent
group by b.idBed, b.name, b.idCustomer;
The idCustomer looks strange to me in the select and group by, but I don't know what you are trying to achieve.
Also note the use of table aliases, which make the query easier to write and to read.
EDIT - i'm reposting this question in an attempt to explain what i mean better
I'm using SQL 2008 R2 and I work for a retail department store and we need a report to show all the sales orders made in each department, and sections of those departments.
What i want is to group up all the sales order lines by department and section, but remove only the sections that have a total sales value of less than £50. I still want to see order lines that are over £50, though.
Here is an example of what i currently have:
Data before filtering
I want to remove the Accessories section and all lines contained within it, as it has a total section value of less than £50. So i would want it looking like this after filtering:
Data after filtering
Here is my code:
SELECT department.department_name
,section.section_name
,sales_order_detail.sales_order_number
,sales_order_detail.sales_order_line
,LineValue
FROM
sales_order_detail INNER JOIN stock_item ON sales_order_detail.stock_item_code = stock_item.stock_item_code
INNER JOIN style ON stock_item.style_code = style.style_code
INNER JOIN department ON style.dept_code = department.department_code
INNER JOIN section ON style.section_code = section.section_code AND style.dept_code = section.department_code AND department.department_code = section.department_code
Can you please explain all the ways this can be done. I've tried using GROUP BY and HAVING but that then filters out all my sales order lines. I've tried using a Group Filter in the visual studio report design surface which removes the lines but then aggregates calculated at the Department group scope don't take into account the lines removed at the section level.
I appreciate any help i can get on this.
Jacob
As you are using 2008R2, you can use the magic that are Windowed Functions to calculate the total of the group that the row belongs to (the partition part of the over clause below) and then wrap your query into a filtering select statement. Not having your data this is obviously not tested, but it should work:
select department_name
,section_name
,sales_order_number
,sales_order_line
,LineValue
,GroupTotal
from(
select d.department_name
,se.section_name
,sod.sales_order_number
,sod.sales_order_line
,sod.qty_ordered * sod.selling_price AS LineValue
,sum(sod.qty_ordered * sod.selling_price) over (partition by d.department_name
,se.section_name
) as GroupTotal
from sales_order_detail sod
inner join stock_item si
on sod.stock_item_code = si.stock_item_code
inner join style s
on stock_item.style_code = s.style_code
inner join department d
on s.dept_code = d.department_code
inner join section se
on s.section_code = se.section_code
and s.dept_code = se.department_code
and d.department_code = se.department_code
) a
where GroupTotal > 50
My question: the owners would like to know the revenue generated so far (i.e. where CheckOutDate < DATE()) for each room type in each hotel.
The calculation must be done in the SQL statement.
Determine the length of stay for each reservation (i.e. number of days) using the DateDiff function datediff('d', checkindate, checkoutdate) and multiply this value by the room rate.
Your output should be formatted as shown on the next page. Your Revenue totals may be different. Keep in mind, the Revenue amount may change on a daily basis, as we want to include only those reservations that are completed, not current or future reservations.
select
room.hotelID, room.roomtype,
datediff('d', Reservation.CheckOutDate, Reservation.CheckInDate) * ROOM_TYPE.RoomRate as Revenue
from
Reservation
inner join
Room on Room.hotelID = Reservation.HotelID
inner join
ROOM_TYPE on ROOM_TYPE.RoomType = Room.roomtype
group by
Room.HotelID, Room.roomtype;
I am getting syntax error statement missing in this.
How to resolve this error in MS Access?
When using a Group By clause, any columns that are not part of the grouping must be aggregated. In your case, Room.HotelID and Room.RoomType are the grouping columns. So they are fine in your SELECT clause, as-is. But Revenue needs to be aggregated. I expect that you will want to use the SUM aggregation to sum up all of the Revenue values for each room type. Try this...
select room.hotelID,
room.roomtype,
SUM( datediff(day,Reservation.CheckOutDate,Reservation.CheckInDate )*ROOM_TYPE.RoomRate) as Revenue
from Reservation
inner join Room on Room.hotelID=Reservation.HotelID
inner join ROOM_TYPE on ROOM_TYPE.RoomType=Room.roomtype
group by Room.HotelID, Room.roomtype;
Running the query below against your data in Access 2010 produced this result set:
hotelID roomtype Revenue
------- -------- ----------
1000 D $23,000.00
1000 F $23,100.00
1000 S $20,700.00
1111 D $36,500.00
1111 F $16,450.00
1111 S $15,300.00
SELECT
rm.hotelID,
rm.roomtype,
Sum(DateDiff('d', rs.CheckInDate, rs.CheckOutDate) * rt.RoomRate) AS Revenue
FROM
(
ROOM AS rm INNER JOIN RESERVATION AS rs
ON (rm.roomno = rs.RoomNo) AND (rm.hotelID = rs.HotelID)
)
INNER JOIN ROOM_TYPE AS rt
ON rm.roomtype = rt.RoomType
WHERE rs.CheckOutDate < Date()
GROUP BY rm.hotelID, rm.roomtype;
You should still learn how to use the Query Builder but I think the parens should look something like this:
select
Room.HotelID, Room.roomtype,
sum(
datediff('d',Reservation.CheckOutDate,Reservation.CheckInDate) *
ROOM_TYPE.RoomRate
) as Revenue
from
((Reservation inner join Room on Room.hotelID = Reservation.HotelID)
inner join ROOM_TYPE on ROOM_TYPE.RoomType = Room.roomtype)
group by
Room.HotelID, Room.roomtype;
So in summary:
Be careful with grouping columns and aggregates
Access uses quotes around it's datediff argument unlike some other systems
Nesting of joins needs parentheses
In MS Access we have to mention in brackets () on the clause in from statement. Apart from that datediff function has to be a part of aggregate function.
I have two tables: EQUIPMENT and WORKORDERS.
EQUIPMENT returns the count of Equipment against a particular depot by the type of Equipment:
MAINTDEPOT EQUIPCOUNT EQUIPTYPE
1 44 MC
2 20 MC
3 5 MC
1 20 FS
2 3 FS
3 10 FS
...and so on. These counts rarely change unless a new bit of kit is put in.
I need to join a count of WORKORDERS to this table, but the work orders have a COSTCENTRE of either A B or E. This is so that I can generate a percentage of equipment with workorders.
I've joined the tables, but when I add a parameter filter to the WORKORDERS COSTCENTRE column the Count of EQUIPMENT changes, and I need it to stay the same.
I'm guessing I need to use subqueries to ensure that the left subquery remains static whilst the filter only changes the right hand one. Does anyone have any idea how I do this?
Here's my current query:
SELECT E.E_MAINTDEPOT, E.E_EQUIPCOUNT, C.Category, E.MYORDER, E.W_WORKCOUNT,
E.E_NOWO, E.W_HRS, E.E_QA, E.E_EGI, E.E_CLASS,
ISNULL(ROUND(CAST(E.E_NOWO AS Float) /
CAST(E.E_EQUIPCOUNT AS Float) * 100, 2), 100) AS RESULT,
SUBSTRING(E.E_CLASS, 1, 1) AS EM_CLASS
FROM (
SELECT T.E_MAINTDEPOT, COUNT(T.EQUIP_NO) AS E_EQUIPCOUNT,
SUM(C.W_WORKCOUNT) AS W_WORKCOUNT,
COUNT(T.EQUIP_NO) - SUM(C.W_WORKCOUNT) AS E_NOWO, T.MYORDER,
T.E_QA, T.E_EGI, T.E_CLASS, SUM(C.W_HRS) AS W_HRS
FROM EQDType AS T
FULL OUTER JOIN EquipWOCount AS C
ON T.EQUIP_NO = C.EQUIP_NO
GROUP BY T.MYORDER, T.E_MAINTDEPOT, T.E_QA, T.E_EGI, T.E_CLASS, C.W_FUNCTION
) AS E
INNER JOIN EQDCategory AS C
ON E.MYORDER = C.Myorder
ORDER BY E.MYORDER, E.E_MAINTDEPOT
Thank you