Report Builder 3.0 Charts - Need to show empty category groups - sql-server

I am using SQL Server Report Builder 3.0 to create a bar chart. The chart is a count of satisfaction scores (Excellent, Very Good, Good, Fair, Poor), with a bar showing each of the respective scores. It works beautifully, except in the case where there are no records with a specific score. I would like to be able to show all of the options, even if there is a value of zero. Is there a way to put a placeholder there or otherwise force it to show?

Create another table that contains all of the category names.
CREATE TABLE CATEGORIES(ID NOT NULL PRIMARY KEY);
Then insert the category names into the table.
INSERT INTO CATEGORIES
VALUES ('Excellent', 'Very Good', 'Good', 'Fair', 'Poor');
Then for your bar chart dataset,
SELECT C.ID, COUNT(A.ID)
FROM Categories C
LEFT OUTER JOIN yourTableNameHere A on C.ID = A.category
GROUP BY C.ID;
The result will be a dataset with (CategoryName, Count) records.

Related

Many to many relation hookup in Delphi

How do I do a many to many (master-master) relation in Delphi, I cannot find an example. Only dblookups and master-detail which I understand.
Like a product can belong to one or more categories. Like this table structure:
Product Table
ProductId, ProductName
CategoryTable
CategoryId, CategoryName
Relation table
ProductId, CategoryId
Ideally if you select a record in the product grid the edit of a product in a detail record is started in the right side of the screen. In here you can edit the product properties an ideally you can select via checkboxes one or more categories in a checkbox group/grid.
How do you hook this up with TTable of TQuery components? Is there a way?
Hope you can help!
Sincerely Edward
Some more explaination:
The goal is like:
master [product grid list] Detail [on selected product]
property **A**
property **B**
property **C**
property **D**
property **Category collection**
Category 1 - checked
Category 2 - unchecked
Category 3 - unchecked
Category 4 - checked
This can be transformed to a simple Master-Detail relation by using a joined query over Relation Table and Category Table (similar like this example):
SELECT * FROM Relation a
JOIN Category b on a.CategoryId = b.CategoryId
WHERE ProductId = :ProductId
In case you want a list of all categories where a separate field indicates if a relation to the product exists, you can use a query like this (example for MSSQL, the new field is named Checked):
SELECT c.*, CASE WHEN r.CategoryId IS NULL THEN 0 ELSE 1 END AS Checked
FROM CATEGORY
LEFT JOIN Relation r ON (c.CategoryId = r.CategoryId) AND (r.ProductId = :ProductId)
ORDER BY c.CategoryId
Note that you have to write the code to add or delete the relation record when you manipulate the check list by yourself.

how to make an easy graphical tool to combine database tables in vb.net?

We have to combine 3 dinstinct sql databases into one. I've copied all tables into a single Database, and now I'd have to assign then toghether. the situation is this:
the database has 3 Tables. Call them TB1 TB2 TB3
each table has its own ID column
each table contains different informations about the same item, except for the shelf property. for example, tb1 contains shelf, size and color, tb2 contains shelf, quantity and serial number, tb3 contains shelf, price and material
a shelf can contain multiple items. So same shelf does not mean same item. But a single Item cannot be on 2 shelfes.
the ID numbers of the tables do not match. so for example ID 30 of tb1 is not the same item as ID 30 on tb2.
A item present in one table MIGHT not be present in other tables.
each table contains about 1000 rows
What I need to do is to come up with a tool that allows the user to quickly create connections between tables. My current idea is to make a form with 3 Datagridviews one next to the other, containing the 3 databases. Then when I select a row on the first Datagridview it automatically scrolls to the rows in the other two datagridviews where the shelfnumber is the same. (if there is one..) the user selects one row in each table and hits the save Button, the three ID numbers of the single tables are saved into a new table.
But maybe there is a better solution to this. maybe something graphical? easier to use then selecting single rows in each table?
Thanks
The lack of a common Primary Key across the tables makes this difficult - as I'm sure you discovered.
I'd try something like this and see how it looks in the DGV
SELECT 'tb1' Table, ID, shelf, size, color, NULL QTY, NULL SN, NULL Price, NULL Material from T1
UNION
SELECT 'tb2' Table, ID, shelf, NULL, NULL, quantity,serial_number, NULL, NULL from T2
UNION
SELECT 'tb3' Table, ID, shelf, NULL, NULL, NULL, NULL, price, material from T3
You might be able to add a SORT BY ID, Table to the bottom.
Each SELECT needs the same number of columns. Only the first SELECT is used for column headers.

SQL Server FullText Search with Weighted Columns from Previous One Column

