How to Output results based on year from query? - coldfusion

I have a query:
<cfquery name="pivotquery">
SELECT employeedept,cse_name,YEAR,January,February,March,April,May,June,July,August,September,October,November,December
FROM (
SELECT month= datename(month,execoffice_date)
, YEAR =YEAR(execoffice_date)
, employeedept
, COUNT(*) as 'totalstars'
FROM CSEReduxResponses
WHERE execoffice_status = 1
GROUP BY employeedept
, month(execoffice_date)
, YEAR(execoffice_date)
, DATENAME(month,execoffice_date)
)
AS r
JOIN csedept d ON d.cse_dept = r.employeedept
PIVOT
(
SUM(totalStars)
FOR [month] IN (
[January],[February],[March],[April],
[May],[June],[July],[August],
[September],[October],[November],[December]
)
)
AS pvt
</cfquery>
This gets me all the data I want based on the month and year.
I'm outputing the results in a table:
<table >
<thead>
<tr>
<th>Department</th>
<th>January</th>
<th>Frebruary</th>
.........
</tr>
</thead>
<tbody>
<cfoutput query="pivotquery" >
<tr>
<td>#pivotquery.csedept_name#</td>
<td>#pivotquery.January#</td>
<td>#pivotquery.February#</td>
.......
</tr>
</cfoutput>
</tbody>
</table>
Yes is outputting the data correctly. How can I get it to output the results in a separate table by year?
If you take a look at this sqlfiddle, it has 2014 and 2015 data. So I would like generate a separate table for each year. So with the data I created in the sqlfiddle, it would have 2 tables: one for 2014 and 2015.

Depends on how you want things to be displayed. But since it looks like your data is ordered by year then you should be able to display by year via grouping your cfoutput by year. So something like:
<cfoutput query="pivotquery" group="YEAR">
<table >
<thead>
<tr>
<th>Department for #pivotquery.YEAR#</th>
<th>January</th>
<th>Frebruary</th>
.........
</tr>
</thead>
<tbody>
<cfoutput>
<tr>
<td>#pivotquery.csedept_name#</td>
<td>#pivotquery.January#</td>
<td>#pivotquery.February#</td>
.......
</tr>
</cfoutput>
</tbody>
</table>
</cfoutput>

Related

Follow-up Dax Drop Duplicates

