How to merge two SQL queries in VBA with one similar column? - mysql

I have two SQL tables (table1 and table2), one of which contains dates for each day (column [dte_Date]) and the according level of an index (like the S&P 500) (column [flt_Close]), the other contains dates for each day (column [dte_ReportDate]) and the according prices for a product (column ([flt_Price]). I would like to make a VBA macro with two queries and then display in a Worksheet three columns :
DATE - LEVEL of the INDEX - Price of the PRODUCT
... - ... - ...
and so on. Unfortunately, the two tables don't always have the same dates so I can not write the first table and then fill the last column with the price of the product because the dates don't necessarily match.
So, how to make sure that I correctly fill the worksheet (if for one date there is only one value, then I want to display it and display "0" or "No value" for the other column) ?
Here is how the table look (table1) :
[dte_Date] ... [flt_Close]
2015-01-01 ... 2000
2015-01-02 ... 2010
2015-01-03 ... 2020
and (table2) :
[dte_ReportDate] ... [flt_Price]
2015-01-01 ... 10
2015-01-03 ... 11
and that would be the result I would like to have in my Excel worksheet:
DATE ... Close ... Price
01/01/15 2000 10
01/02/15 2010 No value (or 0)
01/03/15 2020 11

Related

Average of MS SSRS Tablix group totals

I have a SQL Server Report Builder tablix report that evaluates sales activity over time.
Rows by company, columns are grouped by date. Something like this:
2015 2016 2017
Company1 10 12 1
Company2 6 5 0
Company3 8 10 7
(The report also expands columns into months)
I would like to add a column, or color a background, calculated based on the average of each year's totals. For example, Company1 averages 7.6/year if I include 2017. I would like to be able to say that 2015 was 131% of average, 2016 was 157% of average, and 2017 is 13% of average. Bonus points if I can exclude the current year from the average.
The result might look something like this:
2015 2016 2017
Company1 10 (131%) 12 (157%) 1 (7.6%)
Company2 6 (%%) 5 (%%) 0 (%%)
Company3 8 (%%) 10 (%%) 7 (%%)
Since the source data has one sale per row, and the tablix is what's creating the grouped count by date, I can't seem to just run an average, which just gives me "1", due to the fact that I'm counting on a count column. The source data looks something like this:
CompanyName Date SalesRep Amt Count
Company1, 1/1/2015, salesrepname, 50000, 1
Company1, 2/1/2015, salesrepname, 20000, 1
Company1, 3/1/2015, salesrepname, 50000, 1
Company1, 4/1/2015, salesrepname, 10000, 1
Company1, 5/1/2015, salesrepname, 5000, 1
...
How do I go about getting the average of each year?
If you were just grouping on Company and Year you could override the scope of your aggregates with a group name. However, SSRS doesn't have a way to specify combinations of groups. So in your case you will need to make those sub-calculations available another way. It is usually best to do that in the SQL. You can either add a subquery to your existing query (preferred) or add an additional dataset. If you use a separate dataset you'll also have to match up the values with a Lookup function.
If you try to come up with an elaborate workaround like custom code or referencing textboxes it is going to become difficult to maintain and will be very inefficient.
wouldn't a formula like this work?
=sum(Fields!count.Value)/
(sum(Fields!count.Value,"Year")/countdistinct(Fields!CompanyName.Value,"Year"))
assuming your column group name is Year.

Spotfire intersect first 'n' periods

Is there a way to use an Over and Intersect function to get the average sales for the first 3 periods (not always consecutive months, sometimes a month is skipped) for each Employee?
For example:
EmpID 1 is 71.67 ((80 + 60 + 75)/3) despite skipping "3/1/2007"
EmpID 3 is 250 ((350 + 250 + 150)/3).
I'm not sure how EmpID 2 would work because there are just two data points.
I've used a work-around by calculated column using DenseRank over Date, "asc", EmpID and then used another Boolean calculated column where DenseRank column name is <= 3, then used Over functions over the Boolean=TRUE column but I want to figure the correct way to do this.
There are Last 'n' Period functions but I haven't seen anything resembling a First 'n' Period function.
EmpID Date Sales
1 1/1/2007 80
1 2/1/2007 60
1 4/1/2007 75
1 5/1/2007 30
1 9/1/2007 100
2 2/1/2007 200
2 3/1/2007 100
3 12/1/2006 350
3 1/1/2007 250
3 3/1/2007 150
3 4/1/2007 275
3 8/1/2007 375
3 9/1/2007 475
3 10/1/2007 300
3 12/1/2007 200
I suppose the solution depends on where you want this data represented, but here is one example
If((Rank([Date],"asc",[EmpID])<=3) and (Max(Rank([Date],"asc",[EmpID])) OVER ([EmpID])>=3),Avg([Sales]) over ([EmpID]))
You can insert this as a calculated column and it will give you what you want (assuming your data is sorted by date when imported).
You may want to see the row numbering, and in that case insert this as a calculated column as well and name it RN
Rank([Date],"asc",[EmpID])
Explanation
Rank([Date],"asc",[EmpID])
This part of the function is basically applying a row number (labeled as RN in the results below) to each EmpID grouping.
Rank([Date],"asc",[EmpID])<=3
This is how we are taking the top 3 rows regardless if Months are skipped. If your data isn't sorted, we'd have to create one additional calculated column but the same logic applies.
(Max(Rank([Date],"asc",[EmpID])) OVER ([EmpID])>=3)
This is where we are basically ignoring EmpID = 2, or any EmpID who doesn't have at least 3 rows. Removing this would give you the average (dynamically) for each EmpID based on their first 1, 2, or 3 months respectively.
Avg([Sales]) over ([EmpID])
Now that our data is limited to the rows we care about, just take the average for each EmpID.
#Chris- Here is the solution I came up with
Step 1: Inserted a calculated column 'rank' with the expression below
DenseRank([Date],"asc",[EmpID])
Step 2: Created a cross table visualization from the data table and limited data with the expression below

SSIS fuzzy lookup (lookup agains valid range of values)

I was wondering if anyone had a good solution to trying lookup a value against a range of values in a fuzzy lookup transformation.
By "range of values" I mean either a date range such as start and end dates in the lookup table or comparison range such as a high and low value of house numbers compared to the exact house number in a record.
Or if there is solution how to solve fuzzy lookup against only valid values by condtion.
Iam using ssis 2008
Example:
My sales data example:
ID Product Quatity date
1 Product1 1 1.2.2015
2 Produc?t1 1 1.2.2015
3 Produt1_ 1 10.7.2015
My price list
ID Name Price ValidFrom ValidTO
1 Product1 10 1.1.2015 28.2.2015
2 Product1 11 1.3.2015 null
My sales data are kind of dirty (sources are various) - that's why I want to use FUZZY lookup.
I want to fuzzky lookup againts my price list but only against valid prices.
So after lookup result should look like this
ID Product Quatity date Price
1 Product1 1 1.2.2015 10
2 Produc?t1 1 1.2.2015 10
3 Produt1_ 1 10.7.2015 11
But if I use fuzzy I cannot specify the condition before I use fuzzy lookup.
Thanks in advance,
Martin

To calculate sum of the fields in a matrix with column grouping

I am working on a ssrs report with column grouping. the followin is my scenario.
Matrix 1:
ID 2012 2013
1 20 40
1 30 50
Total 50 90
Matrix 2:
ID 2012 2013
1 60 70
1 60 80
Total 120 150
I need the sum of matrix1 and matrix2 like below:
ID 2012 2013
1 170 240
But I got the result like :
ID 2012 2013
1 410 410
I have applied column grouping in all the 3 matrices and gave the expression to get sum for matrix 3 as: =Sum(Fields!amount1.Value, "dsmatrix1") + Sum(Fields!Tamount1.Value, "dsmatrix2")
Please help me to get a solution for this.
Thanks!
I think I know what's going on. Correct me if I'm wrong.
Based on what I'm seeing, I'm guessing that Matrix 1 and Matrix 2 only have three fields each, an ID field, an amount field (being "amount1" or "Tamount1"), and a year field.
Your column grouping is manipulating the display of the data to show all values broken out by year. This works fine when looking at data from a single dataset. However, your formula is specifying that the sum of everything in the Amount1 field of dsmatrix1 and the Tamount1 field of dsmatrix2 should be added. This does not take into account the column grouping. Your expression is essentially taking all of the values from both datasets and adding them together.
Not knowing more about your query structure or how the data is filtered, my best guess is that you need another SQL dataset. In this case, you would take the queries from your two previous datasets and union them with the "Union All" command. Note that you will want to use Union All and not just Union. More on that here: What is the difference between UNION and UNION ALL?
Your end result should look something like this:
--This will be your dsmatrix1 query copied and pasted
Select ...
Union All
--This will be your dsmatrix2 query copied and pasted
Select ...
--Place one single Order by clause at the bottom
Order by ...
Note: for your two queries to be unioned properly, you'll need to make sure that each have the same number of fields, each with the same data types. Then you can point your third matrix to the new dataset.
Hope that helps!

MS Access: Using Single form to enter query parameters in MS access

compliment of the day.
Based on the previous feedback received,
After creating a Ticket sales database in MS Access. I want to use a single form to Query the price of a particular ticket at a particular month and have the price displayed back in the form in a text field or label.
Below are sample tables and used query
CompanyTable
CompID CompName
A Ann
B Bahn
C Can
KK Seven
- --
TicketTable
TicketCode TicketDes
10 Two people
11 Monthly
12 Weekend
14 Daily
TicketPriceTable
ID TicketCode Price ValidFrom
1 10 $35.50 8/1/2010
2 10 $38.50 8/1/2011
3 11 $20.50 8/1/2010
4 11 $25.00 11/1/2011
5 12 $50.50 12/1/2010
6 12 $60.50 1/1/2011
7 14 $15.50 2/1/2010
8 14 $19.00 3/1/2011
9 10 $40.50 4/1/2012
Used query:
SELECT TicketPriceTable.Price
FROM TicketPriceTable
WHERE (((TicketPriceTable.ValidFrom)=[DATE01]) AND ((TicketPriceTable.TicketCode)=[TCODE01]));
In MS Access, a mini boxes pops up to enter the parameters when running the query. How can I use a single form to enter the parameters for [DATE01] and [TCODE01]. and the price displayed in the same form in a textfield (For further calculations).
Such as 'Month' field equals to input to [DATE01] parameter
'Ticket Code' equals to input for [TCODE01] parameter
Textfield equals to output of the query result (Ticket price)
If possible, I would like to use only the Month and Year in this format MM/YYYY.The day is not necessarry. How can I achieve it in MS Access?
If any question, please don't hesitate to ask
Thanks very much for your time and anticipated feedback.
You can refer to the values in the form fields by using expressions like: [Forms]![NameOfTheForm]![NameOfTheField]
Entering up to 300 different types of tickets
Answer to your comment referring to Accessing data from a ticket database, based on months in MS Access)
You can use Cartesian products to create a lot of records. If you select two tables in a query but do not join them, the result is a Cartesian product, which means that every record from one table is combined with every record from the other.
Let's add a new table called MonthTable
MonthNr MonthName
1 January
2 February
3 March
... ...
Now if you combine this table containing 12 records with your TicketTable containing 4 records, you will get a result containing 48 records
SELECT M.MonthNr, M.MonthName, T.TicketCode, T.TicketDes
FROM MonthTable M, TicketTable T
ORDER BY M.MonthNr, T.TicketCode
You get something like this
MonthNr MonthName TicketCode TicketDes
1 January 10 Two people
1 January 11 Monthly
1 January 12 Weekend
1 January 14 Daily
2 February 10 Two people
2 February 11 Monthly
2 February 12 Weekend
2 February 14 Daily
3 March 10 Two people
3 March 11 Monthly
3 March 12 Weekend
3 March 14 Daily
... ... ... ...
You can also get the price actually valid for a ticket type like this
SELECT TicketCode, Price, ActualPeriod AS ValidFrom
FROM (SELECT TicketCode, MAX(ValidFrom) AS ActualPeriod
FROM TicketPriceTable
WHERE ValidFrom <= Date
GROUP BY TicketCode) X
INNER JOIN TicketPriceTable T
ON X.TicketCode = T.TicketCode AND X.ActualPeriod=T.ValidFrom
The WHERE ValidFrom <= Date is in case that you entered future prices.
Here the subquery selects the actually valid period, i.e. the ValidFrom that applies for each TicketCode. If you find sub-selects a bit confusing, you can also store them as query in Access or as view in MySQL and base a subsequent query on them. This has the advantage that you can create them in the query designer.
Consider not creating all your 300 records physically, but just getting them dynamically from a Cartesian product.
I let you put all the pieces together now.
In Access Forms you can set the RecordSource to be a query, not only a table. This can be either the name of a stored query or a SQL statement. This allows you to have controls bound to different tables through this query.
You can also place subforms on the main form that are bound to other tables than the main form.
You can also display the result of an expression in a TextBox by setting the ControlSource to an expression by starting with an equal sign
=DLookUp("Price", "TicketPriceTable", "TicketCode=" & Me!cboTicketCode.Value)
You can set the Format of a TextBox to MM\/yyyy or use the format function
s = Format$(Now, "MM\/yyyy")