How to find the users/roles running highest number of queries - snowflake-cloud-data-platform

How to find the users and corresponding no.of queries executed by the user for all users in snowflake account.
I like to see output some thing like this for all the users.
username no.of queries executed by user
XXXXXXX 50
The below query helps in getting the details of queries executed by single user.
select query_text,
warehouse_name,
database_name,
schema_name,
user_name,
role_name,
execution_status,
error_code,
error_message,
start_time,
end_time
from table(information_schema.QUERY_HISTORY_BY_USER('USERNAME')) -- put username here
order by start_time desc;
Let me know for nay details required.

You can use the Query_history view in the account_usage schema though there will be a little delay in propagating the latest details. You can group by the user_name column.
https://docs.snowflake.com/en/sql-reference/account-usage/query_history.html#query-history-view

Related

Security tower wants Snowflake audit records in SIEM

Our Security group is asking for us to have Snowflake audit records ingested into our on prem SIEM by the end of the quarter. I've found the information_schema.login_history records but I'm struggling to find anything else that the SIEM might want (privilege usage, etc). Any tips on relevant views or functions would be appreciated.
some tables can be used to understand query & login attempts by Snowflake users along with various dimensions. For details take a look at:
https://docs.snowflake.net/manuals/sql-reference/functions/login_history.html
https://docs.snowflake.net/manuals/sql-reference/functions/query_history.html
Here are some of the SNOWFLAKE ACCOUNT_USAGE SCHEMA QUERIES that may come handy.
Access_History ,Query_History will help to find out who and How the Snowflake DB is been accessed and Query History will show the queries executed ,Role ,Warehouse,start time ,end time etc.
Also try to login to Snowsight get the full lineage of a specific Role.
--TO FIND THE ACTIVE USERS IN THE ACCOUNT--
SELECT FIRST_NAME,LAST_NAME,DISPLAY_NAME from "SNOWFLAKE"."ACCOUNT_USAGE"."USERS"
WHERE DELETED_ON IS NULL GROUP BY FIRST_NAME,LAST_NAME,DISPLAY_NAME
ORDER BY FIRST_NAME DESC;
--TO FIND THE ACTIVE USERS AND ROLES IN THE ACCOUNT--
SELECT ROLE,GRANTEE_NAME,GRANTED_BY FROM "SNOWFLAKE"."ACCOUNT_USAGE"."GRANTS_TO_USERS"
WHERE DELETED_ON IS NULL
GROUP BY ROLE,GRANTEE_NAME,GRANTED_BY
ORDER BY GRANTEE_NAME DESC;
--TO FIND THE ACTIVE GRANTS ON ROLES TO OBJECTS--
SELECT PRIVILEGE,TABLE_CATALOG,GRANTEE_NAME,GRANTED_BY FROM "SNOWFLAKE"."ACCOUNT_USAGE"."GRANTS_TO_ROLES"
WHERE DELETED_ON IS NULL
GROUP BY PRIVILEGE,TABLE_CATALOG,GRANTEE_NAME,GRANTED_BY
ORDER BY TABLE_CATALOG;

Snowflake show tables not accessed in last 20 days

There is a situation where I need to clean up my database in snowflake.
we have around 40 database and each database has more than 100 table. Some are getting loaded everyday and some are not, but used everyday.
However, There has been lots of table added for testing and other purpose (by lots of developer and user).
Now we are working on cleaning up un-used table.
We have query_history table which gives us the information of query run in past, however it has field such as database, warehouse, User etc. but not table.
I was wondering is there is any way we can write a query which give us table name not used (DDL and DML b0th) in last 10 days.
select obj.value:objectName::string objName
, max(query_start_time) as QUERY_DATE_TIME
from snowflake.account_usage.access_history
, table(flatten(direct_objects_accessed)) obj
group by 1
order by QUERY_DATE_TIME desc;
The information schema has a tables view and in that you have a last altered column, will that work with you? It will not give you the last accessed table but will give the last altered table. Other than this, there are no easy way to get this information from snowflake at this time. I also needed this feature, I think we should request for this feature.
select table_schema,
table_name,
last_altered
from information_schema.tables
where table_type = 'BASE TABLE'
and last_altered < dateadd( 'DAY', -10, current_timestamp() )
order by table_schema,
table_name;

SQL Server view for PII and Non PII end user