Similiar to a question asked here,
Given, this table, I want to only keep the records where the email appears first.
email
firstname
Lastname
Address
City
Zip
ABC#XYZ.com
Scott
Johnson
A
Z
1111
ABC#XYZ.com
Bill
Johnson
B
Y
2222
ABC#XYZ.com
Ted
Smith
C
X
3333
DEF#QRP.com
Steve
Williams
D
W
4444
XYZ#LMN.com
Sam
Samford
E
U
5555
XYZ#LMN.com
David
Beals
F
V
6666
DEF#QRP.com
Stephen
Jackson
G
T
7777
TUV#DEF.com
Seven
Alberts
H
S
8888
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>email</th>
<th>firstname</th>
<th>Lastname</th>
<th>Address</th>
<th>City</th>
<th>Zip</th>
</tr>
</thead>
<tbody>
<tr>
<td>ABC#XYZ.com</td>
<td>Scott</td>
<td>Johnson</td>
<td>A</td>
<td>Z</td>
<td>1111</td>
</tr>
<tr>
<td>ABC#XYZ.com</td>
<td>Bill</td>
<td>Johnson</td>
<td>B</td>
<td>Y</td>
<td>2222</td>
</tr>
<tr>
<td>ABC#XYZ.com</td>
<td>Ted</td>
<td>Smith</td>
<td>C</td>
<td>X</td>
<td>3333</td>
</tr>
<tr>
<td>DEF#QRP.com</td>
<td>Steve</td>
<td>Williams</td>
<td>D</td>
<td>W</td>
<td>4444</td>
</tr>
<tr>
<td>XYZ#LMN.com</td>
<td>Sam</td>
<td>Samford</td>
<td>E</td>
<td>U</td>
<td>5555</td>
</tr>
<tr>
<td>XYZ#LMN.com</td>
<td>David</td>
<td>Beals</td>
<td>F</td>
<td>V</td>
<td>6666</td>
</tr>
<tr>
<td>DEF#QRP.com</td>
<td>Stephen</td>
<td>Jackson</td>
<td>G</td>
<td>T</td>
<td>7777</td>
</tr>
<tr>
<td>TUV#DEF.com</td>
<td>Seven</td>
<td>Alberts</td>
<td>H</td>
<td>S</td>
<td>8888</td>
</tr>
</tbody>
</table>
Expected output table:
email
firstname
Lastname
Address
City
Zip
ABC#XYZ.com
Scott
Johnson
A
Z
1111
DEF#QRP.com
Steve
Williams
D
W
4444
XYZ#LMN.com
Sam
Samford
E
U
5555
TUV#DEF.com
Seven
Alberts
H
S
8888
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>email</th>
<th>firstname</th>
<th>Lastname</th>
<th>Address</th>
<th>City</th>
<th>Zip</th>
</tr>
</thead>
<tbody>
<tr>
<td>ABC#XYZ.com</td>
<td>Scott</td>
<td>Johnson</td>
<td>A</td>
<td>Z</td>
<td>1111</td>
</tr>
<tr>
<td>DEF#QRP.com</td>
<td>Steve</td>
<td>Williams</td>
<td>D</td>
<td>W</td>
<td>4444</td>
</tr>
<tr>
<td>XYZ#LMN.com</td>
<td>Sam</td>
<td>Samford</td>
<td>E</td>
<td>U</td>
<td>5555</td>
</tr>
<tr>
<td>TUV#DEF.com</td>
<td>Seven</td>
<td>Alberts</td>
<td>H</td>
<td>S</td>
<td>8888</td>
</tr>
</tbody>
</table>
There is no inherent ordering of a table in DAX, so in order to take the first row you need to add an index column or define an ordering on the table somehow.
For this answer, I'll assume that you've added an index column somehow (in the query editor or with a DAX calculated column).
You can create a filtered table as follows:
FilteredTable1 =
FILTER (
Table1,
Table1[Index]
= CALCULATE ( MIN ( Table1[Index] ), ALLEXCEPT ( Table1, Table1[email] ) )
)
For each row in Table1, this checks if the index is minimal over all the rows with the same email.
Assuming that we added an Index column with non duplicate values, it's possible to reduce the number of context transitions to only one per Email by preparing an Indexes table containing the indexes to be selected, and then apply this Indexes table as a filter using TREATAS.
T Index Unique =
VAR Indexes =
SELECTCOLUMNS(
ALL( 'T Index'[Email] ),
"MinIndex", CALCULATE( MIN( 'T Index'[Index] ) )
)
RETURN
CALCULATETABLE( 'T Index', TREATAS( Indexes, 'T Index'[Index] ) )
If instead we have non-unique column across the different Emails but unique per each email, like a timestamp, we can prepare a filter table containing the email and the timestamp
For instance with a T Date table like the following
The calculated table becomes
T Date Unique =
VAR EmailDate =
ADDCOLUMNS(
ALL( 'T Date'[Email] ),
"MinDate", CALCULATE( MIN( 'T Date'[Date] ) )
)
RETURN
CALCULATETABLE( 'T Date', TREATAS( EmailDate, 'T Date'[Email], 'T Date'[Date] ) )

In DAX (not powerquery) drop duplicates based on column

In my PowerBI desktop, I have table that is calculated from over other tables with a structure like this:
Input table:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC#XYZ.com</td>
</tr>
<tr>
<td>Bob</td>
<td>ABC#XYZ.com</td>
</tr>
<tr>
<td>Ted</td>
<td>ABC#XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF#XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN#QRS.com</td>
</tr>
<tr>
<td>Bill</td>
<td>LMN#QRS.com</td>
</tr>
</tbody>
</table>
Now, I want to keep only the first record for each unique email. My expected output table using DAX is:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC#XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF#XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN#QRS.com</td>
</tr>
</tbody>
</table>
I was trying to use RANKX and FILTER, but not having any success.
Sadly, the answer to this question is that there is no way in DAX to refer to the rows position relative to the other rows in the table. The only option is to use some column value for sorting purpose.
What we could do with the existing two columns table is to get the MAX or MIN Firstname per each Email. So we can write a calculated table like follows, where T is the input table and T Unique is the generated table.
T Unique =
ADDCOLUMNS(
ALL( T[Email] ),
"Firstname",
CALCULATE(
MAX( T[Firstname ] )
)
)
But this doesn't satisfy the requirement.
To obtain the desired result we need to add a column to the input table, with an index or a timestamp.
For this example I added an Index column using the following M code in Power Query, that is generated automatically by referencing the original table and then clicking on Add column -> Index column button
let
Source = T,
#"Added Index" = Table.AddIndexColumn(Source, "Index", 1, 1, Int64.Type)
in
#"Added Index"
So I obtained the T Index table.
Now we can write the following calculated table that uses the new column to retrieve the first row for each Email
T Index Unique =
ADDCOLUMNS(
ALL( 'T Index'[Email] ),
"Firstname",
VAR MinIndex =
CALCULATE(
MIN( 'T Index'[Index] )
)
RETURN
CALCULATE(
MAX( 'T Index'[Firstname ] ),
'T Index'[Index] = MinIndex
)
)
that generates the requested table
In a real case scenario, the best place to add the new column is directly into the code that generates the input table.

