about database table design - sql-server

I've done research on the web for a while but couldn't find a same situation. What I need is follow:
I have 20 groups, and each group has its own document template. For example, in group one, the template has 26 contents: A,B,C,D,E.....Z. But not all of these 26 contents will display.
For example, document 1 will display 10 contents, and document will display 15 contents. In group two, the template has 30 contents: aa1,bb2,cc3,.....yy30. Each document will display certain contents depending on parameters passed, same as group one.
I will create a method with parameters and the documents will be generated based on the parameters passed.
How should I design the database tables in sql server?
1) Use A,B,C,D....Z as columns, the values will be either true(show) or false(not show)? But each group has different templates. For example, group two will have columns aa, bb, cc.....So I have to create 20 tables for 20 groups? This is not a good strategy? The records be will like:
A B C
doc1 true true false
doc2 true true false
2) Use A,B,C,D...Z as rows, the values will be either true(show) or false(not show)? Then they will be many redundant records. For example, document 1 of group 1 will have:
doc1 A true
doc1 B true
doc1 C false
...
doc2
doc2
...
doc
Please help give advice. Thanks!

What I understand about your situation is as under:
You have 20 groups
Each group has set of contents
Each group has multiple document templates
Each document template has multiple contents as per need.
Considering that you don't care about normalization; you need to create single table as under:
Template Table (Group, Document, Content) and add rows only for those contents that are displayed (i.e. true in your example) for a document of a group.
Group Document Content
----- -------- -------
G1 Doc1 A
G1 Doc1 B
G1 Doc2 A
G1 Doc2 B
...
G2 Doc1 AA
G2 Doc1 BB
G2 Doc2 BB
G2 Doc2 EE
...

Related

Table Schema with multiple columns in fact table referring to one column in dimension table

To start off, I am creating a table schema in Power BI with the use of R to wrangle all of my data.
Here is a simple example of my issue. I have a table with ID numbers and several demographics related to each ID. In this case, you'll see 3 demographics related to each ID with a true/false for each demographic (in my work situation, I actually have 95 demographics).
ID
Female
Veteran
Government
1
TRUE
FALSE
FALSE
2
FALSE
FALSE
TRUE
3
TRUE
TRUE
TRUE
4
FALSE
FALSE
FALSE
So, let this be the fact table. A dimension table would look something like this:
Demographic
Key
Female
10
Veteran
11
Government
12
I need to create a relationship between these two tables. I'll be using Power BI, so I can only use one direct relationship. The main purpose is to be able to create visualizations that will filter down on a user's selection. For example, if the user is interested in how many ID's are female and veteran, the graph would only show ID #3.
As is, the dimension table will not work because there are no keys in the fact table to connect the two. For it to work properly, I would need one, and only one, column in the fact table with a key that connects to the dimension table. That would look like this:
ID
Female
Veteran
Government
Key
1
TRUE
FALSE
FALSE
10
2
FALSE
FALSE
TRUE
12
3
TRUE
TRUE
TRUE
10, 11, 12
4
FALSE
FALSE
FALSE
This doesn't work because Power BI won't "search" for a key within the "Key" column. It can only have one key per row, not a set of keys, as far as I'm aware. I could potentially make keys that would be the combination of demographics. So, for ID #3, the key would be "10_11_12" and then have that exact key within the dimension table, too. But, as mentioned above, I have 95 demographic columns and that's a right massive mess.
I have also tried to make the initial fact table above long instead of wide:
ID
Demographic
Value
Key
1
Female
True
10
1
Veteran
False
11
1
Government
False
12
2
Female
False
10
2
Veteran
False
11
2
Government
True
12
3
Female
True
10
3
Veteran
True
11
3
Government
True
12
4
Female
False
10
4
Veteran
False
11
4
Government
False
12
However, Power BI will only aggregate the data. That is, for our example of female and veteran, the graph will show any ID that is female as well as any ID that is veteran. So, the result would show ID's #1 and #3, but it should only show #3 (I need female and veteran not female or veteran).
Any ideas of how to get a dimension table and fact table to work well together for my situation?
If this is your Fact Table
(ID,Female, Veteran, Government)
Your dimensions would be
DimFemale, DimVeteran, DimGovernment, etc. Each Dimension would have two rows and probably only a single column. So you typically just don't use dimension tables when the you don't have any data other than the dimension key.
I am wanting a filter in the filter pane that has a drop-down of all 95 demographics.
That's not a dimension table, that's a child fact table with bi-directional cross filtering. Just have (Id, Demographic) and only add the ones that are TRUE.
You only need the first table, no need to complicate.
If the user wants to know the number of ID's that are female and veteran, you would have a slicer/filter for female and veteran and the results would be filtered accordingly.

