I have a table with for which the column "CODE" has values like this:
FTRA2
BRB92
RBRB4
XYZ
SXM4
RBRB4
NLDR
XYZ
FTRA2
POEU
FTRA2
I currently have this formula
="[ Unique values " & DISTINCTCOUNT(MyTable[CODE]) & "]
" & CONCATENATEX(DISTINCT(MyTable[CODE]), MyTable[CODE] ,", ")
that outputs this:
[ Unique values 7 ]
FTRA2, BRB92, RBRB4, XYZ, SXM4, NLDR, POEU
I would like to show all the unique values and their count (except those with the string "XYZ") and below show how many "XYZ" values are, like this:
[ Unique values 6 ]
FTRA2, BRB92, RBRB4, SXM4, NLDR, POEU
[2 XYZ values]
In this case there are 2 "XYZ" values, but could be zero XYZ values too.
I'm using Excel 2016.
How can I do this? Thanks in advance.
UPDATE1
I get this error tryng Joe's solution.
UPDATE2
Joe, I was able to make work your first part modifying like this:
= VAR ExcludeValue = "XYZ"
RETURN
CALCULATE(
"[ Unique values " & DISTINCTCOUNT(MyTable[Code]) & " ]"
" & CONCATENATEX(DISTINCT(MyTable[Code]), [Code], ", ")
, MyTable[Code] <> ExcludeValue
)
But when I add the second part it says this error
This formula is invalid or incomplete: 'Calculation error in
measure 'MyTable[Code]: The function COUNT takes an argument
that evaluates to numbers or dates and cannot work with values
of type String.'.
I also removed the UNICHAR since doesn't work on Excel.
UPDATE3
Joe's solution it works correctly after I modified the COUNT(MyTable[Code]) to COUNTROWS(MyTable)
The final solution looks like this.
=VAR ExcludeValue = "XYZ"
RETURN
CALCULATE(
"
[ Unique values " & DISTINCTCOUNT(MyTable[Code]) & " ]
" & CONCATENATEX(DISTINCT(MyTable[Code]), [Code], ", ")
, MyTable[Code] <> ExcludeValue
) & "
" & CALCULATE(
"[" & COUNTROWS(MyTable) & " " & ExcludeValue & " values]"
, MyTable[Code] = ExcludeValue
) & "
"
Update4
Print nothing when there is no "XYZ" values works with your IF() addition. I've tried to follow your logic to do the same when there is no values at all. I added an
IF() to count if MyTable[Code] <> ExcludeValue is greater than 0 and if true do original CALCULATE, if not BLANK() but doesnt work.
CountLabel =
VAR ExcludeValue = "XYZ"
RETURN
IF(
CALCULATE(COUNTROWS(MyTable), MyTable[Code] <> ExcludeValue) > 0,
CALCULATE(
"[ Unique values " & DISTINCTCOUNT(MyTable[Code]) & " ]"
& UNICHAR(10) &
CONCATENATEX(DISTINCT(MyTable[Code]), [Code], ", ")
, MyTable[Code] <> ExcludeValue
),
BLANK()
)
& IF(
CALCULATE(COUNTROWS(MyTable), MyTable[Code] = ExcludeValue) > 0,
UNICHAR(10) & " " & UNICHAR(10) &
CALCULATE(
"[" & COUNTROWS(MyTable) & " " & ExcludeValue & " values]"
, MyTable[Code] = ExcludeValue
),
BLANK()
)
FINAL UPDATE
This is the final formula that works as expected. Thanks to Joe's help in this case.
=VAR ExcludeValue = "XYZ"
RETURN
IF(
CALCULATE(DISTINCTCOUNT(MyTable[Code]), MyTable[Code] <> ExcludeValue) > 0 &&
MyTable[Count of Code]>0,
CALCULATE(
"
[ Unique values " & DISTINCTCOUNT(MyTable[Code]) & " ]
" & CONCATENATEX(DISTINCT(MyTable[Code]), [Code], ", ")
, MyTable[Code] <> ExcludeValue
),
BLANK()
)
&
IF(
CALCULATE(DISTINCTCOUNT(MyTable[Code]), MyTable[Code] <> ExcludeValue) > 0 &&
CALCULATE(COUNTROWS(MyTable), MyTable[Code] = ExcludeValue) > 0,
"
" &
BLANK()
)
& IF(
CALCULATE(COUNTROWS(MyTable), MyTable[Code] = ExcludeValue) > 0,
CALCULATE(
"[" & COUNTROWS(MyTable) & " " & ExcludeValue & " values]"
, MyTable[Code] = ExcludeValue
),
BLANK()
) & "
"
UPDATE: - Changed my formula from using COUNT to COUNTROWS based on feedback from OP.
UPDATE 2: - Add IF statement to formula to exclude excluded count when 0.
UPDATE 3: - Add IF statement to formula to exclude distinct count when 0.
I will say that I created this solution in Power BI, but Excel 2016 should have the same functionality when it comes to DAX (with minor tweaks).
I created a measure with your formula, and simply wrapped each piece (the distinct count, and the repeated count) with a CALCULATE statement that is used to filter your MyTable down to the codes you care about.
I used a variable for the "XYZ" value in case that needs to be changed. Now you can simply change it in one place (at the beginning of the formula) and the rest of the formula will reflect that change.
I also used UNICHAR(10) to add the line breaks instead of counting on the new lines in the formula.
With the IF statements...
The first will check if the distinct count of items not equal to the specified value is greater than zero. If not, it won't show anything.
The second will check if the distinct count and the row count of the specified value are both greater than zero. If they are, it will add the line break.
The third will check if the row count of items equal to the specified value is greater than zero. If not, it won't show anything.
The final formula is:
CountLabel =
VAR ExcludeValue = "XYZ"
RETURN
IF(
CALCULATE(DISTINCTCOUNT(MyTable[Code]), MyTable[Code] <> ExcludeValue) > 0,
CALCULATE(
"[ Unique values " & DISTINCTCOUNT(MyTable[Code]) & " ]"
& UNICHAR(10) &
CONCATENATEX(DISTINCT(MyTable[Code]), [Code], ", ")
, MyTable[Code] <> ExcludeValue
),
BLANK()
)
&
IF(
CALCULATE(DISTINCTCOUNT(MyTable[Code]), MyTable[Code] <> ExcludeValue) > 0 &&
CALCULATE(COUNTROWS(MyTable), MyTable[Code] = ExcludeValue) > 0,
UNICHAR(10) & " " & UNICHAR(10),
BLANK()
)
& IF(
CALCULATE(COUNTROWS(MyTable), MyTable[Code] = ExcludeValue) > 0,
CALCULATE(
"[" & COUNTROWS(MyTable) & " " & ExcludeValue & " values]"
, MyTable[Code] = ExcludeValue
),
BLANK()
)
Here is what the result looks like (again, in Power BI).
Came up with something similar but slightly different using COUNTROWS instead of CALCULATE to filter the table for the unique item. Also I am just learning DAX so don't know if this is a "proper" way to do it, but it seems to work.
Measure =
VAR Exclusion = "XYZ"
RETURN
"[ Unique values " & COUNTROWS(FILTER(DISTINCT(MyTable[CODE]), [CODE] <> Exclusion)) & "]
" & CONCATENATEX(FILTER(DISTINCT(MyTable[CODE]), [CODE] <> Exclusion), [CODE] ,", ") &
"
[" & COUNTROWS(FILTER(MyTable, MyTable[CODE] = Exclusion))+0 & " " & Exclusion & " values]"
Related
I have a string, basically it's a SQL statement. I want to extract some part of it.
Here is the code
SELECT
DTE as "Date",
CURRENT_DATE AS "Day",
concat( BCCO, BCBCH ) AS "client/batch",
BCSTAT as "Batch Status",
CASE
WHEN EXC = 'MCR' THEN CNT
ELSE 0
END AS "MCR-NPR",
CASE
WHEN EXC = 'NRC' THEN CNT
ELSE 0
END AS "NRC-NPR",
CASE
WHEN EXC = 'OFD' THEN CNT
ELSE 0
END AS "OFD-NPR",
CASE
WHEN EXC = 'TDB' THEN CNT
ELSE 0
END AS "TDB-NPR",
CASE
WHEN EXC = 'TDC' THEN CNT
ELSE 0
END AS "TDC-NPR",
CASE
WHEN EXC = 'UDC' THEN CNT
ELSE 0
END AS "UDC-NPR",
CASE
WHEN EXC = 'BIN' THEN CNT
ELSE 0
END AS "BIN-WRN",
CASE
WHEN EXC = 'DSP' THEN CNT
ELSE 0
END AS "DSP-WRN",
I want to extract every element between END AS and the quote. A vector like ("MCR-NPR",...,"DSP-WRN") will be the desire output.
I know I may need to use regular expression, but I couldn't extract every one of them.
Any idea will be appreciated.
Best,
1) grep/read.table grep out lines with END AS and use read.table with a sep of double quote to read those. The second column will be the desired data. No regular expressions or packages are used.
read.table(text = grep("END AS", s, value = TRUE, fixed = TRUE),
sep = '"', as.is = TRUE)[[2]]
## [1] "MCR-NPR" "NRC-NPR" "OFD-NPR" "TDB-NPR" "TDC-NPR" "UDC-NPR" "BIN-WRN"
## [8] "DSP-WRN"
1a) This is similar to (1) but uses sub with a regular expression instead of read.table:
sub('.*END AS "(.+)".*', "\\1", grep("END AS", s, value = TRUE))
## [1] "MCR-NPR" "NRC-NPR" "OFD-NPR" "TDB-NPR" "TDC-NPR" "UDC-NPR" "BIN-WRN"
## [8] "DSP-WRN"
2) strapply Another approach is the following. It makes use of the fact that the desired strings follow END AS and are surrounded with double quotes It has the shortest code of the ones shown here.
library(gsubfn)
unlist(strapplyc(s, 'END AS "(.+)"'))
## [1] "MCR-NPR" "NRC-NPR" "OFD-NPR" "TDB-NPR" "TDC-NPR" "UDC-NPR" "BIN-WRN"
## [8] "DSP-WRN"
3) strcapture Another base R approach using the same pattern as in (2) is:
na.omit(strcapture('END AS "(.+)"', s, list(value = character(0))))
giving:
value
9 MCR-NPR
13 NRC-NPR
17 OFD-NPR
21 TDB-NPR
25 TDC-NPR
29 UDC-NPR
33 BIN-WRN
37 DSP-WRN
Note
The input s in reproducible form:
s <-
c("SELECT ", " DTE as \"Date\",", " CURRENT_DATE AS \"Day\",",
" concat( BCCO, BCBCH ) AS \"client/batch\",", " BCSTAT as \"Batch Status\",",
" CASE ", " WHEN EXC = 'MCR' THEN CNT ", " ELSE 0 ", " END AS \"MCR-NPR\",",
" CASE ", " WHEN EXC = 'NRC' THEN CNT ", " ELSE 0 ", " END AS \"NRC-NPR\",",
" CASE ", " WHEN EXC = 'OFD' THEN CNT ", " ELSE 0 ", " END AS \"OFD-NPR\",",
" CASE ", " WHEN EXC = 'TDB' THEN CNT ", " ELSE 0 ", " END AS \"TDB-NPR\",",
" CASE ", " WHEN EXC = 'TDC' THEN CNT ", " ELSE 0 ", " END AS \"TDC-NPR\",",
" CASE ", " WHEN EXC = 'UDC' THEN CNT ", " ELSE 0 ", " END AS \"UDC-NPR\",",
" CASE ", " WHEN EXC = 'BIN' THEN CNT ", " ELSE 0 ", " END AS \"BIN-WRN\",",
" CASE ", " WHEN EXC = 'DSP' THEN CNT ", " ELSE 0 ", " END AS \"DSP-WRN\"")
I am getting this error whenever I try to run my project although the column isn't of type system.string. I have a page that is coded the same way with different numbers and it doesn't give me this error. This is my SQL string:
MyCompSqlString = "SELECT (KAIPRDDTA.F4102LA.IBPRP6)ColOne, (KAIPRDCOM.F0005.DRDL01)ColTwo, COUNT(KAIPRDDTA.F42119LA.SDSOQS*.01)ColThree, SUM(KAIPRDDTA.F42119LA.SDAEXP*.01*CXCRR)ColFour, count(SDDOC)ColFive, SUM(KAIPRDDTA.F42119LA.SDSOQS*.01)ColSix "
MyCompSqlString += "FROM KAIPRDDTA.F42119LA, KAIPRDDTA.F55311, KAIPRDCOM.F0005, KAIPRDDTA.F0015, KAIPRDDTA.F4102LA"
MyCompSqlString += "WHERE DRSY = '41' AND DRRT = '01' AND TRIM(DRKY) = IBPRP6 AND KAIPRDDTA.F42119LA.SDITM = KAIPRDDTA.F4102LA.IBITM AND KAIPRDDTA.F42119LA.SDMCU = KAIPRDDTA.F4102LA.IBMCU AND KAIPRDDTA.F42119LA.SDSLSM = KAIPRDDTA.F55311.TERR AND (KAIPRDDTA.F42119LA.SDIVD >= " & SDJ & ") AND (KAIPRDDTA.F42119LA.SDIVD <= " & EDJ & ") AND "
MyCompSqlString += "(KAIPRDDTA.F42119LA.SDSLSM > 0) AND (KAIPRDDTA.F42119LA.SDGLC NOT IN ('FT60', 'TXTX', 'IN20', 'INSP', 'INWC', 'INWR', 'INWS','',' ')) AND "
MyCompSqlString += "(trim(KAIPRDDTA.F42119LA.SDLNTY) NOT IN ('T', 'F', 'TX', 'TA', 'TS', 'RF', 'RP','BC')) AND (KAIPRDDTA.F42119LA.SDNXTR <> '999') AND (KAIPRDDTA.F42119LA.SDDCTO not in ('ST','CR','SR')) "
MyCompSqlString += "AND (KAIPRDDTA.F55311.VIEWID = '" & MyView & "') AND (SDAN8 <> 24157 and SDAN8 <> 152) AND ((SDTRDJ-1)=CXEFT) AND (SDBCRC=CXCRCD) AND (CXCRDC ='USD')"
MyCompSqlString += "GROUP BY KAIPRDDTA.F4102LA.IBPRP6, KAIPRDCOM.F0005.DRDL01"
and this is my summary row:
<ig:SummaryRow EmptyFooterText="" FormatString=" {1}" ShowSummariesButtons="false">
<ColumnSummaries>
<ig:ColumnSummaryInfo ColumnKey="ColThree">
<Summaries>
<ig:Summary SummaryType="Sum" />
</Summaries>
</ig:ColumnSummaryInfo>
<ig:ColumnSummaryInfo ColumnKey="ColFour">
<Summaries>
<ig:Summary SummaryType="Sum" />
</Summaries>
</ig:ColumnSummaryInfo>
<ig:ColumnSummaryInfo ColumnKey="ColFive">
<Summaries>
<ig:Summary CustomSummaryName="100.00%" />
</Summaries>
</ig:ColumnSummaryInfo>
<ig:ColumnSummaryInfo ColumnKey="ColTwo">
<Summaries>
<ig:Summary CustomSummaryName="Totals:" />
</Summaries>
</ig:ColumnSummaryInfo>
</ColumnSummaries>
Does anyone have any suggestions as to why it is giving me this error? Let me know if you need any more information and I will update my question. Thanks in advance for your responses
You have a group which is NULL. This error means not all of the values are integer. So this query must produce a NULL as a value on some of the rows.
I'm getting a syntax error in my UPDATE statement, but I'm not sure where exactly it is. Here's my code:
strSelected = "UPDATE CFRRR SET assignedby = " & Me.cmbassignedby.Column(1) & ", assignedto = " & _
Me.cmbassignedto.Column(2) & ", Dateassigned = " & Now() & ", actiondate = " & _
Now() & ", Workername = " & Me.cmbassignedto.Column(2) & ", WorkerID = " & _
Me.cmbassignedto.Column(1) & " WHERE CFRRRID In ( " & strSelected & " );"
CurrentDb.Execute strSelected
It's most likely because of the Now() function, which also prints the current time (seperated with a space) - hence the syntax error. Try to surround them with single quotation marks.
You can also print out the SQL Statement
Debug.Print strSelected to see what you have concatenated...
I'm calling the ExecuteQuery method of my DataContext object. I expect a String and an Integer for each row as a result but all my values are nothing and 0 when I run the ToList function. All my results should be different strings and numbers. My query runs perfectly if I run it directly, but ExecuteQuery returns garbage instead of valid results. What can be the cause of this?
Thank you in advance.
Edit:
public function something as List(of Pair(of String, Integer))
Dim c As TTDataContext = ContextFactory.CreateDataContext()
Dim startValueLen = CStr(StartValue).Length
Dim query As String = "select top " & CStr(Limit) & " case " &
" when WONum like '0000%' then SUBSTRING(WONum, 5, Len(WONum) - 4) " &
" when WONum like '000%' then SUBSTRING(WONum, 4, Len(WONum) - 3) " &
" when WONum like '00%' then SUBSTRING(WONum, 3, Len(WONum) - 2) " &
" when WONum like '0%' then SUBSTRING(WONum, 2, Len(WONum) - 1) " &
" else WONum " &
" end as retVal, " &
" case " &
" when WONum like '0000%' then 1 " &
" when WONum like '000%' then 2 " &
" when WONum like '00%' then 3 " &
" when WONum like '0%' then 4 " &
" else LEN(WONum) " &
" end as retLen " &
" from TblWorkOrder " &
" where CompanyID = " & CStr(CompanyID) & " and LEN(WONum) >= " & CStr(startValueLen) & " and (WONum > '" & CStr(StartValue) & "' or LEN(WONum) > " & CStr(startValueLen) & ") " &
" order by retLen, retVal"
Dim temp = c.ExecuteQuery(Of Pair(Of String, Integer))(query)
Return temp.ToList
End Function
The cause of the problem was that my Pair class had a First and a Second property and I didn't return my results as First and as second. So the solution for the problem is to return the first value as First and the second value as Second instead of retVal and retLen.
I want to select all the Female patients from the patient table where the area = south or area= west and then group the result by Disease name
So I had to write the where condition like this :
command10.CommandText = "SELECT D.DiseaseName, COUNT(D.Patient_ID) AS PNO FROM PatientAffectDisease D INNER JOIN patient P on D.Patient_ID = P.Patient_ID WHERE P.Gender='" & "female" & "'" & " AND P.Area='" & "south" & " '" & "OR P.Area='" & "west" & " '" & " GROUP BY DiseaseName "
But this doesn't return the right result.
Any Idea?
Put parenthesis around your OR'd conditions
e.g.
WHERE P.Gender='" & "female" & "'" & " AND
(P.Area='" & "south" & " '" & "OR P.Area='" & "west" & " '" & ")
or just use an IN clause ...
where p.gender = 'female' and p.area in ('south', 'west')
The issue is that you had extra spaces after south and west with this code: " '"
You were trying to find 'south ' or 'west ', not 'south' or 'west'.
You can also modify this condition to use an IN clause.
command10.CommandText = "SELECT D.DiseaseName, COUNT(1) AS PNO FROM PatientAffectDisease D INNER JOIN patient P on D.Patient_ID = P.Patient_ID WHERE P.Gender='female' AND P.Area IN ('south', 'west') GROUP BY DiseaseName"
I think the problem is in your where clause specifically related to not using parentheses.
command10.CommandText =
"SELECT D.DiseaseName, COUNT(D.Patient_ID) AS PNO " & _
" FROM PatientAffectDisease D " & _
" INNER JOIN patient P on D.Patient_ID = P.Patient_ID " & _
" WHERE P.Gender='female' AND P.Area in ('south','west') " _
" GROUP BY DiseaseName "
Here is the text of your query:
SELECT
D.DiseaseName,
COUNT(D.Patient_ID) AS PNO
FROM PatientAffectDisease D
INNER JOIN patient P on D.Patient_ID = P.Patient_ID
WHERE P.Gender='female'
AND P.Area='south '
OR P.Area='west '
GROUP BY DiseaseName
In SQL, the AND naturally has precendence over the OR.
So you're effectively asking
WHERE (P.Gender='female' AND P.Area='south') OR (p.Area = 'west' )
You must use brackets to explicitly state the precedence you need
WHERE P.Gender='female' AND (P.Area='south' OR p.Area='west')
The reason your posted query isn't working properly is because you have an extra space after 'west' and 'south' in the generated query.
You should always group your logic with () to make it easier to maintain and understand the code - and keep away from bugs such as this one.
AND binds harder than OR, so what you had earlier was the same as writing:
(P.Gender = 'female' AND P.Area = 'west') OR P.Area = 'south' -- not correct
Instead of using P.Area = 'west' OR P.Area = 'south' you can use the IN operator, as in the below example:
SELECT D.DiseaseName, COUNT(D.Patient_ID) AS PNO
FROM PatientAffectDisease D
INNER JOIN patient P ON D.Patient_ID = P.Patient_ID
WHERE P.Gender = 'female' AND P.Area IN ('west','south')
GROUP BY D.DiseaseName
command10.CommandText = "SELECT D.DiseaseName, COUNT(D.Patient_ID) AS PNO FROM PatientAffectDisease D INNER JOIN patient P ON D.Patient_ID = P.Patient_ID WHERE P.Gender = 'female' AND P.Area IN ('west','south') GROUP BY D.DiseaseName"