Is Salesforce SOQL GROUP BY case sensitive for different locales? - group-by

Lets say I have records with values like 'TEST DATA' and 'test data' in some field. When I run SOQL (in Developer Console or from Apex) by user with EN locale, it arranges records with 'TEST DATA' and 'test data' values to one group, but when I run same query by user with non-English locale (or same user after switching locale to non-English), it separates records to different groups.
I tried several different non-English locales, like Spanish, German, Italian, and it works same.
The example of SOQL query is:
SELECT MyField__c MyField__c_2, GROUPING(MyField__c) grouping_MyField__c_2, SUM(Amount) SUM_Amount, count(Id) cnt
FROM Opportunity
GROUP BY ROLLUP(MyField__c)
ORDER BY GROUPING(MyField__c) desc, MyField__c desc NULLS LAST
I think it should work same for any locales, and not sure why it's not. I know that in Salesforce SOQL sort order is determined by current user locale, but I observe same behavior for group by also, and don't know if this is correct behavior or not.

Related

In SSRS, can you group multiple parameter values into one?

I am relatively new to SSRS but have been working with SQL for years. I have been tasked with creating a report that reflects shipped items based on their status. For example, I have x number of items with varying statuses including "IN_TRANSIT", "RECEIVING", "SHIPPED", "WORKING", and "CLOSED". The requestor is asking if I can provide the following options in a report drop down:
"IN_PROCESS" Status filter including all statuses except "CLOSED".
"CLOSED".
Essentially, they want to be able to view all non closed statuses, closed, statuses, or all. Right now, I have it set so you can individually select all statuses, essentially getting them the data they want, just not with the "right" parameters.
My question is, does SSRS provide a way to essentially 'group' the non-closed statuses into one inside the report so that when they select "IN_PROCESS" it sends those non-closed statuses to the SQL query I have built in? The problem with using SQL for this is that the dataset I created to generate the dropdown options provides "CLOSED" and "IN_PROCESS" as it's output options, but when they select "IN_PROCESS" (sending that value to the filter in the report), since it's not an actual status, nothing comes back.
If more information or clarification is required, please let me know.
Thanks ahead of time!
You can create a new column in your SQL query and use a CASE statement to give the value of IN_PROCESS or CLOSED for the applicable status. Then you will just need to the filtering condition to match the SSRS parameter to the new column.
Depending on how often this case is likely to be reused should help determine how to approach it. If it sounds like it might become a regular process.... "Oh can we have another report with the same filter but showing xyz " then take the time to setup correctly and it will save time in the future.
Personally I would add a database table, if possible, that contains the status names and then a status group name (ignoring fully normalising for the sake of simplicity here).
CREATE TABLE StatusGroups(Status varchar(10), StatusGroup varchar(10))
INSERT INTO StatusGroups VALUES
('IN_TRANSIT', 'In Process'),('RECEIVING, 'In Process'),('SHIPPED', 'In Process'),('WORKING', 'In Process'),('CLOSED' 'Closed')
Then a simple view
CREATE MyNewView AS
SELECT t.*, g.StatusGroup
FROM MyTable t
JOIN StatusGroups g on t.STATUS = g.Status
Now change your report dataset query to use this view passing in the report parameter like this...
SELECT *
FROM MyNewView
WHERE StatusGroup = #myReportParameter
Your dataset for your report parameter's available values list could then be something like
SELECT DISTINCT StatusGroup FROM StatusGroups
This way if you every add more status or statusgroup values you can add an entry to this table and everything will work without ever having to edit your report.

First Access date or Enrolled date for a specific course

I would really appreciate any help with this dilemma !
I need a report that just lists out the exact date when a user has enrolled into a specific course (or First access). i.e. if the user is enrolled in two courses on the site on two different dates, I need the exact date when the user commenced each course. (either enrolled or access)
I believe the role assignment date for the specific course should do the trick, but how do I get the 'role assigned' date for all users of a course ?
I tried setting up a SQL query as below. It gives me the list of users, the courses they are enrolled into etc.
However, it is giving me the same creation / access date for all the course - which is the site level date. How do I get the course level start or role assignment date ?
I would really appreciate any help. I am really at my wits end !
user2.firstname AS Firstname,
user2.lastname AS Lastname,
user2.email AS Email,
user2.city AS City,
DATE_FORMAT(FROM_UNIXTIME(user2.firstaccess), '%Y-%m-%d %H:%i') AS 'Firstaccess',
DATE_FORMAT(FROM_UNIXTIME(user2.timecreated), '%Y-%m-%d %H:%i') AS 'Timecreated',
course.fullname AS Course
,(SELECT shortname FROM prefix_role WHERE id=en.roleid) AS ROLE
,(SELECT name FROM prefix_role WHERE id=en.roleid) AS RoleName
FROM prefix_course AS course
JOIN prefix_enrol AS en ON en.courseid = course.id
JOIN prefix_user_enrolments AS ue ON ue.enrolid = en.id
JOIN prefix_user AS user2 ON ue.userid = user2.id
Moodle version 3.5 -
You cannot get first course access in moodle 3+. This action is not logged anymore, you can only get last access.
As for enrolment time (TimeCreated), try this:
SELECT u.username, u.lastname, u.firstname, c.fullname, DATE_FORMAT(FROM_UNIXTIME(ue.timecreated), '%Y-%m-%d %H:%i') AS 'Timecreated' FROM prefix_user_enrolments ue LEFT JOIN prefix_enrol e ON (ue.enrolid = e.id) LEFT JOIN prefix_course c ON (e.courseid = c.id) LEFT JOIN prefix_user u ON (ue.userid = u.id)
First access actually makes no sense, since enrolment time will always be the earliest date between two. Even if user uses self-enrolment. Guest course access is probably the only exception, but it doesn't require user id, so it will make your report inconsistent anyway. So 99% of the time you would want to check upon user enrolments exactly, and the earliest date is always enrolment time.
If your moodle version is less than 3, you may get first access via prefix_log
You can retrieve the first access to the course by querying the mdl_logstore_standard_log for the event "\core\event\course viewed" eventname.
SELECT * FROM mdl_logstore_standard_log
WHERE eventname LIKE "%course_viewed%"
AND userid=##
timecreated is the specific field you're looking for
If a user is not enrolled in the course and they view the enrollment page (for that course), the course viewed event is not fired. So you shouldn't get any false positives.

SQL Reporting Services, filtering on Field not in DISTINCT SELECT statement?

I am using MS SQL Report Builder 3.0 to generate a report for SQL Reporting Services. I have a dataset that includes the columns AppointmentDate, PatientID, and InsuranceCarrier. I want to find out the number of DISTINCT patients that visited within a certain timeframe (begining AppointmentDate to ending AppointmentDate). The only time a patient should be present more than once in the query is if they had a different insurance carrier on a repeat visit.
If I perform the following query:
SELECT DISTINCT AppointmentDate, PaientID, InsuranceCarrier
FROM Encounters
WHERE AppointmentDate >= #beginningofdaterange
AND AppointmentDate <= #endofdaterange
Then I get a list of each patient and insurance carrier that visited in that date range. Unfortunately, since each AppointmentDate is also distinct, the Patients get duplicated for each individual appointment date. For example, if Patient X shows up twice in that timeframe specified, it will show both appointments.
If I remove the AppointmentDate from my SELECT statement, then under Dataset properties in the Report Builder 3.0 I can no longer Filter based on the AppointmentDate expression. I could do my filtering directly in the WHERE clause of the T-SQL statement, but that means I cannot use the run-time Report Parameters input by the user. This is a problem because I am filtering based on Report Parameters that the user selects when running the report. They input the starting AppointmentDate and a "18-months prior" Parameter is calculated as the beginning and end AppointmentDates to filter against.
So how do I include the AppointmentDate so that I can filter with it, but not include it in my DISTINCT SELECT so that it properly DISTINCTifies my data.
#FreefallGeek,
What do you mean by you can't filter AppointmentDate if you remove it from SELECT? Report Builder allows you do dataset filtering based on the user assigned parameter in run time with query like this,
SELECT DISTINCT PaientID, InsuranceCarrier
FROM Encounters
WHERE
AppointmentDate >= #beginningofdaterange
AND AppointmentDate <= #endofdaterange
With #beginningofdaterange and #endofdaterange as your report parameter. This should work unless you need to do additional filtering that require to return AppointmentDate as result.
If you really need to return the Appointment date as result or for additional filtering, then the next question is what should be the AppointmentDate when there are multiple visit with same patient and insurance carrier? The first visit or the last visit within the date range? If that is the case, you could use group by like this for first visit,
SELECT Min(AppointmentDate) AS FirstAppointmentDate, PaientID, InsuranceCarrier
FROM Encounters
WHERE
AppointmentDate >= #beginningofdaterange
AND AppointmentDate <= #endofdaterange
GROUP BY PaientID, InsuranceCarrier
ORDER BY AppointmentDate
However, from your description, it appears that you only need the distinct patient and insurance carrier with the capability to filter the date. If that understanding is correct, you could just filter the appointment with user input parameter in the WHERE clause without the SELECT.
In this particular case, I would take into account all visits per the entire day. And instead of displaying multiple encounters per patient per day, I would go to display for the report as AppointmentDate only the day part of the AppointmentDate itself. As the filtering might not need the exact moment of the visit, but only the fact that it took place. The resulting set would be then filtered by the report.
Your particular select would look like the following:
-- small modification (take encounters by entire day):
SELECT DISTINCT
CAST(e.AppointmentDate as Date) as AppointmentDateDay, -- the day of the visit
e.PatientID,
e.InsuranceCarrier,
COUNT(e.Id) as CntVisits -- display them if you'd like
FROM Encounters as e
WHERE AppointmentDate >= '20130624 10:00:00'
AND AppointmentDate <= '20130625 18:00:00'
GROUP BY PatientID, InsuranceCarrier, CAST(e.AppointmentDate as Date)
ORDER BY PatientId;
Example Fiddle - see both result sets.
If you really need to show the entire AppointmentDate to the user, I admit I don't have an idea now.

Jasper Reports Group VS Oracle Order By

I have a report that I am in the process of converting from Crystal Reports to JasperReports. I am designing the report using iReport 4.5 and JasperReport Server 4.5. Oracle Stored Procedure that returns REF_CURSORS is used to populate data. Below is a sample SQL:
Select First_Name, Last_Name, DOB, City From PPL Order By DOB;
When I use this SQL in the report designer and design a report and I create groups as follows
Parent Group is First_Name
Second Group is City
Basically I want to group all the people with similar first name in the all the cities it applies.
Expected results:
First_Name Last_Name DOB City
Alan Kum 10/01/2010 Mumb
Alan Boss 01/10/2001 Mumb
Alan Cross 10/10/2000 Irvn
But since the SQL has an order by clause my data is not displayed in the expected manner as displayed above. How do I overcome this issue?
The issue is I can not change the procedure as it's being used in the application and also an Excel version of the report uses the same query where they want to see the data in order by DOB.
Well... the "correct" solution is to change the query to order by the fields you want to order by: First_Name, City (and then perhaps by DOB or Last_Name to have a fully deterministic ordering).
But since you don't have that option available to you, you can instead do the sorting in JasperReports. Edit your query and then click the button "Sort options...". This should allow you to re-sort the data as you like. It will be slower sorting in the report engine, but slower and correct is far better than a quick result which doesn't meet your needs.

Show Report group even when no records selected

I'm trying to show employees at a company grouped by worked and still working (in vs2005 crystal reports).
The user can pass by parameter a list of companies they want to show.
Tables: VRP-COMPANY, VRP-COMPANY-OPPORTUNITY, VRP-OPPORTUNITY-PRODUCT
The record selection formula: {VRP-COMPANY.COMPANY company} in {?companies}
Grouping is done on: VRP-COMPANY.COMPANY company, then formula to decide its working or worked and then on productname.
Now when I run the report I only get to see the companies who have got entries in the VRP-COMPANY-OPPORTUNITY. I want to see the company name (group) even if there are no entries in the opportunity table. How to do this in Crystal Reports? I tried Left join between company and company-opportunity tabel but no effect.
I found the problem. Left join was correct but I had an additional select formula (on opportunity status to be closed-won. Therefore it let out the record. The record can also be null when there are no opportunities.
Should the question be deleted?