Business Objects - Count Distinct Entries - sap

I'm pretty new to Business Objects
I have data for requests which then have a number of status against them. I have used variables to create a flag (of 1) on those with a status of "First_Seen" and "Authorized".
Now for RequestID some only have an Authorized flag, some only have a First_Seen flag and others have both flags. I need to know how many RequestIDs I have irrespective of whether they have 1 or 2 flags (not the total number of flags).
Edit:
Note that some of the RequestIDs have multiple status.
RequestID | Status | First_Seen_Flag | Authorised_Flag |
:----------|:-------------:|:-----------------:|:-----------------:|
123456 | First_Seen | 1 | 1 |
123456 | Authorised | 1 | 0 |
345678 | First_Seen | 1 | 1 |
345678 | Authorised | 0 | 1 |
987654 | First_Seen | 1 | 0 |
765432 | Authorised | 0 | 0 |
I need to count unique RequestIDs where the First_Seen_Flag is 1 of Authorised_Flag is 1 or both flags are 1, bearing in mind that not all RequestIDs have both status or have multiple ie 987654 which only has a single status and 765432 which only has authorized but does not have any flag on it as it did not meet the criteria to be flagged.
Your assistance is much appreciated.
Gareth

To do this you need to create a column doing an "AND" with both flags. Then you can count on this third column.
New column you insert should be something like below formula:
=([First_Seen] = 1) and ([Authorized] = 1)

Related

Postgres: How do I count occurrences of each enum value when they exist in columns as an array?

I have an enum State which can contain values like CA, NY, etc.
If I have a table Users , with a column states that contains an array of State values, so for example {CA, NY} how can I write a query to count the users grouped by each State value? so for {CA, NY} that should count 1 for CA and 1 for NY
So If I had records like:
| id | states |
| -- | ------- |
| 1 | {CA,NY} |
| 2 | {CA} |
| 3 | {NV,CA} |
I would expect a query to output:
| State | count |
| ----- | ----- |
| CA | 3 |
| NV | 1 |
| NY | 1 |
The first piece of advice is to normalise your data. You are breaking 2nd Normal form by holding multiple pieces of information in a single column.
Assuming you can't change that, then you will need to SPLIT the data like this
enter link description here
and you can then COUNT() and group it.

PowerBI / SQL Query to verify records

I am working on a PowerBI report that is grabbing information from SQL and I cannot find a way to solve my problem using PowerBI or how to write the required code. My first table, Certifications, includes a list of certifications and required trainings that must be obtained in order to have an active certification.
My second table, UserCertifications, includes a list of UserIDs, certifications, and the trainings associated with a certification.
How can I write a SQL code or PowerBI measure to tell if a user has all required trainings for a certification? ie, if UserID 1 has the A certification, how can I verify that they have the TrainingIDs of 1, 10, and 150 associated with it?
Certifications:
CertificationsTable
UserCertifications:
UserCertificationsTable
This is a DAX pattern to test if contains at least some values.
| Certifications |
|----------------|------------|
| Certification | TrainingID |
|----------------|------------|
| A | 1 |
| A | 10 |
| A | 150 |
| B | 7 |
| B | 9 |
| UserCertifications |
|--------------------|---------------|----------|
| UserID | Certification | Training |
|--------------------|---------------|----------|
| 1 | A | 1 |
| 1 | A | 10 |
| 1 | A | 300 |
| 2 | A | 150 |
| 2 | B | 9 |
| 2 | B | 90 |
| 3 | A | 7 |
| 4 | A | 1 |
| 4 | A | 10 |
| 4 | A | 150 |
| 4 | A | 1000 |
In the above scenario, DAX needs to find out if the mandatory trainings (Certifications[TrainingID]) by Certifications[Certification] is completed by
UserCertifications[UserID ]&&UserCertifications[Certifications] partition.
In the above scenario, DAX should only return true for UserCertifications[UserID ]=4 as it is the only User that completed at least all the mandatory trainings.
The way to achieve this is through the following measure
areAllMandatoryTrainingCompleted =
VAR _alreadyCompleted =
CONCATENATEX (
UserCertifications,
UserCertifications[Training],
"-",
UserCertifications[Training]
) // what is completed in the fact Table; the fourth argument is very important as it decides the sort order
VAR _0 =
MAX ( UserCertifications[Certification] )
VAR _supposedToComplete =
CONCATENATEX (
FILTER ( Certifications, Certifications[Certification] = _0 ),
Certifications[TrainingID],
"-",
Certifications[TrainingID]
) // what is comeleted in the training Table; the fourth argument is very important as it decides the sort order
VAR _isMandatoryTrainingCompleted =
CONTAINSSTRING ( _alreadyCompleted, _supposedToComplete ) // CONTAINSSTRING (<Within Text>,<Search Text>); return true false
RETURN
_isMandatoryTrainingCompleted