In the database on which I am attempting to create a FullText Search I need to construct a table with its column names coming from one column in a previous table. In my current implementation attempt the FullText indexing is completed on the first table Data and the search for the phrase is done there, then the second table with the search results is made.
The schema for the database is
**Players**
Id
PlayerName
Blacklisted
...
**Details**
Id
Name -> FirstName, LastName, Team, Substitute, ...
...
**Data**
Id
DetailId
PlayerId
Content
DetailId in the table Data relates to Id in Details, and PlayerId relates to Id in Players. If there are 1k rows in Players and 20 rows in Details, then there are 20k rows in Data.
WITH RankedPlayers AS
(
SELECT PlayerID, SUM(KT.[RANK]) AS Rnk
FROM Data c
INNER JOIN FREETEXTTABLE(dbo.Data, Content, '"Some phrase like team name and player name"')
AS KT ON c. DataID = KT.[KEY]
GROUP BY c.PlayerID
)
…
Then a table is made by selecting the rows in one column. Similar to a pivot.
…
SELECT rc.Rnk,
c.PlayerID,
PlayerName,
TeamID,
…
(SELECT Content FROM dbo.Data data WHERE DetailID = 1 AND data.PlayerID = c.PlayerID) AS [TeamName],
…
FROM dbo.Players c
JOIN RankedPlayers rc ON c. PlayerID = rc. PlayerID
ORDER BY rc.Rnk DESC
I can return a ranked table with this implementation, the aim however is to be able to produce results from weighted columns, so say the column Playername contributes to the rank more than say TeamName.
I have tried making a schema bound view with a pivot, but then I cannot index it because of the pivot. I have tried making a view of that view, but it seems the metadata is inherited, plus that feels like a clunky method.
I then tried to do it as a straight query using sub queries in the select statement, but cannot due to indexing not liking sub queries.
I then tried to join multiple times, again the index on the view doesn't like self-referencing joins.
How to do this?
I have come across this article http://developmentnow.com/2006/08/07/weighted-columns-in-sql-server-2005-full-text-search/ , and other articles here on weighted columns, however nothing as far as I can find addresses weighting columns when the columns were initially row data.
A simple solution that works really well. Put weight on the rows containing the required IDs in another table, left join that table to the table to which the full text search had been applied, and multiply the rank by the weight. Continue as previously implemented.
In code that comes out as
DECLARE #Weight TABLE
(
DetailID INT,
[Weight] FLOAT
);
INSERT INTO #Weight VALUES
(1, 0.80),
(2, 0.80),
(3, 0.50);
WITH RankedPlayers AS
(
SELECT PlayerID, SUM(KT.[RANK] * ISNULL(cw.[Weight], 0.10)) AS Rnk
FROM Data c
INNER JOIN FREETEXTTABLE(dbo.Data, Content, 'Karl Kognition C404') AS KT ON c.DataID = KT.[KEY]
LEFT JOIN #Weight cw ON c.DetailID = cw.DetailID
GROUP BY c.PlayerID
)
SELECT rc.Rnk,
...
I'm using a temporary table here for evidence of concept. I am considering adding a column Weights to the table Details to avoid an unnecessary table and left join.

Storing multiple employee IDs in one column of data

Web app is being written in classic ASP with a MSSQL backend. On this particular page, the admin can select 1 or any/all of the employees to assign the project to. I'm trying to figure out a simple way to store the employee IDs of the people assigned to it in one column.
The list of employees is generated from another table and can be dynamic (firing or hiring) so I want the program to be flexible enough to change based on these table changes.
Basically need to know how to assign multiple people to a project that can later be called up on a differen page or from a different query.
Sorry for the n00bish question, but thanks!
Don't store multiple ID's in one column! Create another table with the primary key of your existing table and a single ID that you want to store. You can then insert multiple rows into this new table, creating a 1:m (one to many) relationship. For example, let's look at an order table:
order:
order_id
order_date
and I have a product table...
product:
product_id
product_name
Now, you could go down the road of adding a column to order that let you list the products in the order, but that would be bad form. What you want instead is something like..
order_item:
order_item_id
order_id
product_id
quantity
unit_price
You can then perform a join to get all of the products for a particular order...
select
product.*
from orders
inner join order_item on order_item.order_id = order.order_id
inner join product on product.product_id = order_item.product_id
where orders.order_id = 5
Here's an example order_id of 5, and this will get all of the products in that order.
You need to create another table that stores these values such as. So this new table would store one row for each ID, and then link back to the original record with the original records ID.

Combining SQL results using LINQ

I have a database of company registrants (for a search/directory functionality). We've added a new table to hold "enhanced" information for registrants that pay for this feature (such as advertisements/additional images/logos etc). Right now the new table just holds the registrants unique identifier, and a few additional fields (paths to images etc). A user can search for users with specific criteria, and the enhanced listings should appear at the top of the list. The results should not show any registrant twice (so if a user has an enhanced listing they should only appear in the top "enhanced listing" area). How can I accomplish this?
Left outer join from the old table to the new table.
Prepend to your query's "order by" "case when new_table.id is null then 1 else 0 end"
So if you had this:
select foo, bar from old_table
order by bar, foo;
You'd have this:
select a.foo, a.bar from old_table a
left join new table b on (a.customer_id = b.customer_id)
order by
case when new_table.customer_id is null then 1 else 0 end,
bar, foo;
Edit: I left out the "left" from the outer join in the code.
If you are using LINQtoSQL and the designer-generated entities, you should have an entity set of related information on your registrant entity -- assuming you have set up the proper foreign key relationship. If you added this later you may need to add this by hand (see here) or delete/re-add your entities to the designer for it to pick up the new relationship. Then your query would be something like:
var registrants = db.Registrants.Where( ... selection criteria here ... );
registrants = registrants.OrderByDescending( r => r.EnhancedData.Count() )
.ThenBy( r => r.Name ); // or normal sort order
Presumably count will be either 0 or 1 so this should put the ones with enhanced data at the top of your result.

Resources