Seems the indexes are missing for new entities created since some time late June 1st, 2015

We have an app running on google appengine and it works well until some time today (June 1st, 2015). We found that new entities created are missing index and they are not in the query result. I'm not sure what happens, since old entities don't have this problem. The single field index seems working fine. I don't have any clue how to solve this issue. I appreciate if anyone can shed some light on it.
Here is one example:
We have an entity like this:
EntityA {
String A;
String B;
Integer C;
}
We have such records in datastore:
A B C
123 bb 1 - old record
123 bb 2 - old record
123 bb 3 - new record
There are index for [A, B], [A, C], [A, B, C]
We found that following GQL
Select * from EntityA where A='123' and B='bb';
Will get result like this, where the new record is missing:
A B C
123 bb 1
123 bb 2
The new record is missing. However if we query with single field index like this:
Select * from EntityA where A='123';
Or like this:
Select * from EntityA where B='bb';
We see the new record in result.
A B C
123 bb 1
123 bb 2
123 bb 3
Also, query like this will get empty result:
Select * from EntityA where C=3;
But query on first two records return proper result:
Select * from EntityA where C=1;
Select * from EntityA where C=2;
So I feel like the indexes are not created for the new records.
Nothing is changed from my side, but the issue seems to be gone now earlier at June 2nd, and I do see new records in query results. Sill no clue what's the cause, and not sure if any other one see the same issue as mine. I still have to manually save all the records which were created during this period to re-create the indexes.

Keep the order of current and future posts

One of my curiosities these days is how to order some posts. I will give you a clear example, maybe one the majority of you experimented in the past.
The Facebook Timeline, which you can add posts and events to, at any point in time you want. In this case, I assume, the posts are ordered by the date. When you add a new status for the past, you have to assign it a date, so it is easy to get them in order.
What I want to do is to have posts and the option to add a new post after a specific one. I don't have the option to add a date to it but I have to have a way to get them in that order.
So, if every post has an id and a date (the creation date). If a new post is added between 2 posts, I can't increment all the ids of the "upper" posts, so that I can order by the id. Neither is the date, because I can add a post between two older posts in the future.
What solution do you imagine for this? What criteria should I order by (I am ready to make some database scheme changes if needed)?
OK, there's another possible solution. Use two columns for ordering: Order1 is basic order, and Order2 is order within group defined by Order1. You assign your posts to some arbitrary groups (i.e. all posts from single day or every 100 posts) by setting Order1. Within each group posts are ordered according to value in Order2.
If a new post must be inserted into some group you only need to renumber Order2 values for posts in this particular group - not all posts in table.
Of course when retrieving the rows you order by Order1, Order2.
So your table looks like this:
PostName Order1 Order2
------------------------
A 1 1
B 1 2
C 1 3
D 1 4
E 2 1
F 2 2
G 2 3
Now if you want to insert X between F and G you renumber only items in group Order1 = 2, so that rows become:
PostName Order1 Order2
------------------------
A 1 1
B 1 2
C 1 3
D 1 4
E 2 1
F 2 2
G 2 4
X 2 3
Now, if you want to insert Z between A and B you only renumber Order2 in posts in group Order1 = 1:
PostName Order1 Order2
------------------------
A 1 1
B 1 3
C 1 4
D 1 5
E 2 1
F 2 2
G 2 4
X 2 3
Z 1 2
IF you're not going order by a criteria (Date, for example), you will need something to order them. Not necessary have to use column Id to order, you could add a column that is not the PK, and makes the function of ordinalPosition.
So, when you insert at the end, you will get the max ordinalPosition, and then do ordinalPosition+1.
If you want to insert between two of those, then you look the ordinal position of the two post you have (to insert between them), update incrementing in 1 all ordinalColumns, from the major of those two post, and then (now you got a "hole" in the ordinalPosition), insert the new ordinalPosition, and that will be the the minor of those two post + 1 (which equally the mayor of those two post)
Then, you will get the posts ordered by your ordinalPosition:
Select fields from Posts
-- where your criteria goes here
order by ordinalPosition
Maybe you consider that's not a good way, because everytime you insert a post between two another one, you will have to do an update - but the Db is not magic, has to order by some criteria. And have to make sure there is no posts with same order id, so probably will have to add some Unique Constraint or something as you want.
You're not gonna update very old posts probably, so I don't think will be so much update's everytime you add a posts between other two.

