Dynamically change database due to WHERE MySQL Crystal Reports - mysql

I'm programming with .NET 4.5, VS 2012 with CrystalReports in and MySQL (the last ^^).
I have 3 or more tables named like "rp31_bla_2012_bla" or "rp31_bla_2013_bla" or ...
Imagine you have a table with this:
- Name - Age - Job - Year -
Robert - 45 - Doctor - 2001
Robert - 45 - Housemade- 2002
Robert - 45 - Geek - 2006
Robert - 45 - Cooker - 2009
Robert - 45 - (null) - 2013
Nadège - 21 - CallGirl - 2001
Nadège - 21 - (null) - 2002
Nadège - 21 - CallGirl - 2008
Nadège - 21 - Home - 2008
Now I have a WinForm with two textBox, if the user writes "Robert" and "2013" I have to make a report with the "rp31_bla_***2013***_bla" WHERE Name = Robert.
Is it possible?
Which type of report should I create?
How can I change dynamically the query?

You can use union to combine the 3 tables and filter by name
SELECT * FROM
(
SELECT ..., 2012 as Year FROM rp31_bla_2012_bla
UNION
SELECT ..., 2013 as Year FROM rp31_bla_2013_bla
UNION
SELECT ..., 2014 as Year FROM rp31_bla_2014_bla
) t
WHERE t.Year =2013 and t.Name ='Robert'
Since the datasource will never change you don't need to to switch the tables.
This approach will be slower because you will always query the 3 tables
Another option will be to use a command in Crystal reports and to create a dynamic query which will be executed using exec -then you will be able to query just one table but you will need to handle special characters in the name ( like '%?)

Related

MS access: Merging 02 tables into 01

I am using Microsoft Access database (Please don’t suggest me to use some other database since I donot have that choice in this particular situation).
I have 02 tables as below.
Table 1: Purchase Order
PO_No, Item_No, Order_Qty
01 a 10
01 b 5
02 a 8
02 b 2
Table 2: Stock
Item_No, Batch_No, Qty
a 0001 5
a 0002 50
b 0003 10
=> I would like to create something like this:
Item_No, Batch_No, Ship_Qty, PO_No
a 0001 5 01
a 0002 5 01
a 0002 8 02
b 0003 5 01
b 0003 2 02
Please help!
EDIT: Make-Table Example
You still need to read through at least some of the links that I posted earlier but I don't think you we getting what I meant so here's an animation to show you the steps.
Create Select Query from the 2 tables
Test Select Query to make sure output is what you want in new table
Convert Select Query to Make Table Query
Execute Make Table Query
This is a very short process, just a few minutes.
Good Luck.
STEP 1:
First you need to create a Select Query using both of your tables, joined together, similar to this: (See the tutorials at the bottom of this answer.)
STEP 2:
Once the Select Query is producing the data how you want it organized, you can convert it to a Make Table query:
Tutorials:
Skillshare : Intro to Access - Microsoft Access Basics for Beginners
Microsoft.com : Introduction to Queries: Access
YouTube : Acccess 2016: Multi-table queries
Office.com : Join tables and queries
Microsoft.com : Create a make-table query
Well kudos to ashleedawg for that effort.
In the end - your very first step must be to make a select query that will result in the records/fields correctly of what will be the new table.
The second step is then to make a Make Table Query. But that can wait for now.
In glancing at your 2 source tables, and the resulting 3rd table you seek - - I did not see any join logic that would create that result. If you can explain what is the logic - - then help with that select query can be provided.

Fill in the missing values in a column determined by the column itself and date

I have a subscription table looks like the following.
There are about 1 million unique IDs.
The table lists subscription status when user began subscription service as indicated by 'Sub' and when it unsubscribed as indicated by 'Usub'.
ID Year Month Status
A 2014 1
A 2014 2
A 2014 3
A 2014 4 Sub
A 2014 5
A 2014 6
A 2014 7
A 2014 8 Usub
A 2014 9
A 2014 10
A 2014 11
A 2014 12
B 2014 1
B 2014 2
B 2014 3
B 2014 4
B 2014 5 Usub
B 2014 6
B 2014 7
B 2014 8
B 2014 9 Sub
B 2014 10
B 2014 11
B 2014 12
. . . .
. . . .
. . . .
I am looking to fill in the gap between each status updates.
The desired output table would look like the following:
ID Year Month Status
A 2014 1 Usub
A 2014 2 Usub
A 2014 3 Usub
A 2014 4 Sub
A 2014 5 Sub
A 2014 6 Sub
A 2014 7 Sub
A 2014 8 Usub
A 2014 9 Usub
A 2014 10 Usub
A 2014 11 Usub
A 2014 12 Usub
B 2014 1 Sub
B 2014 2 Sub
B 2014 3 Sub
B 2014 4 Sub
B 2014 5 Usub
B 2014 6 Usub
B 2014 7 Usub
B 2014 8 Usub
B 2014 9 Sub
B 2014 10 Sub
B 2014 11 Sub
B 2014 12 Sub
. . . .
. . . .
. . . .
Although the first table shows both users have more than one status change, any given ID does not necessarily have more than one status change. However, each ID will have at least one status. ie. a user subscribed on 2014/8 and never unsubscribed will have status= Sub on 2014/8.
You can do that with procedural code, reading the data in order, and using a variable to store the "state" of the previous record (with a reset on each new ID).But SQL is not procedural.
So what kind of procedural wrapper can we get for a standard single-node database (e.g. MySQL) and for a distributed system (e.g. Hive)?
MySQL has a stored procedure language that supports cursors to
iterate on rows from a SELECT query (Google will get you a large number of tutorials like this one taken at random)
Hive 2.0 also has a kind of procedural language extension, but it's
not part of Hive itself -- you must run your procedural script in a
specific tool (and not everyone has Hive 2.0 anyway) -- also, Hive runs distributed queries on a distributed file system, so "shuffling" all the rows on a single client node then iterating with a single-threaded tool sounds very clumsy -- investigate at your own risk
Hive also has a complicated and cumbersome way to run arbitrary procedural code in a distributed way (in each Mapper or each Reducer), with the TRANSFORMclause (a Hive traduction of the legacy and poorly-named "Hadoop streaming" feature); unfortunately the documentation is cryptic (you'd better get a good old book e.g. "Programming Hive" from O'Reilly) and when you finally can make it work, well, the performance drop is significant
or, you may develop a custom Hive UDF in Java with a little twist -- i.e. storing the state from previous row in Java variables and using it
for the current row
Now, what kind of procedural logic do you need to implement in your custom query and custom code?
first, you need the input query to SORT BY key, date
with a Hive TRANSFORM or a Hive UDF, you also need to DISTRIBUTE BY key so that every key has its history processed as a whole, in a single node (otherwise the results would make absolutely no sense!)
define 2 variables for "PreviousRowKey" and "PreviousRowState"
on 1st row, or on change of Key, then "PreviousRowState = Usub" and "PreviousRowKey = currentKey"
on change of State then "PreviousRowState = currentState" else force "currentState = PreviousRowState"

Add variance in the rows of table

I've a SSRS report which should look like below,
--------------------------------
Year Product Total customers
--------------------------------
2015 prd1 100
prd2 50
prd3 60
2014 prd1 80
prd2 60
prd3 60
Varience
Prd1 20
Prd2 -10
Prd3 0
I've done the year wise grouping and the data mapping. But I'm not sure how to add variance(between 2015-2014) in each row based on the each product of the year
Update:
My dataset looks like this
Year CategoryId CategoryDesc TotalCustomerCount
2013 Prd1 Testproduct 100
2013 Prd2 Testprod2 50
2013 Prd3 Tesrprod3 45
2014 Prd1 Testproduct 80
2014 Prd2 Testprod2 60
You can see that some products may miss out in a year.
Note: The dataset is created from a Dimesional cube and not from SQL queries.
It is kind of hard to tell exactly without knowing what your current dataset looks like.
But I believe that Stanislovas' example will be of little use to you because his example only works if your dataset has a single row for each product, with columns with the total for each year. Which I'm guessing you do not have because you used row grouping to get the above result. If you did, you could've used column-grouping instead of row-grouping to get a better overview.
You have two possibilities:
Replace your current dataset completely with a dataset that has columns for each year value (like in Stanislovas' example). To achieve this kind of dataset you need your query to look like this for example:
SELECT DISTINCT(myTable.Product), t1.Total AS 'Total2014', t2.Total AS 'Total2015'
FROM myTable
JOIN (SELECT Product, SUM(Total) AS Total
FROM myTable
WHERE Year = 2014
GROUP BY Product) as t1 ON t1.Product = myTable.Product
JOIN (SELECT Product, SUM(Total) AS Total
FROM myTable
WHERE Year = 2015
GROUP BY Product) as t2 ON t2.Product = myTabel.Product
This can then be used to make a table that looks like this:
---------------------------------------
| Product | 2014 | 2015 | Variance |
---------------------------------------
| prd1 | 100 | 80 | 20 |
| prd2 | 50 | 60 | -10 |
| prd3 | 60 | 60 | 0 |
...
Or you can add a second datasource that has calculated these differences before sending it to the reporter. Here is an example to help you with your query: https://stackoverflow.com/a/15002915/4579864
If you need any more help, just leave a comment and I'll try and explain furthur. This should at least get you started.
I think the easiest way to handle this requeriment is generating the data from the query using T-SQL. However the output you require can be produced from SSRS using a dataset with the same structure as the dataset you provided in the update.
In order to recreate your scenario I used this dataset.
Year Product CategoryDesc TotalCustomerCount
2013 Prd1 Testproduct 100
2013 Prd2 Testprod2 50
2013 Prd3 Tesrprod3 45
2014 Prd1 Testproduct 80
2014 Prd2 Testprod2 60
My approach is take the minimum and maximum year values (2013 and 2014) and the product in every row and look up the TotalCustomerCount to substract it. This is a step by step guide.
First, create a calculated field in your dataset. Right click the dataset in Report Data pane, call it Year_Product and set this expression in the field source textbox.
=Fields!Year.Value & "-" & Fields!Product.Value
This will produce an additional field called Year_Product which has Year and Product fields concatenated with the - character in middle. In example: 2013-Prd1, 2014-Prd1, 2013-Prd3 etc.
Now create a tablix with this data arrangement:
In the cell highlighted in red use this expression:
=Lookup(Max(Fields!Year.Value,"DataSet13") & "-" &
Fields!Product.Value,Fields!Year_Product.Value,Fields!TotalCustomerCount.Value,"DataSet13")
-
Lookup(Min(Fields!Year.Value,"DataSet13") & "-" &
Fields!Product.Value,Fields!Year_Product.Value,Fields!TotalCustomerCount.Value,"DataSet13")
This will look up the max year and product of the row in the Year_Product field and get the TotalCustomerCount.
Year_Product: 2014-Prd1 and TotalCustomerCount: 80
Year_Product: 2013-Prd1 and TotalCustomerCount 100
The above example produces -20 since 80 - 100 = -20
It will show us repeated products because every product may be present two times. To avoid this it is necessary to sort the tablix by Product, go to tablix properties and set the below sorting option.
Now hide duplicated rows. Go to tablix properties / Row visibility and select Show or hide based on an expression.
Use this expression ton conditionally hide the duplicated products:
=IIF(
Fields!Product.Value=PREVIOUS(Fields!Product.Value),
true,
false
)
Finally if you preview the report you will see something like this (I recreated your both tables.)
Note I am using only one dataset, the same that you provide in your
question.
Hopefully this what you are looking for let me know if you need further help.

Counting rows from Where Clause and display every count in a different column

Hi I have a MySql Query as follows:
Select Count(*),status,time from table where Status in (2,3,8) group by status,time
The Output is ok i get something like
Count Status time
10 - 1 - 2014
10 - 2 - 2014
19 - 1 - 2015
11 - 2 - 2015
But what i would like to have is something like
Count of Status1 - Count of Status2 - Time
10 - 10 - 2014
19 - 11 - 2015
Is there a nice and efficient way to do since since my database has about 1 mio records. I want to use this data to show it in a table without further manipulation.
Thanks in advance
The following should work:
SELECT SUM(IF(`Status` = 1,1,0) ) CountOfStatus1,SUM(IF(`Status` = 2,1,0) ) CountOfStatus2,TIME FROM TABLE WHERE STATUS IN (1,2) GROUP BY TIME
You will need to adjust it for whatever statuses you want to see.

Create Report with dynamic columns

I have SQL Server 2005 Reporting Services. I need to create a report with number of columns that is defined during runtime.
I have a DB table with content like the following:
Person Date Val
----------------------------------------------
Person1 2012-01-03 3
Person2 2012-02-11 5
Person1 2012-02-17 7
Person2 2012-01-19 2
Person2 2012-01-15 4
I have to create a Report like this:
Person Jan 2012 Feb 2012
----------------------------------------------
Person1 3 7
Person2 6 5
In other words, for every Person I have to make sum of all his Value fields for a given month, and put the sum into column corresponding to the month. In the example above I have 6 for Person2 during month Jan 2012 - this is sum of the values 2 (on 2012-01-19) and 4 (on 2012-01-15).
Thus, in design time I do not know the date range covered by that my table. I should detect it, to build array of months covered by the date range (the Jan 2012 and Feb 2012 in the sampel above) and add a column for each of the months.
How should I implement this using SSRS?
In SQL 2008 and later the approach to this problem changed a little bit, so make sure that you are looking at reference materials for 2005 if that is what you are using.
On this page, look for the Matrix section. Matrices in SSRS are designed to solve exactly the problem you describe with minimal effort. In 2008 Matrices and Tables are both variants of the "Tablix:" a control that can have both row and column groups.
If you're stuck with Tablix, here's a similar situation that I have solved, How do i represent an unknown number of columns in SSRS?.