I have situation where I need to create a view which will be used by end user who may have PII and NON-PII permission clearance controlled by AD groups.
Say i have dim_customer which contains four columns ID, Name, DoB, Country. When PII user runs
Select ID, Name, DoB, Country FROM dim_customer
the pii user should get
ID NAME DoB Country
1 John 1999-10-10 US
If the same query is run by NON-PII user then they should get
ID NAME DoB Country
1 PII DATA PII DATA US
So basically same view object is used but data is displayed according to the pii clearance.
I dont want to create two views with pii and non-pii suffix.
I tried column level permission but that means when end user try the above
query they get error "no select permission on Name and DoB Columns"
I have tried Data Masking but that shows "XXXX" and i would prefer "PII
Data".
I am looking for a solution where the query runs successfully and show results as above.
Is this possible in SQL Server ?
thanks in advance
Create two roles, one that allows PII data, and one that doesn't. Put each user into one role or the other. Than write your view
Select
ID,
Name,
CASE
WHEN IS_ROLEMEMBER ('pii_role') = 1 THEN DoB
ELSE 'PII Data'
END as DoB,
Country
FROM dim_customer

Salesforce - Apex - query accounts based on Activity History

Hey Salesforce experts,
I have a question on query account information efficiently. I would like to query accounts based on the updates in an activityHistory object. The problem I'm getting is that all the accounts are being retrieved no matter if there's "complete" activeHistory or not. So, Is there a way I can write this query to retrieve only accounts with activeHistory that has status="complete" and Type_for_reporting='QRC'?
List<Account> AccountsWithActivityHistories = [
SELECT
Id
,Name
,( SELECT
ActivityDate
,ActivityType
,Type_for_Reporting__c
,Description
,CreatedBy.Name
,Status
,WhatId
FROM ActivityHistories
WHERE Status ='complete' and Type_for_Reporting__c = 'QRC'
)
FROM Account
];
You have a WHERE clause on the histories but you still miss one on the Account level.
For example this would return only Accounts that have Contacts:
SELECT Id, Name
FROM Account
WHERE Id IN (SELECT AccountId FROM Contact) // try with NOT IN too
With Activities it's trickier because they don't like to be used in WHERE in that way.
http://www.salesforce.com/us/developer/docs/officetoolkit/Content/sforce_api_calls_soql_select.htm
The following objects are not currently supported in subqueries:
ActivityHistory
Attachments
Event
EventAttendee
Note
OpenActivity
Tags (AccountTag, ContactTag, and all other tag objects)
Task
Additionally the fine print at the bottom of ActivityHistory definition is also a bit discouraging.
The following restrictions on users who don’t have “View All Data” permission help prevent performance issues:
In the main clause of the relationship query, you can reference only
one record. For example, you can’t filter on all records where the
account name starts with ‘A’; instead, you must reference a single
account record.
You can’t use WHERE clauses.
You must specify a limit of 499 or fewer on the number of rows returned in the list.
You must sort on ActivityDate in ascending order and LastModifiedDate in descending order; you can display nulls last. For
example: ORDER BY ActivityDate ASC NULLS LAST, LastModifiedDate DESC.
Looks like you will need multiple queries. Go for Task (or Event, depending for which the custom field is visible), compose a set of AccountIds and then query the Accounts?
Or you can manually filter through list from your original query, copying accounts to helper list:
List<Account> finalResults = new List<Account>();
for(Account a : [SELECT...]){
if(!a.ActivityHistories.isEmpty()){
finalResults.add(a);
}
}

Average Logins per day SQL Query

I have a users table in MSSQL and i want to find out the average number of logins for all users per day?
I am thinking something with division but not entirely sure
the USER table looks like this
[ID]
,[APPLICATION_ID]
,[LOGIN_NAME]
,[EMAIL]
,[MOBILE_PHONE1]
,[MOBILE_PHONE2]
,[TITLE]
,[FIRST_NAME]
,[LAST_NAME]
,[BIRTHDAY]
,[ADDRESS1]
,[ADDRESS2]
,[CITY]
,[COUNTRY_ID]
,[POSTAL_CODE]
,[PO_BOX]
,[HOME_PHONE]
,[OFFICE_PHONE]
,[FAX]
,[REMARKS]
,[DISPLAY_NAME]
,[MAIDEN_NAME]
,[ADDRESS3]
,[ADDRESS4]
,[KEYWORD1]
,[KEYWORD2]
,[KEYWORD3]
,[KEYWORD4]
,[CREATED_BY]
,[CREATED_ON]
,[MODIFIED_BY]
,[MODIFIED_ON]
,[DELETED]
,[DELETED_BY]
,[DELETED_ON]
,[VERSION]
,[IDENTIFICATION_NO]
,[GENDER_REFERENCE_ID]
,[IDENTIFICATION_REFERENCE_ID]
,[registration_date]
,[contact_person]
,[contact_email]
,[alternative_email]
,[electron_card_number]
,[LAST_LOGIN]
,[LAST_SUCCESSFUL_LOGIN]
,[LAST_UNSUCCESSFUL_LOGIN]
From the table you provide, there is no way of calculating an average. To do this, you would need an historical record of user logins.
There is nowhere in that table that tracks when a user has logged in, other than the last time. You need a separarte table to record all logins, then you can calculate the average number per day.

Resources