How to loop through a SQL query and output individual emails base on

I'm trying to loop over information from a query and send that information in an email. Currently, based on my stored procedure, I'm displaying all the rows in the email.
This is what I'm using to get the above information:
<table>
<thead>
<tr>
<th scope="col" id="left">Admin Name</th>
<th scope="col" id="middle">Department Name</th>
<th scope="col" id="right">Last Logon</th>
</tr>
</thead>
<tbody>
<cfloop query="#inactiveAdmins#">
<tr>
<td class="text-left">#Admin_Name#</td>
<td class="text-left">#Dept_Name#</td>
<td class="">#(Len(Last_Logon) ? dateFormat(Last_Logon, 'mmm dd, yyyy') : 'Never Logged On')#</td>
</tr>
</cfloop>
</tbody>
</table>
This is displaying all Admin Names, All Department Names and all Last Logon.
I need to be able to loop over each department and send an email to each department individually.
To loop over each department, this is what I'm trying, but it's not returning any results. My question is:
Is the syntax correct?
<cfloop query="#ALEmail#">
<cfquery dbtype="query" name="inactiveSW">
SELECT Dept_ID
FROM inactiveSW
WHERE Dept_ID = <cfqueryparam cfsqltype="cf_sql_char" value="#ALEmail.Dept_ID#">
</cfquery>
</cfloop>
This is more of a comment than an answer, but it is long
should be
On this part
<cfquery dbtype="query" name="inactiveSW">
SELECT Dept_ID
FROM inactiveSW
WHERE Dept_ID = <cfqueryparam cfsqltype="cf_sql_char" value="#ALEmail.Dept_ID#">
</cfquery>
Because the FROM is the same as the name=, it is like to either have a syntax error, or overwrite an existing variable.
Besides, you are just selecting a variable that already exists. This doesn't get any new information. Are you trying to test for existence of dept_id?
Lastly, if you are trying to send an email based on a query, it is really straight forward
<cfmail
query="ALEmail"
from="#from#"
to="#to#"
subject="#subject#">
Content here
</cfmail>

How to send table html with email using mailto?

I want to send a email using a href="mailto.."
I have this working code below:
<cfset month = URL.Month>
<cfset year = URL.Year>
<cfquery datasource="newsletters" name="testing">
SELECT * FROM departments_names
where dates >='#datestart#' and dates < #dateend#
AND shooting_star_dept_name IS NOT NULL
ORDER BY
DATEPART(year, dates),
DATEPART(month, dates),
</cfquery>
<cfoutput query="testing" GROUP="deptartmetn_name">
<tr>
<td>
<a href="mailto:?subject=#month#/#year#%20%20Results%20for%20newsletters&
body=#total_count#%20#total/total_count#">
Send email to #deptartmetn_name#</a></td>
</tr>
</cfoutput>
Which just send a simple "12/2" (for example).
I would like to be able to send more than just simple text.
I would like when i click on a link to be able to send a table like below:
<table>
<thead>
<tr >
<th> First Name</th>
<th> Last Name</th>
<th>total</th>
</tr>
</thead>
<cfoutput query="testing">
<tbody>
<tr >
<td>#employee_name#</td>
<td>#employee_lastname#</td>
<td>#total_count#</td>
</tr>
</tbody>
</cfoutput>
</table>
I would like to see what I'm sending first to the recipient.
Would something like this be possible or is there a better way to do this?
My first post here and beginner to coding.
You could use an AJAX callback on your links and use cfmail with cfsavecontent (for the actual HTML content/body of the message) in your callback handler code.

ColdFusion cfoutput query group

