Please bear with my rambling for a moment.
I have a table called Survey.
This table is used to store Different kinds of surveys.
For instance, there is Employee Survey.
Salary Survey, etc.
Then there is a Questions table.
This table houses questions related to each Survey.
It has surveyId fk to Survey table.
But the real kicker is that it also has a field called QuestionOrder.
I need this field to be able to order and re-order questions related to a particular Survey.
For instance, right now, if a user takes an Employee survey, the first question starts with number 1), the next question, 2), et.
If we start with a new Survey, we would like the question for that survey to start with 1.
I would like to do this with QuestionOrder field.
Any idea how to do this?
I do not think this can be easily done via SQL. Perhaps you should move this logic to the application layer. For instance, when you add a new question, the QuestionOrder will be equal to "# of QuestionOrder in Survey" + 1
Create view with ROW_NUMBER() OVER(PARTITION BY surveyId ORDER BY >as you need<) as QuestionOrder
Related
I have a report with a parameter where the end user chooses a practice name that corresponds to a group of people. Most of these groups have fewer than 10 people, but a small number of them have as many as 150. When there are more than 15 people in a given group, they want separate graphs, each with no more than 15 people. So for most of the groups, we only need one graph. For a few, we need a lot of graphs.
Behind the scenes, I created a graph for each multiple of 15 people, and set them to only be visible if there are actually that many people in the group. This does what I need it to, but it makes the report super slow. As close as I can tell, behind the scenes when an end user runs the report it's still somehow rendering the hidden graphs and slowing it all to heck. (I did find this link which I think suggests this is a known bug.
I need to have one report where the end user selects the practice name, so I can't make two reports, "My practice is normal" and "My practice is ginormous". I thought maybe I could make a conditional sub-report split into those two reports based on the practice name parameter, but that doesn't appear to be possible; you can play around with visibility but I'm guessing that will still cause the invisible graph rendering problem and not help my speed.
Are there any other cool tips I can try to speed up my report, or is this just a case of too many graphs spoiling the broth?
The easiest way would be to generate a group number for every 15 people and then use a list control to repeat the chart for each group.
Here's a very quick example of this in action. I just used some sample data from one of the Adventure Works sample database.
Here's my query that returns every person in each selected department. Note that I have commented out the DELCAREs as these were just in there for testing.
--DECLARE #Department varchar(50) = ''
--DECLARE #chartMax int = 5
SELECT
GroupName, v.Department, v.FirstName, v.LastName
, ChartGroup = (ROW_NUMBER() OVER(PARTITION BY Department ORDER BY LastName, FirstName)-1) / #chartMax -- calc which chart number the person belongs to
, Salary = ((ABS(CHECKSUM(NewId())) % 100) * 500) + (ABS(CHECKSUM(NewId())) % 1000) + 10000 -- Just some random number to plot
FROM [HumanResources].[vEmployeeDepartment] v
WHERE Department IN (#Department)
ORDER BY Department
The key bit is the ChartGroup column
ChartGroup = (ROW_NUMBER() OVER(PARTITION BY Department ORDER BY LastName, FirstName)-1) / #chartMax
This will give the first 5 rows in each department a ChartGroup of 0 the next 15 1 and so on. I used 5 rather than 15 just so it's easier to demo.
Here's the dataset results
Now, in your report, add a List, set it's dataset property to your dataset containing your main data (the query above in my case).
Now edit the 'details' rowgroup properties and add a grouping by Practice and ChartGroup (Department and ChartGroup in this example)
In the list box's textbox, right-click then insert a chart.
Set the chart up as required, in my example, I used salary as the values on a pie chart and the employee names as the labels.
Here's the final design ..
Note that I set the department as a multi-value parameter and also set the number of persons per chart (chartMax) as a report parameter.
When I preview the report I get this for 'Engineering' which has 6 employees
Sales has 18 employees so we get this
.... and so on, it will generate a new chart for every 15 people or part thereof.
I am struggling in the creation of a report including four tables.
Those tables should be the same for each account. I use just one dataset. When I run the report, the data is good, but tables listing appears wrong.
First all BALANCE DETAIL tables for all accounts selected are listed, then all DEBIT TRANSACTION tables for all accounts selected are listed etc.
For each account the page should show up just like this
Please give me an easy-to-understand answer since I am really a beginner in this sector.
It might be easier to this with 5 separate datasets, but I think you can do it with just on also.
Create on 'main' table on the dataset. use 4 detail rows, 1 column
Group it on accountnumber
In each detail of the main table, insert a new table with the same dataset.
Group those sub-tables also on accountnumber
Add a filter to the subtables. set the subtable accountnumber equal to the outer table account number (you can use the expression builder, but it should read something like this: row['ponum'] equals row._outer["ponum"] )
Good luck!
I know this has been asked before..sort of. And that's why I'm posting. Basically I'm building a report in Crystal that relies, to keep this simple, at least 3 tables.
Table A is inner joined to table B by a unique ID. Table B has a child table that may or may not have data related to this unqiue ID.
As a general example table A is a customer table, table B is a product table and the child table is contains the product number. All customers have a product, but not all customers have product number in the child table. I hope I've explained that simply enough.
My issue is sort of between Crytal and Access and how to query this. When I'm writing behind something in VB it's easy enough to write and execute a query and display the result in the desired manner. However I can't seem to get my query straight... I either end up with a report with cartesian product as the resultset, which displays ok...except that even with the few records I have ends up being about 30k pages..or I end up with a blank dataset because the child table does not have corrisponding data to B.
Using outter joins I've managed to get my results within some amount of reason but not acceptable to a real world report. I'm sure this issue has come up but I can't seem to find any suitable answers and to be honest I'm not even sure what questions to ask being a Crystal n00b.
What I'm really after is the data from Table A, the data from Table B and children tables. While they are logically linked and can be linked with the ID field, it isn't necessary I don't think because I am taking a parameter value for the report of the ID field. And once the tables are filtered, no other action needs to be taken except to dump them back on the report.
So can anybody point me in the right direction? Can I set up individual datasoruces (unrelated) based perhaps in a seperate section? Should I build a tree of queries and logic in my DB to get what I need out? I've been racking my brain and can't seem to find the right solution, any and all advice is apreciated and if I can clarify anything or answer any questions I will.
Thanks in advance.
As per requested below:
Section1
ID fname lname
01 john smith
Section2
ID notifiedDate notifiedTime
01 10/10/2012 12:35PM
S2childAdmin
ID noteName
01 jane doe
This data is logically related and can be related in the DB. However it is not necessary as long as the ID parameter is passed to each table. Querying Section1 inner joined with Section2 works fine. But any other arrangements result in more rows than required and I end up with a report many times duplicated. What I really need is something like Section1 joined with Section2 and S2childAdmin as a freely availble table. Otherwise it multiplies my data or results in a null recordset (because it can return 0 rows)
I think this should help point you in the right direction, though it has been 5 years or so since I did heavy Crystal Reports work.
One option might be to join everything using Outer Joins like you stated you were, then use a Crystal Report 'group' on the Table A ID, with a group based upon Table B ID inside of that. So you would, in the actual 'Detail' area put your table C details if there were any, and then use the Group header/footer for Table A and Table B to show data specific to those objects.
Another possible solution that may fall short of your requirements but might get you thinking in another way, is to create your main report and in it, display the fields from table A. Then below those fields include a sub-report and pass in the unique ID from Table A. You will then have a query inside of the subreport that finds all of the Table B records with that Table A.ID value and displays their details.
At this point you run into a weakness of Crystal Reports (at least as of the last version I used) in that you cannot have a subreport inside of a subreport.
I am new to Asp.Net, MVC3, Linq, and everything else related to it. I'm very used to PHP and ColdFusion so pardon my ignorance! Essentially what I am trying to do is re-create the situation in ColdFusion where I can perform the equivalent of a cfoutput's group attribute. I'm so used to just calling a stored procedure and then doing
<cfoutput group="id">
and then another inner cfoutput for any columns that have non-distinct data. Works like a charm! Not so much in Asp.Net.
I would like to stay with using my stored procedure, which is returning a join from two tables with a one-to-many relationship. For example's sake let's say I have 3 columns: a full name, a title, and a graduation year. The graduation year is the column from the joined table, so my result from the stored procedure looks like this:
Jim Professor 2005
Jim Professor 2008
Jim Professor 2011
I am sending this to the View. I am assuming it's the View's job to then group the data based on one of the columns (probably the full name). I want to output an HTML table with 3 columns and in this situation I would have ONE row:
Jim Professor 2005, 2008, 2011
I have googled tons of examples that use this thing called a group key. This does not seem to help me because I'm not interested in just outputting one value "Jim" (or whatever the grouped value is), I need both "Jim" and "Professor" values to be output for each row. My thinking is I would need 2 foreach loops, the outer loop displaying the fullname and title and the inner loop going through all possible matches for the graduation years. I cannot seem to get the graduation years in a group, especially with this IGrouping syntax. The key can only store one value and I need every value on that row, I only really need one or two values to be iterated over. Should I try and create a custom view model after I perform a secondary linq grouping and then send that to a strongly typed view?
EDIT:
Ok, I have code that works but it seems very inefficient as I basically have to re-define all of the columns/values that I have from my stored procedure. It almost makes me want to forget stored procedures and just use LINQ for everything. It seems what I was asking for is a kind of "group on multiple columns" and link helped immensely.
var records = db.getRecords();
var groups = from r in records
group r by new
{
r.id
}
into row
select new ListVM()
{
id = row.Key.id,
fullname = row.Select(x => x.fullname).First(),
title = row.Select(x => x.title).First(),
degrees = row.Select(x => x.degree_name).ToList(),
majors = row.Select(x => x.major_name).ToList()
};
return View(groups);
I of course had to create a ViewModel for this to work. In my view then I can use for loops to iterate over the degrees and majors lists. Is this the best way to do this? I just generally need more than just the group key to display my entire row of information, and only want to iterate over lists once or twice in a 20 column row, as opposed to only displaying the group key once and iterating over everything in most examples I see.
I'm not that big specialist with Linq and MVC, but faced with your problem I would:
Deal with data preparation in controller/model, after being taught that view should be concerned with displaying things only.
I would use knowledge from these topics to solve your particular problem:
a) grouping by multiple columns:
Group By Multiple Columns
b) Concatenation as an aggregate function:
Using LINQ to concatenate strings
c) Using aggregates and grouping by multiple columns
How to write a LINQ query combining group by and aggregates?
Once you have data in your view model, just display it.
I believe I've finally found out how to solve what I was looking for. A "group join" seems to solve my problem with ease. The information I found on this page solved it: http://geekswithblogs.net/WillSmith/archive/2008/05/28/linq-joins-and-groupings.aspx
I'm new to programming, so bear with me as I try to explain what I"m needing to do. This is in ASP.net iwth VB. I have a quiz project that I've been assigned for work. This quiz project contains two main SQL Databases it pulls the info from.
First is a Quiz table, which contains three columns: QuizID (Pri Key), Title, Description. This is where I declare the quizzes, indicated by the QuizID (1, 2, 3....etc)
The second table is the Questions table, containing the following columns: QuestionsID (Pri Key), Title, Answer1, Answer2, Answer3, Answer4, Answer5, CorrectAnswer, QuestionOrder, QuizID
The QuizID in the Quesitons table matches the QuizID in the Quiz table. Thus for QuizID = 1, it consists of all the questions with the matching QuizID in the Questions table. The CorrectAnswer I want to assign a simple value (1, 2, 3...etc).
I need a way to take a set of questions (based on the QuizID) put them in some sort of table and randomize them (or rather shuffle them) so that each time this quiz is taken, it pulls all questions randomly, but not repeating any)
I then want the code to pull the question and coorepsonding answers to pick from in a radiobuttonlist. However, It only needs to pull the number of answers. Example, a True/False will only have Answer1 and Answer2. The other Answers will have the NULL value in it.
There needs to then be a way to go through each one of these questions that have been placed in the table (in that random order) using a "next" button. When a question and possible answwers are displayed, I alaready have code to keep the answers in the session to grade it at the end (using correctAnswer and selected answer.
I have no specific way to bind the data to the Database. I have used SQLDataSource to make other connections before, but I don't know if this is the best way.
Thanks in advance for any advice. As I said, I'm a noob, so providing all the code will be helpful.
Can you provide any sample code to demonstrate the approach that you wish to take. I am willing to help you learn and fix bugs, but I wont write all your code for you.