for each List lastname and people they supervise, include All employees must be listed (even those who do not supervise anyone) - postgresql

order by most number of employees supervised, then by last name.
SELECT Lname,COUNT(*)
FROM EMPLOYEE
WHERE Ssn=Super_ssn IS NOT NULL
GROUP BY Super_ssn,lname
The problem here is, I am not sure about what to include in WHERE to actually count those ssn
Example setup:
https://www.db-fiddle.com/f/xhEj2sAgdTMABBkCtJvmoC/0#&togetherjs=z3CKywAccH

Related

PostgreSQL: How to check if a list is contained in another list?

I'm working with PostgreSQL 13.
I have two tables like this:
permission_table
name
permission
Ann
Read Invoice
Ann
Write Invoice
Ann
Execute Payments
Bob
Read Staff data
Bob
Modify Staff data
Bob
Execute Payroll
Carl
Read Invoice
Carl
Write Invoice
risk_table
risk_id
permission
Risk1
Read Invoice
Risk1
Write Invoice
Risk1
Execute Payments
Risk2
Read Staff data
Risk2
Modify Staff data
Risk2
Execute Payroll
I'd like to create a new table containing the names of the employees of the first table whose permissions are pointed as risks in the second table. After the execution, the results should be like this:
name
risk_id
Ann
Risk1
Bob
Risk2
Since Carl only has two of the three permissions belonging to Risk2, he will not be included in the results.
My first brute force approach was to compare the list of permissions belonging to a risk to the permissions belonging to an employee. If the first list is included in the second one, then that combination of employee/risk will be added to the results table.
INSERT INTO results_table
SELECT a.employee, b.risk_id FROM permission_table a, risk_table b WHERE
((SELECT permission FROM risk_table c WHERE b.permission = c.permission ) EXCEPT
(SELECT permission FROM permission_table d WHERE a.employee=d.employee)
) IS NULL;
I'm not sure if the results could be correct using this approach, because if the tables are big, it takes a very long time even if I add a WHERE clause limiting the query to just one employee.
Could you please help?
One way of approaching this one is by
computing the amount of permissions for each "risk_id" value
joining the "permissions" and "risks" table with counts on matching "permission" values
making sure that the distinct count of permissions for each triplet "<permissions.name, risks.risk_id, risks.cnt>" corresponds to the full amount of permissions.
WITH risks_with_counts AS (
SELECT *, COUNT(permission) OVER(PARTITION BY risk_id) AS cnt
FROM risks
)
SELECT p.name, r.risk_id
FROM permissions p
INNER JOIN risks_with_counts r
ON p.permission = r.permission
GROUP BY p.name, r.risk_id, r.cnt
HAVING COUNT(DISTINCT r.permission) = r.cnt
Carl won't be included in the output as he doesn't have all permissions from "risk_id = 'Risk 1'"
Check the demo here.

Postgres SELECT id LAG(id) OVER (ORDER BY id) FROM invoice WHERE id = 2

I've looked all over the internet and I fail to get this query running as expected.
I've got a table of invoices and some invoices are related to one another because they belong to the same project.
My ticket says I've got to get the PREVIOUS invoice based on a provided invoice.
Say Project A has 10 invoices, and I'm looking at invoice #4, I've got to write a query which will return the ID of the previous Invoice. Bear in mind, the invoice table is home to all sorts of projects, and each project could have many invoices on their own, so I want to avoid getting many IDs back and then iterating over them.
To illustrate the issue, I've written this fiddle.
It works somewhat acceptably when I don't filter for steps.id, but that means returning hundreds of IDs to sift through.
I've tried and tried but I can't seem to get the column previousStep to be kind of bound to the ID column.
Simply find the invoice with the next largest id for the same project:
SELECT inv2.id
FROM invoice AS inv1
JOIN invoice AS inv2
ON inv1.project = inv2.project AND inv1.id > inv2.id
WHERE inv1.id = 1057638
ORDER BY inv2.id DESC
LIMIT 1;

Split multiple times in Tableau for Join Condition (Datasource or Worksheet)

I have two EXCEL files and trying to use the customer id from one file to match the customer id's that are included as a part of 2nd file which includes a 300 character. The Customer id in the second file is embedded as a part of the 300 characters.
I need to find-out how I can take the customer ids from the first file (customer file) to join them with the second file that includes the customer transactions.
I can use the Datasource Join options and establish one condition such as below,
Customer ID = SPLIT([Field Number],"_",1) but since this condition is not enough and I need multiple SPLITS to get the customer ID based on other conditions using SPLIT, it is not working within the DataSource Tab-> Join Options.
HOW CAN I DO MULTIPLE SPLITS like
Customer ID = SPLIT([Field Number],"",1) OR Customer ID =
SPLIT([Field Number],"GET",6) OR Customer ID = SPLIT([Field
Number],"TEACH",1)
If I need to do this within the Worksheet, using the calculated field, please let me know how I can use the Calcuated Field option but include all the conditions..
Thanks in advance for your time
Customer File:
Picture of the firest file includings the Customer IDs
Transction file:
enter image description here

TSQL - Deleting with Inner Joins and multiple conditions

My question is a variation on one already asked and answered (TSQL Delete Using Inner Joins) but I have a different level of complexity and I couldn't see a solution to it.
My requirement is to delete Special Prices which haven't been accessed in 90 days. Special Prices are keyed on Customer ID and Product ID and the products have to matched to a Customer Order Detail table which also contains a Customer ID and a Product ID. I want to write one function that will look at the Special Price table for each Customer, compare each Product for that Customer with the Customer Order Detail table and if the Maximum Order Date is more than 90 days earlier than today, delete it from the Special Price table.
I know I can use a CURSOR (slow but effective) but would prefer to have a single query like the one in the TSQL Delete Using Inner Joins example. Any ideas and/or is more information required?
I cannot dig more on the situation of your system but i think and if it is ok for you, check MERGE STATEMENT, it might be a help instead of using cursors. check this Link MERGE STATEMENT

How to remove duplicate records in OpenERP ver 6.1.1

I want to get Employee ID, Leave Reason, Leave type and Employee name for my internal report purpose. I wrote a SQL query to retrieve those data and I got some duplicates also.
Seems it's missing some join / foreign id mapping part missing
select
h.id as employee_id,h.name as leave_reason,
s.name,r.name as res_name
from
hr_holidays_status s,
hr_holidays h,
hr_employee e,
resource_resource r
where
h.employee_id=e.id and
h.holiday_status_id=s.id and
e.resource_id=r.id
order by
resource_id
Your query looks correct, but maybe you're getting unexpected results because the hr_holidays table contains both "Leave Requests" and "Leave Allocations". It's like a double-entry system where leave allocations increase the quantity of leave days available for an employee or an employee category, while leave requests decrease it.
Your query should probably take this distinction into account, and you might also want to filter on other fields like the state, because some of the records may not be validated yet.
Looking at the declaration of the hr.holidays model in 6.1, you will see a few noteworthy fields that could be used in your query:
type: can be Allocation ('add') to represent an increment, or Request ('remove') to represent a decrement
holiday_type: can be Employee ('employee'), in which case the employee_id column indicates which employee, or Category ('category'), in which case the category_id column indicates which category
state: New ('draft'), Waiting Approval ('confirm'), Refused ('refuse'), Waiting Second Approval ('validate1'), Approved ('validate'), Cancelled ('cancel')