streamlit, st_aggrid, possible to do enableColumnGroup=True to perfectly mimic pivottables? - pivot-table

https://streamlit-example-app-interactive-table-streamlit-app-mt9qg6.streamlit.app/
allows to group by rows
would it be possible to group by columns as well ? it would then completely fill pivot tables role

Based on the docs for streamlit-aggrid, it looks like you can do builder.configure_default_column(groupable=True)

Related

Groupby and count() with alias and 'normal' dataframe: python pandas versus mssql

Coming from a SQL environment, I am learning some things in Python Pandas. I have a question regarding grouping and aggregates.
Say I group a dataset by Age Category and count the different categories. In MSSQL I would write this:
SELECT AgeCategory, COUNT(*) AS Cnt
FROM TableA
GROUP BY AgeCategory
ORDER BY 1
The result set is a 'normal' table with two columns, the second column I named Count.
When I want to do the equivalent in Pandas, the groupby object is different in format. So now I have to reset the index and rename the column in a following line. My code would look like this:
grouped = df.groupby('AgeCategory')['ColA'].count().reset_index()
grouped.columns = ['AgeCategory', 'Count']
grouped
My question is if this can be accomplished in one go. Seems like I am over-doing it, but I lack experience.
Thanks for any advise.
Regards, M.
Use parameter name in DataFrame.reset_index:
grouped = df.groupby('AgeCategory')['ColA'].count().reset_index(name='Count')
Or:
grouped = df.groupby('AgeCategory').size().reset_index(name='Count')
Difference is GroupBy.count exclude missing values, GroupBy.size not.
More information about aggregation in pandas.

SQL join with same if exists, if not, any

I need to update a column with the prices of products. The product can be identical as the order or can be similar to the order.
When te product is identical, it's easy.
But when the product is similar, not all the characteristics are equal to the order table, and I don't know how to do the match.
So far, I've writed a query like this:
Update #SelledProducts
Set S.Price=O.Price
FROM
#SelledProducts S, #OrdersWithPrice O
WHERE S.MandatoryCharacteristic1=O.MandatoryCharacteristic1
AND S.MandatoryCharacteristic2=O.MandatoryCharacteristic2
AND S.MandatoryCharacteristic3=O.MandatoryCharacteristic3
--Te following is wrong:
...
AND S.OptionalCharacteristic1=O.OptionalCharacteristic1
AND S.OptionalCharacteristic2=O.OptionalCharacteristic2
But of course it's not working when the OptionalCharacteristics are not equal. With optional characteristic, I mean:
The order can have a red box, but if there are no red boxes, there can be any color boxes for the same order.
How can I achive this? I'm using SQL Server 2008.
Thanks
You can use OR Condition instead of AND in your query for optional Characteristics.
Please find below example for it.
Update #SelledProducts
Set S.Price=O.Price
FROM
#SelledProducts S, #OrdersWithPrice O
WHERE S.MandatoryCharacteristic1=O.MandatoryCharacteristic1
AND S.MandatoryCharacteristic2=O.MandatoryCharacteristic2
AND S.MandatoryCharacteristic3=O.MandatoryCharacteristic3
--Te following is wrong:
...
AND ( S.OptionalCharacteristic1=O.OptionalCharacteristic1
OR S.OptionalCharacteristic2=O.OptionalCharacteristic2)

SQL Select on Records that Meet Criteria from Another Table

I've got a very complex query and trying to give a simple example of one of the sub-tables I'm having problems with, if you need more information or context please let me know.
I've posed a CSV file with some sample data here:
https://drive.google.com/open?id=0B4xdnV0LFZI1dzE5S29QSFhQSmM
We make cakes, and 99% of our cakes are made by us. The 1% is when we have a cake delivered to us from a subcontractor and we 'Receive' and 'Audit' it.
What I wanted to do was to write something like this:
SELECT
Cake.Cake
Instruction.Cake_Instruction_Key
Steps
FROM
Cake
Join Instruction
ON Cake.Cake_Key = Instruction.Cake_Key
JOIN Steps
ON Instruction.Step_Key = Steps.Step_Key
WHERE
MIN(Steps.Step_Key) = 1
This fails because you can't have an aggregate in the WHERE clause.
The desired results would be:
Cake C 13 Receive
Cake C 14 Audit
Cake D 15 Receive
Cake D 16 Audit
Thank you in advance for your help!
Take a look at the HAVING keyword:
https://msdn.microsoft.com/en-us/library/ms180199.aspx
It works more or less the same as the WHERE clause but for aggregate functions after the GROUP BY clause.
Beware however this can be slow. You should try filtering down the number of records as much as possible in the WHERE and even consider using a tempory table to aggregate the data into first.
What you're talking about is the GROUP BY/HAVING clause, so in your case you would need to add something like
GROUP BY Cake.Cake, Instruction.Cake_Instruction_Key, Steps
HAVING MIN(Steps.Step_Key) = 1

Query to list all users of a certain group