How to write a query to see who called who the most in an Access database of phone calls?

I have a phone bill in Excel that shows all calls made to and from my phone and I imported it into a table in Access 2007. I want to learn to use Access to do a simple query to determine who I talk to the most.
Say we have Column A (caller) and Column B (person being called), and that my number will always be in either column. How do I make a query in Access to determine which phone number I talk the most with? I've got the Table with the Excel data in it, but I need some step-by-step handholding to learn how to do the query.
In simple english, I want to query all phone calls that contain my number in either column A or column B. Then, I want to count each unique pair (mynumber + othernumber or othernumber + mynumber should be counted under the same pair). Then, I want to count/summarize each unique pair to see which pair yields the highest count.
E.g. Go to Create ribbon, click Query Wizard, etc...
Thanks!
Lets say you have the following table :-
Column A : Column B
---------:----------
Fred : 1
Bill : 2
Fred : 1
You could do a query for example :-
SELECT A, B, Count(B) AS CountOfB
FROM Table1
GROUP BY A, B
ORDER BY Count(B) DESC
This would give you :-
Column A : Column B : CountOfB
---------:----------:----------
Fred : 1 : 2
Bill : 2 : 1
The first row would list the most common occurrences of column B and the count would list the number of times that row has been seen.

yet another tsql question

i have three tables
documents
attributes
attributevalues
documents can have many attributes
and these atributes have value in attributevalue table
what i want in single query get all documents and assigned atributes of relevant documents in row each row
(i assume every documents have same attributes assigned dont need complexity of diffrent attribues now)
for example
docid attvalue1 attvalue2
1 2 2
2 2 2
3 1 1
how can i do that in single query
Off the top if my head, I don't think you can do this without dynamic SQL.
The crux of the Entity-Attribute-Value (EAV) technique (which is what you are using) is to store columns as rows. What you want to do is convert those rows back to columns for the purpose of this query. Using PIVOT makes this possible. However, PIVOT requires knowing the number of rows that need to be converted to columns at the time the query is written. So assuming you are using EAV because you need flexible attributes/values, you won't know this information when you write the query.
So the solution would be to use dynamic SQL in conjunction with PIVOT. Did a quick search and this looks promising (didn't really read the whole thing):
http://www.simple-talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx
For the record, I am not a fan of dynamic SQL and would recommend finding another approach to the larger problem (e.g. pivoting in application code).
If you know all the attributes (and their IDs) at design-time:
SELECT d.docid,
a1.attvalue AS attvalue1
a2.attvalue AS attvalue2
FROM documents d
JOIN attributevalues a1 ON d.docid = a1.docid
JOIN attributevalues a2 ON d.docid = a2.docid
WHERE a1.attrid = 1
AND a2.attrid = 2
If you don't, things get quite a bit messier and difficult to answer without knowing your schema.
lets make example
documents table's columns
docid,docname,createddate,createduser
and values
1 account.doc 10.10.2010 aeon
2 hr.doc 10.11.2010 aeon
atributes table's columns
attid,name,type
and values
1 subject string
2 recursive int
attributevalues table's columns
attvalueid,docid,attid,attvalue(sql_variant)
and values
1 1 1 "accounting doc"
1 1 2 0
1 2 1 "humen r doc"
1 2 2 1
and I want query result
docid,name,atribvalue1,atribvalue1,atribvalueN
1 account.doc "accounting doc" 0
2 hr.doc "humen r doc" 1

Resources