Checking for rows relating to previous days which might not exist - tsql

I am having some trouble in my check of whether or not I received prices yesterday for let´s say - my apples.
The tricky part is that in the table where prices are stored, there won´t be any row relating to yesterday if I did not get prices yesterday. So how can I make my check everyday if I want to be sure that the day before I got some prices?

If you have a Calendar table (see here for example) with a field called Date and making some assumptions about your data structure:
SELECT c.[Date],
ISNULL(p.Prices,'No Prices')
FROM Calendar c
LEFT JOIN Prices p ON c.[Date] = p.[Date]
Your question is not very clear, but it actually might even be as simple as just checking for the presence of a row for the previous day, rather than reporting across all dates (in this case I consider there are multiple products):
SELECT DISTINCT
prod.Product,
CASE WHEN prev.Product IS NULL
THEN 'No Prices for yesterday'
ELSE 'Prices recorded for yesterday'
END AS PricesYesterday
FROM Prices prod
LEFT JOIN Prices prev ON prev.Product = prod.Product
AND prev.[Date] = dateadd(day,datediff(day,0,GETDATE()),0) - 1

Related

Creating a column that returns date based on various conditions

Context: I'm fairly new to coding as a whole and is learning SQL. This is one of my practice/training session
I'm trying to create a Dimension Table called "Employee Info" using the Adventureworks2019 public Database. Below is my attempt query to fetch all the data needed for this table.
SELECT
e.BusinessEntityID AS EmployeeID,
EEKey = ROW_NUMBER() OVER(ORDER BY(SELECT NULL)),
p.FirstName,
p.MiddleName,
p.LastName,
p.PersonType,
e.Gender,
e.JobTitle,
ep.Rate,
ep.PayFrequency,
e.BirthDate,
e.HireDate,
ep.RateChangeDate AS PayFrom,
e.MaritalStatus
From HumanResources.Employee AS e FULL JOIN
Person.Person AS p ON p.BusinessEntityID = e.BusinessEntityID FULL JOIN
Person.BusinessEntityAddress AS bea ON bea.BusinessEntityID = e.BusinessEntityID FULL JOIN
HumanResources.EmployeePayHistory AS ep ON ep.BusinessEntityID = e.BusinessEntityID
Where
PersonType='SP'
OR PersonType='EM'
ORDER BY EmployeeID;
Query result
Each employee (EE for short) will have a unique [EmployeeID]. The [EEKey] is simply used to mark ordinal numbers of each record.
EEs are paid different rates shown in the [Rate] column. There will be duplicate records if any EE receives a change in his/her pay rate.
There is currently a [PayFrom] column indicating the first date a pay rate is being applied to each record.
Current requirements: Create a [PayTo] column on the right of [PayFrom] to return the last date each EE is getting paid their corresponding pay rate. There should be 2 scenarios:
If the EE being checked has multiple records, meaning his/her pay rate was adjusted at some point. [PayTo] will return the [PayFrom] date of the next record minus 1 day.
If the EE being checked does not have any additional record indicating pay rate changes. [PayTo] will return a fixed day that was specified (Say 31/12/2070)
Example:
[EmployeeID] no. 4 - Rob Walters with 3 consecutive records in Line 4,5,6. In Line 4, the [PayTo] column is expected to return the [PayFrom] date of Line 5 minus 1 day (2010-05-30). The same rule should be applied for Line 5, returning (2011-12-14).
As for Line 6, since there is no additional similar record to fetch data from, it will return the specified date (2070-12-31), using the same rule as every single-record EE.
As I have mentioned, I am a fresher and completely new to coding, so my interpretation and method might be off. If you can kindly point out what I'm doing wrong or show me what should I do to solve this issue, it will be much appreciated.

Compare 2 Tables When 1 Is Null in PostgreSQL