Returning singular row/value from joined table date based on closest date

I have a Production Table and a Standing Data table. The relationship of Production to Standing Data is actually Many-To-Many which is different to how this relationship is usually represented (Many-to-One).
The standing data table holds a list of tasks and the score each task is worth. Tasks can appear multiple times with different "ValidFrom" dates for changing the score at different points in time. What I am trying to do is query the Production Table so that the TaskID is looked up in the table and uses the date it was logged to check what score it should return.
Here's an example of how I want the data to look:
Production Table:
+----------+------------+-------+-----------+--------+-------+
| RecordID | Date | EmpID | Reference | TaskID | Score |
+----------+------------+-------+-----------+--------+-------+
| 1 | 27/02/2020 | 1 | 123 | 1 | 1.5 |
| 2 | 27/02/2020 | 1 | 123 | 1 | 1.5 |
| 3 | 30/02/2020 | 1 | 123 | 1 | 2 |
| 4 | 31/02/2020 | 1 | 123 | 1 | 2 |
+----------+------------+-------+-----------+--------+-------+
Standing Data
+----------+--------+----------------+-------+
| RecordID | TaskID | DateActiveFrom | Score |
+----------+--------+----------------+-------+
| 1 | 1 | 01/02/2020 | 1.5 |
| 2 | 1 | 28/02/2020 | 2 |
+----------+--------+----------------+-------+
I have tried the below code but unfortunately due to multiple records meeting the criteria, the production data duplicates with two different scores per record:
SELECT p.[RecordID],
p.[Date],
p.[EmpID],
p.[Reference],
p.[TaskID],
s.[Score]
FROM ProductionTable as p
LEFT JOIN StandingDataTable as s
ON s.[TaskID] = p.[TaskID]
AND s.[DateActiveFrom] <= p.[Date];
What is the correct way to return the correct and singular/scalar Score value for this record based on the date?
You can use apply :
SELECT p.[RecordID], p.[Date], p.[EmpID], p.[Reference], p.[TaskID], s.[Score]
FROM ProductionTable as p OUTER APPLY
( SELECT TOP (1) s.[Score]
FROM StandingDataTable AS s
WHERE s.[TaskID] = p.[TaskID] AND
s.[DateActiveFrom] <= p.[Date]
ORDER BY S.DateActiveFrom DESC
) s;
You might want score basis on Record Level if so, change the where clause in apply.

How to add data or change schema to production database

