DAX query to check values in multiple rows - powerpivot

Need help to create a DAX for the below.
EventID CFStatus ManualRowStatus CalculatedRowStatus
1 Paid Count
1 Waived Ignore
2 Paid Count
2 Paid Count
3 Waived Count
3 Waived Count
If CFStatus has both 'Paid' and 'Waived' for a given EventID, then CalculatedRowStatus field should be marked as "Count" for the "Paid" row and "Ignore" for the "Waived" row.
For all other combinations, CalculatedRow status should be marked as "Count".
In short, CalculatedRowStatus column should show same result as that of ManualRowStatus as shown in the picture.
Any help is appreciated.
Thanks in Advance.
Ramesh.

Combination of a standard bit of excel type nested IF() and a CALCULATE() that checks for records of that event id with a paid status:
=
IF (
[CFStatus] = "Paid",
"Count",
IF (
CALCULATE (
COUNTROWS ( 'table' ),
FILTER (
'table',
[EventID] = EARLIER ( [EventID] )
&& [CFStatus] = "Paid"
)
)
> 0,
"Ignore",
"Count"
)
)

Related

Power BI - Using Dax to Filter Based on a Group By

I am new to DAX.
Let's pretend I have a table that looks like this:
Table A:
status delivered sold
late 10 50
late 20 300
early 5 500
Let's pretend I am using this SQL query:
with cte_1 as (
select
status, count(*) as [row_count]
from [table a]
group by [status]
having count(*) > 1
)
select *
from [table a] as p1
inner join [cte_1] as p2
on p1.[status] = p2.[status]
What would be the dax equivalent of this?
The SQL query return the Table A rows with the status that occurrs at least twice in the table, adding the count of the number of rows with the same status. In Power BI we can write a calculated table that adds the count of the rows of the same status and then filter out those with a count less than 2
Result =
FILTER(
ADDCOLUMNS(
'Table A',
"row_count",
CALCULATE(
COUNTROWS( 'Table A' ),
ALLEXCEPT( 'Table A', 'Table A'[Status] )
)
),
[row_count] > 1
)

How do I do conditional logic between rows of a bigquery table?

I'm trying to write a query that goes through a table row by row comparing the current row with the next. Then based on a condition being true will perform a calculation which is then output in a column on the same table and a null value if false.
Consider the example above:
Row 8703 will be referred to as Row 1
Row 8704 will be referred to as Row 2
I would like to, if possible, compare Row 1 bookedEnd with Row 2 bookedStart. If they are of equal value (which in this case they are) I would like to subtract Row 2 actualStartdate from Row 1 actualEnddate and output the value in minutes in a separate column named 'difference' on Row 2.
If they are not of equal value (which is true for all other columns in the example above) I would like to output a null value.
For the above table the extra column named difference would have the row values of:
8701 - Null
8702 - Null
8703 - Null
8704 - 12
8705 - Null
Since you are writing to "Row 2", I use the LAG() function so you are comparing on the row you are writing.
with data as (select * from `project.dataset.table`),
lagged as (
select
*,
lag(bookedEnd,1) over(partition by roomID order by Row asc) as prev_bookedEnd,
lag(actualEnddate,1) over(partition by roomID order by Row asc) as prev_actualEnddate
from data
)
select
* except (prev_bookedEnd,prev_actualEnddate),
case when prev_bookedEnd = bookedStart then timestamp_diff(prev_actualEndDate,actualStartdate, minute) else null end as difference
from lagged
What you will want to do in this scenario is use the lead function
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#lead
it would look similar to
SELECT bookedEnd
, CASE WHEN bookedEnd = LEAD(bookedStart) OVER (PARTITION BY roomid ORDER BY Row) then XXXX END as actualStartdate
, CASE WHEN bookedEnd = LEAD(bookedStart) OVER (PARTITION BY roomid ORDER BY Row) then XXXX END as difference
SELECT
*,
IF( LAG(bookedEnd) OVER (PARTITION BY roomId ORDER BY bookedStart) = bookedStart,
TIMESTAMP_DIFF( actualStartdate,
LAG(actualEnddate) OVER (PARTITION BY roomId ORDER BY bookedStart),
MINUTE
),
NULL
) AS difference
FROM `project.dataset.table`

Count + IIF - Access query

Employees of the company are divided into categories A, B and C regardless of the division they work in (Finance, HR, Sales...)
How can I write a query (Access 2010) in order to retrieve the number of employees for each category and each division?
The final output will be an excel sheet where the company divisions will be in column A, Category A in column B, category B in column and category C in column D.
I thought an IIF() nested in a COUNT() would do the job but it actually counts the total number of employees instead of giving the breakdown by category.
Any idea?
SELECT
tblAssssDB.[Division:],
COUNT( IIF( [Category] = "A", 1, 0 ) ) AS Count_A,
COUNT( IIF( [Category] = "B", 1, 0 ) ) AS Count_B,
COUNT( IIF( [ET Outcome] = "C", 1, 0 ) ) AS Count_C
FROM
tblAssssDB
GROUP BY
tblAssssDB.[Division:];
My aim is to code a single sql statement and avoid writing sub-queries in order to calculate the values for each division.
Count counts every non-Null value ... so you're counting 1 for each row regardless of the [Category] value.
If you want to stick with Count ...
Count(IIf([Category]="A",1,Null))
Otherwise switch to Sum ...
Sum(IIf([Category]="A",1,0))
Use GROUP BY instead of IIF. Try this:
SELECT [Division:], [Category], Count([Category]) AS Category_Count
FROM tblAssssDB
GROUP BY [Division:], [Category];
Try this Count:
Count(IIf([Field1]="N",1))+Count(IIf([Field2]="N",1)) ...
I grouped my qry and place Expression under this Count field I created. It worked for me
Select count(iif(fieldname='a',1,null)) as asde
from [table name]
where .....