List item
I am kinda new in PostgreSQL and I have difficulty to get the result that I want.
In order to get the appropriate result, I need to make multiple joins and I have difficulty when counting grouping them in one query as well.
The table names as following: pers_person, pers_position, and acc_transaction.
What I want to accomplish is;
To see who was absent on which date comparing pers_person with acc_transaction for any record, if there any record its fine... but if record is null the person was definitely absent.
I want to count the absence by pers_person, how many times in month this person is absent.
Also the person hired_date should be considered, the person might be hired in November in October report this person should be filtered out.
pers_postition table is for giving position information of that person.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, pos.name, Count(*)
FROM acc_transaction AS tr
RIGHT JOIN pers_person as pers
ON tr.pin = pers.pin
LEFT JOIN pers_position as pos
ON pers.position_id=pos.id
WHERE tr.event_no = 0 AND DATE_PART('month', DATE)=10 AND DATE_PART('month', pr.hire_date::date)<=10 AND pr.pin IS DISTINCT FROM tr.pin
GROUP BY DATE
ORDER BY DATE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
*This is report for octeber,
*Pin is ID number
I'd start by
changing the RIGHT JOIN for a LEFT JOIN as they works the same in reverse but it's confusing to figure them both in mind :
removing for now the pers_position table as it is used for added information purpose rather than changing any returned result
there is an unknown alias pr and I'd assume it is meant for pers (?), changing it accordingly
that leads to strange WHERE conditions, removing them
"pers.pin IS DISTINCT FROM pers.pin" (a field is never distinct from itself)
"AND DATE_PART('month', DATE)=10 " (always true when run in october, always false otherwise)
Giving the resulting query :
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, Count(*)
FROM pers_person as pers
LEFT JOIN acc_transaction AS tr ON tr.pin = pers.pin
WHERE tr.event_no = 0
AND DATE_PART('month', pers.hire_date::date)<=10
GROUP BY DATE
ORDER BY DATE
At the end, I don't know if that answers the question, since the title says "Compare 2 Tables When 1 Is Null in PostgreSQL" and the content of the question says nothing about it.

Segregate Products based on shipping <SQL>

I have 10 different products (A,B,C),..,J)have multiple purchase dates (by various customers) and delivery dates. I want to see which products have the date difference of less than 5 days. If the date difference is less than 5 days, which products have customer rating less more than 3.If the above criteria is satisfied I want to fetch those products that has the minimum date difference from the queue along with the "Important_date".If there are same minimum date difference for a particular product then I would like to select the top one among the same product in recent times and mark the purchase date as the "Important_date".
The columns in the table are: Product,Purchasedate,deliverydate,date_difference,customer_rating.
I am trying to use case statements to solve the problem in PostgreSQL.
I am looking for an output which will give me all the columns of the table along with "Important_date."

Tableau: Getting Aggregate Count Based on Boolean Attributes

I am really new in Tableau and I would be needing help in some calculation.
My simplified data consists of three columns:
customer no, transaction date, lost_flag
here lost_flag is a boolean which marks as true if a customer made a transaction in the last 365 days.
(max([transaction date)< dateadd('year',-1,max([Report Date])))
I need to find the:
1. number of customers that are lost
2. number of customers that are not lost
3. attrition rate
For number one, I initially did
countd(if ([Lost_flag]) then [Customer No] else "" END)
But obviously it did not work.
Note: Customer_No is not unique here since this is a transactional sales data source
Thanks in advance.
First you need to make sure that your lost flag is being calculated at the customer level rather than the transaction level. In order to do this use the following formula, note that it is similar to yours however I have made it be fixed at customer id and also replaced report date with todays date:
Lost Flag = { FIXED [Customer ID]: (max([Transacton Date])<dateadd('year',-1,max(TODAY())))}
This will add a TRUE or FALSE flag against every transaction for a customer.It is important that this is fixed at the customer id level rather than the transaction otherwise all old transactions for a customer will be flagged as lost even if they have a recent transaction.
So in order to see how many customers are lost do the following:
1) drag lost_flag onto the rows shelf
2) drag customer id onto the text mark and then right click- measure - count distinct.

Tableau - Multiple data into one graph, with double dimension on the x-axis

I'm very new to Tableau, and (maybe because of that) struggling with a graph setting. I need to plot a simple line graph showing the ratio between the number of users that returned after registered x days ago and the total number of users that registered x days ago (regardless on the fact that they returned or not). To do this, I have two tables: TableA having (simplifying) USER_ID and DATE_REGISTRATION, and TableB USER_ID and VISIT_DATE. Both table are joined by USER_ID.
I'm able, of course, to plot each individually (i.e. count distinct of USER_ID with DATE_REGISTRATION on the x axis to get the number of new users registered per day), but not able to combine them. I guess the problem is that I'm using either DATE_REGISTRATION or VISIT_DATE on the x-axis, but in this case I can get one or the other info, but not the two combined.
Ultimately, I would like to be able to have, for each date, both the number of users visiting and the number of user who registered.
Thanks a lot in advance.
Raffaele
Well, problem is your database is not ready to generate those analysis. Your table is user_id oriented, meaning you can do lots of analysis centered on the user_id. To do date oriented you need a table like:
Date User_id Type of event
01/01/2014 1234 Registration
02/01/2014 1234 Visit
Then you can drag Date and Type of event to Columns, and COUNTD(User_id) to rows, to get a bar chart that will show, for each day, how many people registered that day and how many people visited that same day.
Additionally, you can still join this table with the one you have, to have the registration date for each user_id. That way you can, for instance, calculate how many days have passed since registration.