I am new to working with databases and I want to make sure I understand the best way to add or remove data from a database without making a mess of any related data.
Here is a scenario I am working with:
I have a Tags table, with an Identity ID column. The Tags can be selected via the web application to categorize stories that are submitted by a user. When the database was first seeded; like tags were seeded in order together. As you can see all the Campuses (cities) were 1-4, the Colleges (subjects) are 5-7, and Populations are 8-11.
If this database is live in production and the client wants to add a new Campus (City) tag, what is the best way to do this?
All the other city tags are sort of organized at the top, it seems like the only option is to insert any new tags at to bottom of the table, where they will end up taking whatever the next ID available is. I suppose this is fine because the Display category column will allow us to know which categories these new tags actually belong to.
Is this typical? Is there better ways to set up the database or handle this situation such that everything remains more organized?
Thank you
+----+------------------+---------------+-----------------+--------------+--------+----------+
| ID | DisplayName | DisplayDetail | DisplayCategory | DisplayOrder | Active | ParentID |
+----+------------------+---------------+-----------------+--------------+--------+----------+
| 1 | Albany | NULL | 1 | 0 | 1 | NULL |
| 2 | Buffalo | NULL | 1 | 1 | 1 | NULL |
| 3 | New York City | NULL | 1 | 2 | 1 | NULL |
| 4 | Syracuse | NULL | 1 | 3 | 1 | NULL |
| 5 | Business | NULL | 2 | 0 | 1 | NULL |
| 6 | Dentistry | NULL | 2 | 1 | 1 | NULL |
| 7 | Law | NULL | 2 | 2 | 1 | NULL |
| 8 | Student-Athletes | NULL | 3 | 0 | 1 | NULL |
| 9 | Alumni | NULL | 3 | 1 | 1 | NULL |
| 10 | Faculty | NULL | 3 | 2 | 1 | NULL |
| 11 | Staff | NULL | 3 | 3 | 1 | NULL |
+----+------------------+---------------+-----------------+--------------+--------+----------+
The terms "top" and "bottom" which you use aren't really applicable. "Albany" isn't at the "Top" of the table - it's merely at the top of the specific view you see when you query the table without specifying a meaningful sort order. It defaults to a sort order based on the Id or an internal ROWID parameter, which isn't the logical way to show this data.
Data in the table isn't inherently ordered. If you want to view your tags organized by their category, simply order your query by DisplayCategory (and probably by DisplayOrder afterwards), and you'll see your data properly organized. You can even create a persistent View that sorts it that way for your convenience.

SQL Query not Working on ORDER BY

I have a SQL Table that I'm trying to query and order the return. I am able to query just fine and the SQL Statement that I'm using is also working with the exception of the last ORDER BY statement that I need to execute. The sort order is as follows:
Sort the Status column so that 'open' is on top, 'closed' on bottom
Order the 'Flag' column so that empty (null) values are on bottom (above Status = Closed) and values on top
Order the results of items 1 and 2 by the Number column
Here is an example of the raw data:
| Flag | Number | Status |
|------------------------|
| a | 1 | open |
| | 5 | open |
| | 3 | closed |
| a | 4 | open |
| a | 2 | closed |
Here is what I'm going for:
| Flag | Number | Status |
|------------------------|
| a | 1 | open |
| a | 4 | open |
| | 5 | open |
| a | 2 | closed |
| | 3 | closed |
The query statement that I'm using is as follows:
sqlCom.CommandText = "SELECT * FROM Questions
WHERE Identifier = #identifier
AND Flag <> 'DELETED'
ORDER BY Status DESC
, (CASE WHEN Flag is null THEN 1 ELSE 0 END) ASC
, Flag DESC
, [Number] * 1 ASC";
Now, everything works fine, but the 3rd item above (sorting by Number column) doesn't work. Any ideas why?
What I'm currently getting:
| Flag | Number | Status |
|------------------------|
| a | 4 | open | <-- Out of order. Should be below the next record
| a | 1 | open | <-- Out of order. Should be one record up
| | 5 | open | <-- OK
| | 6 | open | <-- OK
| | 3 | closed | <-- OK
| a | 2 | closed | <-- OK
Thanks in advance for any helpful input. I have tried fiddling with the query in SSMS but no luck.
Your third sort expression is on Flag. Those values are being sorted alphabetically before the QNumber sort applies. And note that case matters in the ordering as well.
Here's how I would write it:
ORDER BY
Status DESC, -- might be better to use a case expression
CASE WHEN Flag IS NOT NULL THEN 0 ELSE 1 END,
QNumber
Since your data in the examples contradicts the data in the screenshot, it's not clear whether you needed to remove the third sort column entirely or just sort by ignoring the case of the text.