Unable to create hierarchy in PivotTable - pivot-table

This is how my dataset looks like:
ItemType ItemCategory ItemName
ItemType1 ItemCat1 Item1
ItemType1 ItemCat1 Item2
ItemType1 ItemCat2 Item3
ItemType2 ItemCat1 Item4
ItemType2 ItemCat2 Item5
ItemType2 ItemCat2 Item6
ItemType3 ItemCat1 Item7
ItemType3 ItemCat2 Item8
ItemType3 ItemCat1 Item9
I am trying to display this in PivotTable so that i can get tree view kind of structure with ItemCategory as Row rather than column.
ItemType ItemCat1 ItemCat2
ItemType1 Item1 Item3
Item2
ItemType2 Item4 Item5
Item6
ItemType3 Item7 Item9
Item8
To achieve this, this is what i did.
I created ItemType and ItemCategory as Dimensions and ItemName as Expression. But it does not show me the data in the ItemName column.
I created ItemType, ItemCategory and ItemName as Dimensions, but it does not let me drag and drop ItemCategory column on top of ItemName. It however shows the data.
I created ItemType, ItemCategory and ItemName as Dimensions and ItemName as Expression, it allows me to drag and drop the ItemCategory on top of ItemName expression column but the result is not what i am looking for.
What am i missing here?

I think I was able to achieve what you intended.
Solution used :
ItemType and ItemCategory as Dimensions.
ItemName used in a Expression, Concat(ItemName, chr(13))
In the Presentation tab of the Pivot Table properties, tick the Wrap Cell Text check box in order to display multiple lines in a cell.
The trick here is the Concat function. Since you have multiple ItemName for the same ItemCategory and ItemType you need some way of putting them together. Concat does it, usually generating a comma separated string (you could do it also here, with Concat(ItemName, ',')).
It also might be a good a idea to use the expression Concat(DISTINCT ItemName, chr(13)) to ensure that you don't have repeated ItemNames in the same cell.

Related

Display Foreign Field in Combo Box

My database is based on a cinema and features the following tables:
Movies
Customers
Ticket Information
Screenings
Bookings
I have created a combo box in the Bookings table for the Screening ID field:
This allows me to see a list of information about the cinema's screenings. The four columns that can be seen in this combo box are:
|---------------------|------------------|---------------------|------------------
| Screening ID | Screening Date | Screening Time | Movie ID
|---------------------|------------------|---------------------|------------------
| | | |
All of these fields - Screening ID, Screening Date, Screening Time and Movie ID - are fetched from the Screenings table. But, the final column, Movie ID, doesn't really do much for me. I would really like the movie name to be displayed here, as well as just the identifier, but no such field exists in the Screenings table. It does exist, however in the Movies table, see below:
(The Movies field Movie ID is referenced as a foreign key by Screenings.)
Is there any way in which I can display this field, Movie, as well as Movie ID in my combo box from the first image?
Your comboBox RowSource is currently set to Screenings
Make a new query that joins screenings and movies and assign the query as the rowSource to your combobox. Something like
Select
[Screening ID],
[Screening Date],
[Screening Time],
Movie
From
screenings inner join movies on screenings.[movie id] = movies.[movie id]

SQL column which is a list containing other rows

I have a table which looks like this:
Persons
| Id | Name | FavoriteColor |
And I want to add a new column which is "Friends" so that it becomes
Persons
| Id | Name | FavoriteColor | Friends |
I want the Friends column to be (in abstraction) a list containing the Ids of other rows in the Persons table.
What's the best way to do this? I know I can use FK's to link up tables, but I'm not just linking a specific row to a specific row in a different table, but rather a specific row to a specific table.
You dont add a field, you create a second table
Persons: id, Name, Favorite Color
Friends: PersonA_id, PersonB_id
Where PersonA_id, PersonB_id are Foreign Key to Persons table.
So you can have things like this in persons
id Name Color
1 Luis Blue
2 Pedro Red
3 Ana Yellow
4 Donald Black
Friends:
PersonA_id PersonB_id
1 2
3 1
Luis have 2 friends, Pedro and Ana only have a friend (Luis), and Donald 0 friends.

Designing hierarchy tables