Get a unique row based on a column item in SQL query

I have a sql query to return IT tickets and their satisfaction scores however because of the way our ticketing system works this sometimes returns 2 rows for a ticket reference - 1 with a "Not Rated" rating and one with the real rating.
My question is, is there a way to get the query to only return a single row for each Ticket Reference and only return the "Not Rated" rating if another rating does not exist. i.e. when there are 2 rows with the same ticket reference and one has a rating of "Excellent" and one has a rating of "Not Rated" that it only returns the row with the "Excellent" rating. Any with only 1 row that is "Not Rated" should be returned.
The query looks like this so far -
SELECT DISTINCT
t.Rating_Date,
t.id AS 'Ticket Reference',
[Rating]
= CASE
When tt.[rating_id] = 20 then 'Poor'
When tt.[rating_id] = 15 then 'Average'
When tt.[rating_id] = 17 then 'Good'
When tt.[rating_id] = 6 then 'Excellent'
else 'Not Rated'
END,
[subject],
[priority],
[status],
uu.name,
[assignee_id],
[Location],
[technology]
FROM
[DB1].[dbo].[table1] t
INNER JOIN [DB1].[dbo].[table2] tt
ON t.id=tt.ticket_id
LEFT JOIN [DB1].[dbo].[table3] uu
ON t.assignee_id=uu.id
WHERE
t.rating_date > '2013-07-01'
AND status = 'closed'
AND location = 'UK'
AND technology <> 'Not Known'
AND group_id = '5678912'
ORDER BY
t-rating_date
I think you can wrap the first query, order it by rating_id (if Not rated value is 0 you should order DESC, if Not rated is the highest you should order ASC) and then select the first record using the TOP function of sql-server.
I suppose that the following logic can be implemented here. Please, be aware of that I am using sample data and in order to implement the solution you should understand the idea.
Let's say we have the following data:
Note: I am using id "0" for "Not Rated" status.
If I have understand your need correctly, the output data should be something like this:
As you can see from the screenshot above, for Tickets with IDs 1 and 4 we have "Not Rated" records, but we are not showing them. The "Not Rated" state is displayed only for Ticket with ID 3.
The solution:
;WITH DataSource AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY [TicketID] ORDER BY [TicketRateID] DESC) AS [RowNumber]
,[TicketID]
,[TicketRateID]
FROM #DataSource
)
SELECT [TicketID]
,[RowNumber]
,[TicketRateID]
FROM DataSource
The SQL statement above is using ROW_NUMBER function in order to create a unique ID for each set of records for given tickets. We are sorting the records with DESC directive in order to be sure the "0"/"Not rated" records will have bigger ID.
The output of previous statement is:
As you can see from the screenshot above, we need to display only this records with RowNumber equal to 1. This is done simple with WHERE clause.
Follows, full working example:
SET NOCOUNT ON
GO
DECLARE #DataSource TABLE
(
[TicketID] TINYINT
,[TicketRateID] TINYINT
)
INSERT INTO #DataSource ([TicketID],[TicketRateID])
VALUES (1,6)
,(1,0)
,(2,20)
,(3,0)
,(4,0)
,(4,15)
;WITH DataSource AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY [TicketID] ORDER BY [TicketRateID] DESC) AS [RowNumber]
,[TicketID]
,[TicketRateID]
FROM #DataSource
)
SELECT [TicketID]
,[RowNumber]
,[TicketRateID]
FROM DataSource
WHERE [RowNumber] = 1
SET NOCOUNT OFF
GO

Find Duplicates in SQL and UPDATE them?

I'm trying to find all duplicates in a Table and change one of their values.
Now i use:
SELECT Amount
FROM Bids
GROUP BY Amount, AuctionID
HAVING ( COUNT(Amount) > 1 ) AND (AuctionID=1)
The problem that it returns only
Amount
23.6500
41.8800
42.3500
And not
Amount
23.6500
23.6500
41.8800
41.8800
42.3500
42.3500
So I can't UPDATE all the rows.
How can I get it the way I showed?
Thanks,
Dan
Just wrap it inside an IN query:
SELECT Amount
FROM Bids
WHERE Amount IN (
SELECT Amount
FROM Bids
GROUP BY Amount, AuctionID
HAVING ( COUNT(Amount) > 1 ) AND (AuctionID=1)
)
UPDATE: added UPDATE statement
UPDATE Bids
SET Burned = 1
WHERE Amount IN (
SELECT Amount
FROM Bids
GROUP BY Amount, AuctionID
HAVING ( COUNT(Amount) > 1 ) AND (AuctionID=1)
)
Assume that you have Id in Bids table:
SELECT Amount
FROM Bids b1
WHERE AcutionId = 1
AND EXISTS (Select 1 from Bids b2
WHERE b2.AuctionID = b1.AuctionId
AND b1.Amount = b2.Amount
AND b1.Id <> b2.Id)
I'm curious to know why your original select doesn't satisfy your requirement. If for every member within a set of duplicates you're only selecting one of them, then you have one to update. It should be informative to add AuctionId to the select provided by Frank Schmitt to see what distinguishes these rows.