How can I use a a search filter to display users of a specific group?
I've tried the following:
(&
(objectCategory=user)
(memberOf=MyCustomGroup)
)
and this:
(&
(objectCategory=user)
(memberOf=cn=SingleSignOn,ou=Groups,dc=tis,dc=eg,dc=ddd,D‌​C=com)
)
but neither display users of a specific group.
memberOf (in AD) is stored as a list of distinguishedNames. Your filter needs to be something like:
(&(objectCategory=user)(memberOf=cn=MyCustomGroup,ou=ouOfGroup,dc=subdomain,dc=domain,dc=com))
If you don't yet have the distinguished name, you can search for it with:
(&(objectCategory=group)(cn=myCustomGroup))
and return the attribute distinguishedName. Case may matter.
For Active Directory users, an alternative way to do this would be -- assuming all your groups are stored in OU=Groups,DC=CorpDir,DC=QA,DC=CorpName -- to use the query (&(objectCategory=group)(CN=GroupCN)). This will work well for all groups with less than 1500 members. If you want to list all members of a large AD group, the same query will work, but you'll have to use ranged retrieval to fetch all the members, 1500 records at a time.
The key to performing ranged retrievals is to specify the range in the attributes using this syntax: attribute;range=low-high. So to fetch all members of an AD Group with 3000 members, first run the above query asking for the member;range=0-1499 attribute to be returned, then for the member;range=1500-2999 attribute.
If the DC is Win2k3 SP2 or above, you can use something like:
(&(objectCategory=user)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=example,DC=com))
to get the nested group membership.
Source: https://ldapwiki.com/wiki/Active%20Directory%20Group%20Related%20Searches
And the more complex query if you need to search in a several groups:
(&(objectCategory=user)(|(memberOf=CN=GroupOne,OU=Security Groups,OU=Groups,DC=example,DC=com)(memberOf=CN=GroupTwo,OU=Security Groups,OU=Groups,DC=example,DC=com)(memberOf=CN=GroupThree,OU=Security Groups,OU=Groups,DC=example,DC=com)))
The same example with recursion:
(&(objectCategory=user)(|(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=example,DC=com)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupTwo,OU=Security Groups,OU=Groups,DC=example,DC=com)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupThree,OU=Security Groups,OU=Groups,DC=example,DC=com)))

Ordering and Limiting A Subquery In Salesforce SOQL

I am attempting to retrieve the owner of a case, based on a partial match, where we choose the most recent case that matches the partial match.
This is the query I am attempting:
SELECT User.CustomField__c
FROM User
WHERE User.Id IN (
SELECT OwnerId
FROM Case
WHERE Case.CaseNumber LIKE '%1026'
ORDER BY Case.CreatedDate DESC LIMIT 1)
The following query works on its own, but doesn't seem happy as part of the subquery:
SELECT OwnerId
FROM Case
WHERE Case.CaseNumber LIKE '%1026'
ORDER BY Case.CreatedDate DESC LIMIT 1
Equally, if I drop the ORDER BY and LIMIT it works:
SELECT User.NVMContactWorld__NVM_Agent_Id__c
FROM User
WHERE User.Id IN (
SELECT OwnerId FROM Case
WHERE Case.CaseNumber LIKE '%1026')
Are order / limit queries not allowed in a SOQL subquery?
Just to clarify this issue, the scenario I am dealing with looks like this...
A Salesforce organisation can configure the "display format" for Case Numbers. If they select "4" digits, you get case numbers like:
0001
0125
1234
33456
It is possible to reconfigure your case numbers to get the following case numbers as well as the case numbers above...
000001
001234
033456
I didn't want people to be confused by the LIKE statement, the issue is that 001234 and 1234 are different cases, so if a customer supplies 1234 and I find two records, I want to start off assuming that they are the most recent case.
So either consider the LIKE statement or an IN statement that contains ('001234', '1234')
There is no documentation I could find that specifies that LIMIT and/or ORDER BY do not work with subqueries, but I ran into the same error you mentioned.
However, it may work to start at the Case object and look up to the User, similar to the Lookup Relationships and Outer Joins section in the SOQL documentation. I'm not sure if this would work for you, but it's something you may want to try.
Here's an example:
-- Edit --
SELECT OwnerId, Owner.CustomField__c
FROM Case WHERE
CaseNumber LIKE '%1026'
ORDER BY CreatedDate DESC
LIMIT 1
Turns out Custom Fields are not accessible because OwnerId is a polymorphic key referencing either Group or User. That means the above won't work, sorry.
To work-around this is very complicated. You would have to create a custom lookup field called "User Owner", or something. That would store a lookup reference to the User, if the Owner is a User (this can be checked by comparing the beginning of OwnerId to '005', the User ID prefix). That field would need to be populated using a after insert, after update Trigger. All values for this new field would need to be dataloaded for previously existing Cases. But, once you have this new "User Owner" field, you can access custom fields on User through SOQL, using it.
ORDER BY and LIMIT don't make sense in your subquery because you're not returning records from the subquery. Instead, the subquery just builds a list of IDs used to filter the main query.
If you use a subquery in a way that the subquery records are returned, these clauses are fine. For example, this works:
SELECT Name,
(SELECT FirstName, LastName FROM Contacts ORDER BY LastName LIMIT 10)
FROM Account
I think it's worth adding that with new features of SOQL that were not available when this question was first asked and answered, that the approach of querying from Case should now be viable (with access to custom fields).
In particular the TYPEOF feature provides access to type specific fields through polymorphic lookups: http://www.salesforce.com/us/developer/docs/soql_sosl/Content/sforce_api_calls_soql_select_typeof.htm
It is worth noting that this feature is still in Developer Preview.
SELECT
TYPEOF Owner
WHEN User THEN CustomField__c
END
FROM CASE
Did you try switching your query around to be something like this?
SELECT OwnerId, (select id from user)
FROM Case
WHERE Case.CaseNumber LIKE '%1026'
ORDER BY Case.CreatedDate DESC LIMIT 1

Resources