Lets say that I have to store the following information in my database,
Now my database tables will be designed and structured like this,
In a later date, if I had to add another sub category level how will I be able to achieve this without having to change the database structure at all?
I have heard of defining the columns as row data in a table and using pivots to extract the details later on...Is that the proper way to achieve this?
Can someone please enlighten me or guide me in the proper direction? Thanks in advance...
:)
It would be difficult to add more columns to your table when new levels are to be generated. The best way is to use a Hierarchy table to maintain Parent-Child relationship.
Table : Items
x----x------------------x------------x
| ID | Items | CategoryId |
|----x------------------x------------x
| 1 | Pepsi | 3 |
| 2 | Coke | 3 |
| 3 | Wine | 4 |
| 4 | Beer | 4 |
| 5 | Meals | 2 |
| 6 | Fried Rice | 2 |
| 7 | Black Forest | 7 |
| 8 | XMas Cake | 7 |
| 9 | Pinapple Juice | 8 |
| 10 | Apple Juice | 8 |
x----x------------------x------------x
Table : Category
In category table, you can add categories to n levels. In Items table, you can store the lowest level category. For example, take the case of Pepsi - its categoryId is 3. In Category table, you can find its parent using JOINs and find parent's parents using Hierarchy queries.
In Category table, the categories with ParentId is null(that is with no parentId) will be the MainCategory and the other items with ParentId will be under SubCategory.
EDIT :
Any how you need to alter the tables, because as per your current schema, you cannot add column to the first table because the number of Sub category may keep on changing. Even if you create a table as per Rhys Jones answer, you have to join two tables with string. The problem in joining with string is that, when there is a requirement to change the Sub category or Main category name, you have to change in every table which you be fall to trouble in future and is not a good database design. So I suggest you to follow the below pattern.
Here is the query that get the parents for child items.
DECLARE #ITEM VARCHAR(30) = 'Black Forest'
;WITH CTE AS
(
-- Finds the original parent for an ITEM ie, Black Forest
SELECT I.ID,I.ITEMS,C.CategoryId,C.Category,ParentId,0 [LEVEL]
FROM #ITEMS I
JOIN #Category C ON I.CategoryId=C.CategoryId
WHERE ITEMS = #ITEM
UNION ALL
-- Now it finds the parents with hierarchy level for ITEM
-- ie, Black Forest. This is called Recursive query, which works like loop
SELECT I.ID,I.ITEMS,C.CategoryId,C.Category,C.ParentId,[LEVEL] + 1
FROM CTE I
JOIN #Category C ON C.CategoryId=I.ParentId
)
-- Here we keep a column to show header for pivoting ie, CATEGORY0,CATEGORY1 etc
-- and keep these records in a temporary table #NEWTABLE
SELECT ID,ITEMS,CATEGORYID,CATEGORY,PARENTID,
'CATEGORY'+CAST(ROW_NUMBER() OVER(PARTITION BY ITEMS ORDER BY [LEVEL] DESC)-1 AS VARCHAR(4)) COLS,
ROW_NUMBER() OVER(PARTITION BY ITEMS ORDER BY [LEVEL] DESC)-1 [LEVEL]
INTO #NEWTABLE
FROM CTE
ORDER BY ITEMS,[LEVEL]
OPTION(MAXRECURSION 0)
Here is the result from the above query
Explanation
Black Forest comes under Cake.
Cake comes under Bakery.
Bakery comes under Food.
Like this you can create children or parent for any number of levels. Now if you want to add a parent to Food and Beverage, for eg, Food Industry, just add Food Industry to Category table and keep Food Industry's Id as ParentId for Food and Beverage. Thats all.
Now if you want do pivoting, you can follow the below procedures.
1. Get values from column to show those values as column in pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + COLS + ']', '[' + COLS + ']')
FROM (SELECT DISTINCT COLS,[LEVEL] FROM #NEWTABLE) PV
ORDER BY [LEVEL]
2. Now use the below PIVOT query
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT * FROM
(
SELECT ITEMS, CATEGORY, COLS
FROM #NEWTABLE
) x
PIVOT
(
MIN(CATEGORY)
FOR COLS IN (' + #cols + ')
) p
ORDER BY ITEMS;'
EXEC SP_EXECUTESQL #query
Click here to view result
You will get the below result after the pivot
NOTE
If you want all the records irrespective of an item, remove the WHERE clause inside CTE. Click here to view result.
Now I have provided order of columns in pivot table as DESC ie, its shows top-level parent.....Item's parent. If you want to show Item's parent first followed be next level and top-level parent at last, you can change DESC inside the ROW_NUMBER() to ASC. Click here to view result.
According to your schema there's no relationship between 'main category' and 'sub category' but your sample data suggests there would be a relationship, i.e. Alcohol IS A Beverage etc. This sounds like a hierarchy of categories, in which case you could you a single self-referencing Category table instead;
create table dbo.Category (
CategoryID int not null constraint PK_Category primary key clustered (CategoryID),
ParentCategoryID int not null,
CategoryName varchar(100) not null
)
alter table dbo.Category add constraint FK_Category_Category foreign key(ParentCategoryID) references dbo.Category (CategoryID)
insert dbo.Category values (1, 1, 'Beverages')
insert dbo.Category values (2, 1, 'Soft Drink')
insert dbo.Category values (3, 1, 'Alcohol')
This way you can create as many levels of category as you want. Any category where ParentCategoryID = CategoryID is a top level category.
Hope this helps,
Rhys
In order to add a new sub category, you should add the category to the table "ItemSubCategory1" after that you can easily add it to the "Drinks" table.
For Example:
If there is a new category name "Hot Drinks" and a new item "Coffee" which comes in Beverages main category (let CatId=1, MainCatText='Beverages' in ItemMainCategory table) then
INSERT INTO ItemSubCategory1(CatId,SubCatText) VALUES(4,'Hot Drinks')
INSERT INTO Drinks(ItemId,ItemName,ItemMainCategory,ItemSubCategory)
VALUES(5,'Coffee',1,4)

Same query fetching different results

I am following this article series to learn about ROLLUP and CUBE
http://beyondrelational.com/modules/2/blogs/28/posts/10471/tsql-lab-6-using-with-cube-to-generate-subtotal-and-grand-total-rows.aspx
For this query:
select
case
when grouping(CustomerName) = 1 then 'All Customers'
else CustomerName
end as CustomerName,
case
when grouping(ItemName) = 1 then 'All Items'
else ItemName
end as ItemName,
sum(quantity*pricepercase) as Amount1
from orders
group by CustomerName, ItemName
with cube
The author has result like this:
CustomerName ItemName Amount
-------------------- -------------------- ---------------------
Jacob Item 1 312.50
Jacob Item 2 480.00
Jacob All Items 792.50
Mike Item 1 75.00
Mike Item 2 44.00
Mike All Items 119.00
All Customers All Items 911.50
All Customers Item 1 387.50
All Customers Item 2 524.00
The two extra rows generated by cube are the last 2 rows. I get results like this:
CustomerName ItemName Amount
-------------------- -------------------- ---------------------
Jacob Item 1 312.50
Mike Item 1 75.00
All Customers Item 1 387.50
Jacob Item 2 480.00
Mike Item 2 44.00
All Customers Item 2 524.00
All Customers All Items 911.50
Jacob All Items 792.50
Mike All Items 119.00
The first result set looks appropriate. Why is there a difference when I run it?
IIRC SQL does not guarantee any order except when you explicitely have an ORDER BY in place... sometimes different SQL Server versions/patchlevels "order" differently without an ORDER BY.
I don't know whether the author produced that result using SQL Server 2005 or 2008 or 2008 R2 etc. BUT I higghly suspect that this is the reason for what you see...
IF you need a specific order in the resultset always use an explicit ORDER BYclause!

Group columns in ExtJS Grid

I am new to ExtJS and cannot seem to figure out how to group columns with its own header. An example of what I'm trying to accomplish is below:
+-----------------------+-----------------------+
| Group 1 | Group 2 |
+-------+-------+-------+-------+-------+-------+
| col1 | col2 | col3 | col4 | col5 | col6 |
+-------+-------+-------+-------+-------+-------+
| |
| data goes here |
| |
+-----------------------------------------------+
Obviously, by default I can get col1 through col6 as they are the standard columns. However, I want to add the group names above them. How would I go about doing this or is there a resource that already shows how to do this? I have searched Google for about an hour with no prevail. Thanks in advance for your help!
Like Jared said the pivot grid is great if you want ExtJS to do the pivoting for you. You feed the pivot grid a list of records, specify what to group on on the y and x axis and voila.
I think that would work up to a couple of hundred rows but will become problematic with more ( I have done pivot tables in a online research application I wrote in ExtJS with pivoting on millions of records). Also if you want to feed it your entire grouped data yourself you don't want the pivot grid ( I think)
For both cases you need the GroupHeader plugin:
http://www.sencha.com/forum/showthread.php?22337-Ext.ux.plugins.GroupHeaderGrid-(v1.3)
Good luck with any 1 you choose, both are great
Rob
It looks like you are looking for the pivot grid:
http://dev.sencha.com/deploy/dev/examples/pivotgrid/simple.html

Resources