I have the following table of data from an MDX query that resembles the following:
Account | Location | Type | Person | Amount
ABC | XYZ | AA | Tom | 10
ABC | XYZ | AA | Dick | 20
ABC | XYZ | AA | Harry | 30
ABC | XYZ | BB | Jane | 50
ABC | XYZ | BB | Ash | 100
DEF | SDQ | ZA | Bob | 20
DEF | SDQ | ZA | Kate | 10
DEF | LAO | PA | Olivia | 200
DEF | LAO | PA | Hugh | 120
And I need to add the Amount column for each Account, Location, and Type. If I was using SQL I would perform a query on this data as follows:
Select Account, Location, Type, Sum(Amount) as SumAmmount
From Table
Group By Account, Location, Type
but due to the way we store the data I need to roll-up this data using SSRS. To do that I created a tablix, created a parent group (Which I have called "RollUp") of the default detail group which grouped on Account, Location, and Type and then deleted the detail group so when running the report I get:
Account | Location | Type | Amount
ABC | XYZ | AA | 60
ABC | XYZ | BB | 150
DEF | SDQ | ZA | 30
DEF | LAO | PA | 320
What I need to do now is create a page break so that when I export this SSRS report to excel there are only 1000 rows on each sheet, but I am having trouble writing the expression to split this every 1000 rows. Because I have removed the details group I cannot use the typical expression I would use to page break on a specific row of a dataset (e.g. Group Expression = Floor(RowNumber(NOTHING) / 1000) )
I have tried a few different things like writing some custom code and some running value expressions but haven't been able to figure it out yet.
I did figure out how to do this.
First I created the following custom code in the report definition:
Dim GroupingDummy = "GroupDummy"
Dim RowNumberToReturn = -1
Function PopulateRowNumber(GroupString As String) As Integer
If (GroupString <> GroupingDummy ) Then
GroupingDummy = GroupString
RowNumberToReturn = RowNumberToReturn + 1
End If
Return RowNumberToReturn
End Function
Keeping in mind the grouping I applied to the dataset used the fields Account, Location, and Type, I added a calculated field to my dataset with the name RowNumberCalc and the expression:
=Code.RowNumberToReturn(Fields!Account.Value + Fields!Location.Value + Fields!Type.Value)
Now I could easily create the group that would create a page break at 1000 rows with the expression :
=Floor(Fields!RowNumberCalc.Value / 1000)
Related
I am using the PATSTAT database to select the APPLN_ID of patent applications that have a cpc classification symbol but not another. I need to do this in order to retrieve a control dataset of patents to verify my hypothesis.
PATSTAT is a relational database where each patent application has a set of attributes. The TLS224 table contains multiple rows with the same APPLN_ID and different CPC symbols. I want to retrieve the APPLN_IDs that have a set of symbols A but that do not have a set of symbols B.
From this example data
| APPLN_ID | CPC_CLASS_SYMBOL |
| 2345 | C07K 16/26 |
| 2345 | C07K2317/34 |
| 2345 | C07K2317/76 |
| 2345 | G01N 33/74 |
| 2345 | B01L 9/527 |
| 1000 | C07K2317/34 |
| 1000 | C07K 16/26 |
| 1000 | C07K2317/76 |
| 1000 | B01L 3/5025 |
| 9999 | B01L 3/5025 |
| 9999 | G01N2333/47 |
| 9999 | G01N2333/4727 |
I want to obtain this as a result.
| APPLN_ID |
| 1000 |
Here, the set of values A that must be included are 'C07K 16/26' ,'C07K2317/34', 'C07K2317/76', while the value B that must NOT be present is G01N 33/74.
How can I do that?
This is what I came out with so far (I know that the WHERE IN and NOT IN clauses nullify each other, but it is just to show an example).
SELECT DISTINCT p2.APPLN_ID
FROM (SELECT p1.APPLN_ID, p1.PUBLN_AUTH, YEAR(p1.PUBLN_DATE)
FROM TLS211_PAT_PUBLN p1
WHERE YEAR(p1.PUBLN_DATE) = 2008
AND PUBLN_AUTH = 'WO') p2
JOIN (SELECT DISTINCT cpc3.APPLN_ID
FROM TLS224_APPLN_CPC cpc3
WHERE cpc3.APPLN_ID IN
(SELECT APPLN_ID
FROM TLS224_APPLN_CPC
WHERE CPC_CLASS_SYMBOL NOT IN ('G01N 33/74'))
AND cpc3.APPLN_ID IN
(SELECT APPLN_ID
FROM TLS224_APPLN_CPC
WHERE CPC_CLASS_SYMBOL IN ('C07K 16/26', 'C07K2317/34', 'C07K2317/76'))
) cpc1
ON cpc1.APPLN_ID = p2.APPLN_ID
I am still a newbie to SQL so any help is appreciated!
Thank you
your IN and NOT IN doesn't make sense.
if CPC_CLASS_SYMBOL are in the first Group they are automatocally NOT IN your second
Your WHERE clause would only give you APPLN_ID (and some more) the have these symbols and everything else is excluded.
I have a database of units which have expiry dates. Some of the units are top level units and have sub-assemblies attached. Sub-assemblies also have expiry dates. I'm trying to create a listing that lists the top-level units ordered by their expiration dates and list all relevant sub-assemblies under them.
The ordering should be done in two different ways:
Query which lists top-level units and their sub-assemblies according to expiry date of the parent item.
Query which lists top-level units and their sub-assemblies ordered by the first expiry date of relevant sub-assembly under them.
Here's example of the master table:
ITEM | NAME | UID | INSTALLED_TO_UID | EXPIRY
AAA | Top_level_unit_1 | 1 | | 2018-03-06
BBB | Sub_assy_1 | 75 | 1 | 2019-06-11
AAA | Top_level_unit_2 | 2 | | 2018-08-12
CCC | Sub_assy_2 | 26 | 1 | 2020-02-05
DDD | Sub_assy_3 | 59 | 2 | 2019-11-11
EEE | Sub_assy_4 | 41 | 2 | 2019-10-30
FFF | Sub_assy_5 | 11 | 1 | 2018-04-10
I am running these now in nested queries (second query inside foreach loop), but i am sure there is better and more efficient way of doing this. At least for case 1.
SELECT *
FROM master
WHERE ITEM = AAA
ORDER
BY EXPIRY ASC
And inside result loop for each result:
SELECT *
FROM master
WHERE INSTALLED_TO_UID = (UID from parent query)
The result should be like:
ITEM | NAME | UID | INSTALLED_TO_UID | EXPIRY
AAA | Top_level_unit_1 | 1 | | 2018-03-06
BBB | Sub_assy_1 | 75 | 1 | 2019-06-11
CCC | Sub_assy_2 | 26 | 1 | 2020-02-05
FFF | Sub_assy_5 | 11 | 1 | 2018-04-10
AAA | Top_level_unit_2 | 2 | | 2018-08-12
DDD | Sub_assy_3 | 59 | 2 | 2019-11-11
EEE | Sub_assy_4 | 41 | 2 | 2019-10-30
For case 2 i don't have a clue yet...
Summary: I would like to have only one query to group and order the results instead of relying to another query in result loop. Secondly i would like to figure out a query to order the results by first expiring child item grouped by parent items
You need to use an outer self join to find the parent record (for query 1) or the first-of-children record (for query 2). Then you can use coalesce to decide which value to take (either from the joined table or the main one) for setting the order.
Query 1:
SELECT record.*
FROM master record
LEFT JOIN master parent
ON record.installed_to_uid = parent.uid
AND parent.installed_to_uid is null
ORDER BY COALESCE(parent.expiry, record.expiry),
COALESCE(parent.uid, record.uid),
COALESCE(record.installed_to_uid,-1),
record.expiry
Query 2:
SELECT record.*
FROM master record
LEFT JOIN (SELECT installed_to_uid, MIN(expiry) expiry
FROM master
WHERE installed_to_uid IS NOT NULL
GROUP BY installed_to_uid) first
ON COALESCE(record.installed_to_uid, record.uid) = first.installed_to_uid
ORDER BY COALESCE(first.expiry, record.expiry),
COALESCE(first.installed_to_uid, record.uid),
COALESCE(record.installed_to_uid,-1),
record.expiry
See it run on sqlfiddle
Although there are surely more efficient solutions, why not start with this:
SELECT *
FROM master
WHERE INSTALLED_TO_UID = (
SELECT UID
FROM master
WHERE ITEM = AAA
)
?
I have a data set with this structure:
ContractNumber | MonthlyPayment | Duration | StartDate | EndDate
One contract number can occur many times as this data set is a consolidation of different reports with the same structure.
Now I want to filter / find the contract numbers in which MonthlyPayment and/or Duration and/or StartDate and/or EndDate differ.
Example (note that Contract Number is not a Primary key):
ContractNumber | MonthlyPayment | Duration | StartDate | EndDate
001 | 500 | 12 | 01.01.2015 | 31.12.2015
001 | 500 | 12 | 01.01.2015 | 31.12.2015
001 | 500 | 12 | 01.01.2015 | 31.12.2015
002 | 1500 | 24 | 01.01.2014 | 31.12.2017
002 | 1500 | 24 | 01.01.2014 | 31.12.2017
002 | 1500 | 24 | 01.01.2014 | 31.12.2018
With this sample data set, I would need to retrieve 002 with a specific query. 001 is the the same and does not Change, but 002 changes over time.
Besides of writing a VBA script running over an Excel, I don't have any solid idea on how to solve this with SQL
My first idea would be a SQL Approach with grouping, where same values are grouped together, but not the different ones. I am currently experimenting on this one. My attempt is currently:
1.) Have the usual table
2.) Create a second table / query with this structure:
ContractNumber | AVG(MonthlyPayment) | AVG(Duration) | AVG(StartDate) | AVG(EndDate)
Which I created with Grouping.
E.G.
Table 1.)
ContractNumber | MonthlyPayment
1 | 10
1 | 10
1 | 20
2 | 300
2 | 300
2 | 300
Table 2.)
ContractNumber | AVG(MonthlyPayment)
1 | 13.3
2 | 300
3) Now I want to find the distinct contract number where - in this example only the MonthlyPayment - does not equal to the average (it should be the same - otherwise we have a variation which I need to find).
Do you have any idea how I could solve this? I would otherwise start writing a VBA or Python script. I have the data set in CSV, so for now I could also do it with MySQL, Power Bi or Excel.
I need to perform this Analysis once, so I would not Need a full approach, so the queries can be splitted into different steps.
Very appreciated! Thank you very much.
To find all contract numbers with differences, use:
select ContractNumber
from
(
select distinct ContractNumber, MonthlyPayment , Duration , StartDate , EndDate
from MyTable
) x
group by ContractNumber
having count(*) >1
I'm a MySQL newbie, but I'm sure there must be a way to do this. I've been looking through StackOverflow for quite a while, though, and haven't found it yet.
I have a MySQL table that is generated from a multi-reducer Hadoop MapReduce job which is analyzing log files. The table is being used in the database that supports a Ruby-on-Rails app, and it looks like this:
+----+-----+------+---------+-----------+
| id | src | dest | time | requests |
+----+-----+------+---------+-----------+
| 0 | abc | xyz | 1000000 | 200000000 |
| 1 | def | uvw | 10 | 300 |
| 2 | abc | xyz | 100000 | 200000 |
| 3 | def | xyz | 1000 | 40000 |
| 4 | abc | uvw | 100 | 5000 |
| 5 | def | xyz | 10000 | 100000 |
+----+-----+------+---------+-----------+
I'm trying to coalesce/sum the columns which have the same src and dest, but I just can't figure out how to do it even after searching through the MySQL 5.1 documentation.
I'm trying to write a script which I could run and obtain something like this at the end (neither the order of the rows nor the id column is important):
+----+-----+------+---------+-----------+
| id | src | dest | time | requests |
+----+-----+------+---------+-----------+
| 6 | abc | xyz | 1100000 | 200200000 |
| 7 | def | uvw | 10 | 300 |
| 8 | abc | uvw | 100 | 5000 |
| 9 | def | xyz | 11000 | 140000 |
+----+-----+------+---------+-----------+
Any ideas on how I could figure this out?
You can't really combine the rows in a single table -- at least not easily. That would require both updates and deletes.
So, just create another table:
create table summary_t as
select src, desc, sum(time) as time, sum(requests) as requests
from table t
group by src, desc;
If you really want this go go back into the original table, then use a temporary table and re-insert the data:
create temporary table summary_t as
select src, desc, sum(time) as time, sum(requests) as requests
from t
group by src, desc;
truncate table t;
insert into t(src, desc, time, requests)
select src, desc, time, requests
from summary_t;
However, having said all that, you should just add another step to your map-reduce application to do that final summary.
Group By with SUM aggregate should work
select src, dest, sum(`time`) as `time`, sum(requests) as requests
from yourtable
group by src, dest
Check if this suite your needs, Create a table with the columns src and dest as primary key and other fields like totaltime and totalrequest.
Create an INSERT AFTER trigger on the existing tabl, which updates the other table totaltime and totalrequest with (old + new) using the src and dest as the key for where condition.
I am trying to get an Access report to identify if a text field (NH) does not match with the same ID. For example, ID 179 has two rows but each NH is different (12345 & 12346). I am trying to use DCount to count the IDs where the NH does not match if it is the same ID but I cannot figure it out.
Here is an example of my code:
This is supposed to get the ID's that match such as 179 and 179 and check the NH to see if the are the same and return a count if they are not.
CheckValue = DCount([ID], "vTestQuery", "[NH] <> '" & [NH] & "'" And "[ID] ='" & [ID] & "'")
This gives a value to Me.txtColor for a Conditional formatting I have set up if CheckValue has an actual value.
If (CheckValue > 0) Then
Me.txtColor = CheckValue
I also need this go through all the records in the report and get a count on each matching ID with different NHs so I can flag the NHs that are different.
Can someone let me know if I am even on the right track with this and if so a solution to my dilemma.
Thank you very much!
1st EDIT
Sample Data:
+-----+------------+------------+------------+-------------+
| ID | FullName | DateOfServ | AccountNum | NoteH |
+-----+------------+------------+------------+-------------+
| 179 | Test, Jane | 8/1/2015 | 458585 | AAA-1111111 |
| 180 | Test, Paul | 8/1/2015 | 458586 | AAA-2222222 |
| 181 | Test, John | 8/2/2015 | 458587 | AAA-3333333 |
| 214 | Test, Alex | 8/3/2015 | 458588 | AAA-4444444 |
| 214 | Test, Alex | 8/3/2015 | 458588 | AAA-4444445 |
| 215 | Test, Alex | 8/3/2015 | 458589 | AAA-5555555 |
| 215 | Test, Alex | 8/3/2015 | 458589 | AAA-5555555 |
+-----+------------+------------+------------+-------------+
So what I need the report to do is highlight or change text color for the IDs that match but have a different NH For example record 214 has two records with all the same exact data except for the NoteH and I need both those NoteH to be highlighted or the text changed. I have made the NoteH in question both bold. Let me know if this helps.
2nd EDIT
So the query worked for all duplicate IDs with duplicate NoteH, but it still only registers one ID if the NoteH is different. I added an IDCount to show how the query registers each 214 ID as different because of the different NoteH.
Here are the results:
+-----+------------+---------+
| ID | NoteCount | IDCount |
+-----+------------+---------+
| 214 | 1 | 1 |
+-----+------------+---------+
| 214 | 1 | 1 |
+-----+------------+---------+
| 212 | 2 | 2 |
+-----+------------+---------+
I need a way to have the report recognize that 214 is a duplicate field but the NoteH is not the same. It is really close to working everything else you suggested works great!!!
3rd EDIT
SELECT May.ID, Count(May.ID) AS IDCount, FROM May INNER JOIN
Count(CodeRyteCodingResults.[Note Handle]) AS NoteCount
CodeRyteCodingResults ON May.[Accession #] =
CodeRyteCodingResults.[Accession Number]
GROUP BY May.ID;
Use Aggregate Queries and Conditional Formatting
Create separate queries to get counts of unique notes per ID. It will look something like this (I'm using two queries):
UniqueNotesQuery
SELECT ID, NoteH
FROM BaseTable
GROUP BY ID, NoteH
NoteCountsQuery (this queries the first one)
SELECT ID, Count(NoteH) AS NoteCount
FROM UniqueNotesQuery
GROUP BY ID;
Then join this as part of your report query. It will look something like this:
SELECT BaseTable.*, NoteCountsQuery.NoteCount
FROM BaseTable INNER JOIN NoteCountsQuery
ON BaseTable.ID = NoteCountsQuery.ID
In your report, write a rule in the Conditional Formatting of the textboxes. Something like this:
[NoteCount] > 1
These queries above are just written from scratch, so they are untested, and you will need to flesh them out for your project.
References:
Office Support = GROUP BY Clause
Office Support - Conditional Formatting