Please refer to this page:
http://allblacks.01dev.co.nz/templates/super14/textobjects/SRMatchDayList.cfm
Query dump is included there. I've inherited this code and would prefer to work with it if possible.
The following code outputs fixtures by week.
<table cellspacing="0" cellpadding="0" border="0" align="center" width="530">
<tr bgcolor="#797979">
<th align="left"><p> <b>Date</b></p></td>
<th align="left"><p><b>Game</b></p></td>
<th align="left"><p><b>Venue</b></p></td>
<th align="left"><p><b>Time (NZ)</b></p></td>
<th align="center"><p><b>Result</b> </p></td>
</tr>
<cfset iWeekCounter = 0>
<cfif not attributes.useSegmentTitle and attributes.sortDirection is "desc">
<cfset qSegments = oSeries.getSegmentInfo(seriesID=attributes.seriesID)>
<cfset iWeekCounter = qSegments.recordcount + 1>
</cfif>
<cfoutput query="qSeriesEvents" group="segmentID">
<cfif attributes.sortDirection is "desc">
<cfset iWeekCounter = iWeekCounter-1>
<cfelse>
<cfset iWeekCounter = iWeekCounter+1>
</cfif>
<tr>
<td colspan="5"><p><br><strong>
<cfif attributes.useSegmentTitle>
#qSeriesEvents.segment#
<cfelse>
Week #iWeekCounter#
</cfif>
</strong></p></td>
</tr>
<cfoutput>
<cfif textObjectCount gt 0>
<tr>
<td><p> #DateFormat(eventDateTime, "dd mmm")#</p></td>
<td><p>#event#</p></td>
<td><p>#location#</p></td>
<td><p><cfif showTimeField is 1>#lcase(timeFormat(dateadd('h',iTimeOffset,eventDateTime),"h:mm tt"))#</cfif></p></td>
<td align="center" valign="top"><p><cfif isDate(eventDateTime) AND dateDiff("n",eventDateTime, now())>#oEvent.getTeamResult(eventID, homeTeamID)#-#oEvent.getTeamResult(eventID, awayTeamID)#</cfif> </p></td>
</tr>
<tr><td colspan="5"><div style="height:1px; padding:0px; margin0px; font-size:0; border-bottom: 1px solid ##999"></div></td></tr>
</cfif>
</cfoutput>
</cfoutput>
</table>
However, note weeks 3 - 18 in the above URL, which don't have any data. I don't want to display week lines if there is no data. How can I accomplish this using this query output "group=" setup if possible?
SQL from the website
SELECT tObj.textObjectCount, events.*, venues.venue, venues.location, DATENAME(wk, events.eventDateTime - 1) AS EventWeek, s.segment
FROM events join segments s on s.segmentID = events.segmentID
LEFT OUTER JOIN (
SELECT LUTextObjectEvent.eventID, COUNT(*) AS textObjectCount
FROM LUTextObjectEvent
INNER JOIN textObjects ON LUTextObjectEvent.textObjectID = textObjects.textObjectID
GROUP BY LUTextObjectEvent.eventID
) tObj
ON events.eventID = tObj.eventID
LEFT OUTER JOIN venues ON events.venueID = venues.venueID
WHERE (events.eventID IN (
SELECT eventID
FROM events
WHERE segmentID IN (
SELECT segmentID
FROM segments
WHERE seriesID IN (?))
)
)
ORDER BY s.segmentID asc
You're using a LEFT OUTER JOIN which means you'll have one record for every event/segment. Change those to inner joins and you should have your desired results
SELECT tObj.textObjectCount, events.*, venues.venue, venues.location, DATENAME(wk, events.eventDateTime - 1) AS EventWeek, s.segment
FROM events join segments s on s.segmentID = events.segmentID
INNER JOIN (
SELECT LUTextObjectEvent.eventID, COUNT(*) AS textObjectCount
FROM LUTextObjectEvent
INNER JOIN textObjects ON LUTextObjectEvent.textObjectID = textObjects.textObjectID
GROUP BY LUTextObjectEvent.eventID
) tObj
ON events.eventID = tObj.eventID
INNER JOIN JOIN venues ON events.venueID = venues.venueID
WHERE (events.eventID IN (
SELECT eventID
FROM events
WHERE segmentID IN (
SELECT segmentID
FROM segments
WHERE seriesID IN (?))))
ORDER BY s.segmentID asc