I have a requirement to sum/aggregate total hours entered by day for the week for each user. Each user can have multiple entries for each day depending on which task(s) they are entering hours for. The data looks similar to this (simplified)
Table 1 (SystemUser)
SystemUserID
FullName
1
Bob
2
Sue
Table 2 (TimeEntry)
OwnerID
TimeEntryDate
Task
Duration
1
09/05/2022
A
4
1
09/05/2022
B
4
2
09/05/2022
A
6
2
09/05/2022
B
1
1
09/06/2022
A
8
2
09/06/2022
B
3
2
09/06/2022
B
3
My results should look like this:
FullName
MondayTotal
TuesdayTotal
Bob
8
8
Sue
7
6
My fetch looks like this currently (I have additional code to figure out which day of the week it is to build the dates dynamically based on the workweek). I start with SystemUser and do outer joins to TimeEntry to make sure if they didn't put in any time for a day, I still get the user back.
<fetch aggregate="true">
<entity name="systemuser" >
<attribute name="fullname" alias="FullName" groupby="true" />
<link-entity name="timeentry" from="ownerid" to="systemuserid" link-type="outer" alias="TimeEntriesMonday" >
<attribute name="duration" alias="mondayTotal" aggregate="sum" />
<filter>
<condition attribute="timeentrydate" operator="on" value="2022-09-05" />
</filter>
</link-entity>
<link-entity name="timeentry" from="ownerid" to="systemuserid" link-type="outer" alias="TimeEntriesTuesday" >
<attribute name="duration" alias="tuesdayTotal" aggregate="sum" />
<filter>
<condition attribute="timeentrydate" operator="on" value="2022-09-06" />
</filter>
</link-entity>
</entity>
What I find is it doubles the amounts (and so on as I add in the rest of the week).
FullName
MondayDuration
TuesdayDuration
Bob
16
16
Sue
14
12
I have tried various things, such as "distinct" which doesn't work as if a user enters two entries of "4" hours for a given day it will only return one. I've also tried using inner joins but obviously that doesn't work.
I thought providing a table alias every time I join it along with a filter condition for the date would handle this correctly.
Related
I have some sales data in InfluxDB, basically every 10 seconds I record the total number of sales from SQL, then break that down into sales of different items in the fields.
So a row might look like:
time Bicycles Shovels Hats Candles Sales
01/01/2019 12 6 2 4 24
02/01/2019 14 9 3 5 31
(This is dummy data for this question and doesn't reflect the number in the images, which are from production tests I've been doing with actual data)
It's important to stress this is accumulative, each entry grows by the number of sales.
I can then use Grafana to show me the difference(max(sales)) group by time(1d) to show the total sales (per day in this case)
What I am also trying to do is show the most sales per group (day) in a table, a record sales table, how well we have done in the past.
So I have 3 queries in Grafana:
SELECT time, max(difference) FROM (
SELECT difference(max("Sales"))
FROM "autogen"."Paid_Orders"
WHERE $timeFilter
GROUP BY time(1d) fill(none)
)
Swap "sales" for bicycles and hats (whatever) in the subsequent queries and I end up with a table that looks like:
Problem is I don't know which line is which field. Normally (in SQL) I would do something like SELECT 'Sales' as Type, etc... to add in a column with "Sales" in it. But I can't see that as an option in either Grafana or Influx.
Am I recording the data wrong and could I be leveraging Tags for this?
How can I identify the rows in this table?
yes, your data structure doesn't look good. Instead of one record:
time Bicycles Shovels Hats Candles Sales
01/01/2019 12 6 2 4 24
save multiple records with different item tag (sales is int field):
time item sales
01/01/2019 Bicycles 12
01/01/2019 Shovels 6
01/01/2019 Hats 2
01/01/2019 Candles 4
Then group by time AND item tag + SPREAD function can be used to remove subquery, e.g.
SELECT time, SPREAD(sales)
FROM "autogen"."Paid_Orders"
WHERE $timeFilter
GROUP BY time(1d), "item" fill(none)
I have the following simplified XML structure:
<Product>
<Name>Product 1</Name>
<Discount>
<Name>Discount 1<Name>
<Rate>10</Rate>
<Amount>100</Amount>
</Discount>
<Discount>
<Name>Discount 2<Name>
<Rate>20</Rate>
<Amount>200</Amount>
</Discount>
</Product>
<Product>
<Name>Product 2</Name>
<Discount>
<Name>Discount 1<Name>
<Rate>30</Rate>
<Amount>300</Amount>
</Discount>
<Discount>
<Name>Discount 2<Name>
<Rate>40</Rate>
<Amount>400</Amount>
</Discount>
</Product>
The structure is then processed by a report. What I would like to display is the following:
Product 1
Discount 1 (10%) 100
Discount 2 (20%) 200
Product 2
Discount 1 (30%) 300
Discount 2 (40%) 400
I have tried to structure a subreport as follows:
ReportHeader (contains a table header)
Group 1 (grouped by Product.Internal_Id, with the product name)
Group 2 (grouped by Discount.Internal_Id, with discount data)
Details (suppressed)
Footers (suppressed).
When I preview the result in my editor, it looks exactly as I want. However, when processed by the server, each product group lists all discounts for all products:
Product 1
All discounts for all products
Product 2
Same...
The version of my local report designer is 14.0.4.738. The version embedded in the server is 12.2.205.825.
How should I structure my report template in order to obtain the result I expect? Unfortunately, I have limited experience with Crystal Reports. I have tried many variations and many groupings, to no avail.
I am new to Fetchxml and using MS CRM Dynamics 2015 On Premise to create SSRS report using Visual Studio 2012
My Fetchxml query returns me a Datetime column (CreatedOn)
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="fax">
<attribute name="createdon" />
<attribute name="documenttype" />
<attribute name="activityid" />
<attribute name="statecode" />
<order attribute="createdon" descending="false" />
</entity>
</fetch>
I want to group with Date (not with datetime).
Tried to do formatting by using
=Format(createdonValue.value, "dd/MM/yyyy")
and
=FormatDateTime(createdonValue.value, DateFormat.ShortDate)
It's formatting, but grouping doesn't work. Records repeats.
Please let me know is there any way to group by only with 'Date' part of 'FetchXML resulted date value' or is there anyway to get only 'date' part while querying with fetchxml.( e.g. in another column.)
You can group on multiple items in a single grouping.
Set up the group so it has three conditions
=Year(Fields!MyDateTime.Value)
And
=Month(Fields!MyDateTime.Value)
And
=Day(Fields!MyDateTime.Value)
Your grouping details will then look like this
And this is an example of applying this to a column of dates
Note how the two 04/04/01 dates are grouped, despite the different times.
Hopefully this is what you require. Let me know if I can be of further assistance.
I have a delimited flat file that has 3 columns:
NEW # DETAIL OLD #
------ ------ ------
111111 AAAA 123456
222222 BBBB
333333 CCCC 987654
I need my output to be
# DETAIL
------ ------
111111 AAAA
222222 BBBB
333333 CCCC
123456 AAAA
987654 CCCC
I need to ignore nulls in the OLD # column.
I'm not sure the best way to accomplish this. Union All and/or merge seem to work if you have multiple sources.
The general concept is that you will want to Unpivot. Jason Strate has a really good article on it with his 31 days of SSIS series.
The basic idea is that you want to keep the DETAIL column and let the other two flow into it. Unpivot is the native operation to normalize the data.
Source
I used a query as it was faster to gin up and I added in a row with an explicit NULL value.
SELECT
*
FROM
(
VALUES
('111111','AAAA','123456')
, ('222222','BBBB','')
, ('333333','CCCC','987654')
, ('444444','DDDD',NULL)
) D([NEW #], [DETAIL],[OLD #]);
Unpviot
The operation will unpivot the data. This eliminates NULL values but retains empty strings. This may or may not be the outcome you desire.
Results
At this point, you can see we have the empty string row. You can address this in two ways, I'll let you pick your approach.
Upstream - scrub empty strings to NULL for elimination
Downstream - use a Conditional Split to remove the rows with empty Number values
Biml
Biml, the Business Intelligence Markup Language, describes the platform for business intelligence. Here, we're going to use it to describe the ETL. BIDS Helper, is a free add on for Visual Studio/BIDS/SSDT that addresses a host of shortcomings with it. Specifically, we're going to use the ability to transform a Biml file describing ETL into an SSIS package. This has the added benefit of providing you a mechanism for being able to generate exactly the solution I'm describing versus clicking through many tedious dialogue boxes.
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection ConnectionString="Provider=SQLNCLI11;Data Source=localhost\dev2014;Integrated Security=SSPI;Initial Catalog=tempdb" Name="CM_OLE" />
</Connections>
<Packages>
<Package
ConstraintMode="Linear"
Name="so_25670727">
<Tasks>
<Dataflow Name="DFT Combine all">
<Transformations>
<!--
Generate some source data. Added a row with an explicit NULL
as no real testing is done unless we have to deal with NULLs
-->
<OleDbSource ConnectionName="CM_OLE" Name="OLE_SRC Query">
<DirectInput>
SELECT
*
FROM
(
VALUES
('111111','AAAA','123456')
, ('222222','BBBB','')
, ('333333','CCCC','987654')
, ('444444','DDDD',NULL)
) D([NEW #], [DETAIL],[OLD #]);
</DirectInput>
</OleDbSource>
<!--
Unpivot the data. Combine NEW # and OLD # into a single column called Number.
A "Pivot Key Value" column will also be generated that identifies where the value came
from.
-->
<Unpivot Name="UP Detail">
<Columns>
<Column SourceColumn="DETAIL" TargetColumn="DETAIL"/>
<Column SourceColumn="NEW #" TargetColumn="Number" PivotKeyValue="NEW #"/>
<Column SourceColumn="OLD #" TargetColumn="Number" PivotKeyValue="OLD #"/>
</Columns>
</Unpivot>
<!--
Put something here so we can attach a data viewer
Notice, the NULL does not show in the output but the empty string does.
Depending on your tolerance, you will want to either
* Upstream - scrub empty strings to NULL for elimination
* Upstream - convert NULL to empty string for preservation
* Downstream - use a Conditional Split to remove the rows with empty Number columns
-->
<DerivedColumns Name="DER DataViewer">
</DerivedColumns>
</Transformations>
</Dataflow>
</Tasks>
</Package>
</Packages>
</Biml>
Imagine I have a MSSQL 2005 table(bbstats) that updates weekly showing
various cumulative categories of baseball accomplishments for a team
week 1
Player H SO HR
Sammy 7 11 2
Ted 14 3 0
Arthur 2 15 0
Zach 9 14 3
week 2
Player H SO HR
Sammy 12 16 4
Ted 21 7 1
Arthur 3 18 0
Zach 12 18 3
I wish to highlight textually where there has been a change in leader for each category
so after week 2 there would be nothing to report on hits(H); Zach has joined Arthur with most strikeouts(SO) at
18; and Sammy is new leader in homeruns(HR) with 4
So I would want to set up a process something like
a) save the past data(week 1) as table bbstatsPrior,
b) updates the bbstats for the new results - I do not need assistance with this
c) compare between the tables for the player(s with ties) with max value for each column
and spits out only where they differ
d) move onto next column and repeat
In any real world example there would be significantly more columns to calculate for
Thanks
Responding to Brents comments, I am really after any changes in the leaders for each category
So I would have something like
select top 1 with ties player
from bbstatsPrior
order by H desc
and
select top 1 with ties player,H
from bbstats
order by H desc
I then want to compare the player from each query (do I need to do temp tables) . If they differ I want to output the second select statement. For the H category Ted is leader `from both tables but for other categories there are changes between the weeks
I can then loop through the columns using
select name from sys.all_columns sc
where sc.object_id=object_id('bbstats') and name <>'player'
If the number of stats doesn't change often, you could easily just write a single query to get this data. Join bbStats to bbStatsPrior where bbstatsprior.week < bbstats.week and bbstats.week=#weekNumber. Then just do a simple comparison between bbstats.Hits to bbstatsPrior.Hits to get your difference.
If the stats change often, you could use dynamic SQL to do this for all columns that match a certain pattern or are in a list of columns based on sys.columns for that table?
You could add a column for each stat column to designate the leader using a correlated subquery to find the max value for that column and see if it's equal to the current record.
This might get you started, but I'd recommend posting what you currently have to achieve this and the community can help you from there.