Qlik Sense count if Null - qlikview

I would like to count the number of employees as of today.
The condition should be
Join Day <= Today <= Resign Date OR Resign Date is blank.
My formula is as below, how can I add the condition that Resign Date is blank?
Count({$<[Join Date]={"<=$(=Today())"}, [Resign
Date]={">=$(=Today())"}>}distinct[Employee Code])

Easier will be not to deal with null in the set analysis :)
If you can create a new field in the script for each employee - ResignedStatus (for example):
...
if( isNull([Resign Date]), 'not resigned', 'resigned') as ResignedStatus,
...
After we have this field then the expression to get the count of not resigned users is simple:
count( {< ResignedStatus= {'not resigned'} >} distinct [Employee Code] )
And the overall expression will be:
Count({$<[Join Date]={"<=$(=Today())"}, [Resign Date]={">=$(=Today())"}>}distinct[Employee Code])
+
count( {< ResignedStatus= {'not resigned'} >} distinct [Employee Code] )

Related

Getting 2 result columns from SQL query

I've tried to make an SQL query to get 2 result columns from 1 query. To elaborate:
This is my query:
SELECT Name, AVG(DATEDIFF(day,[Open Date],[Close Date]))
FROM Inventory Where Tested ='Yes' AND [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name
My result:
My desired result:
When also Where Tested = 'No'
How to write an SQL query with Where Tested = 'Yes' and Where Tested = 'No'? Where Tested = 'Yes' is Column 1 result and Tested = 'No' is Column 2 result.
Database:SQL server 2019
EJC answer with subqueries should already probably help with what you need, but just wanted to share some other options to achieve this:
Joining two separate queries
SELECT tested.Name, tested.TestedAVG, not_tested.NotTestedAVG FROM
(SELECT Name, AVG(DATEDIFF(day,[Open Date],[Close Date])) as "TestedAVG"
FROM Inventory
WHERE Tested ='Yes' AND [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name) tested
FULL JOIN
(SELECT Name, AVG(DATEDIFF(day,[Open Date],[Close Date])) as "NotTestedAVG"
FROM Inventory
WHERE Tested ='No' AND [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name) not_tested
ON tested.Name = not_tested.Name
Using case
SELECT Name,
AVG(CASE WHEN Tested ='Yes' THEN DATEDIFF(day,[Open Date],[Close Date]) END) as [Tested AVG],
AVG(CASE WHEN Tested ='No' THEN DATEDIFF(day,[Open Date],[Close Date]) END) as [Not Tested AVG]
FROM Inventory
WHERE [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name
Adding as group by
If you don't need to have it as a separate column, the easiest way would be to add a group by the Tested column as well.
SELECT Name, AVG(DATEDIFF(day,[Open Date],[Close Date])) as "AVG"
FROM Inventory
WHERE [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name, Tested
Then you'll get this structure:
Name
Tested
AVG
aTPO
Yes
56
aTPO
No
50
It's hard to say exactly what you want, but maybe you could use a couple of subqueries?
SELECT Name,
AVG(select DATEDIFF(i2.day,i2.[Open Date],i2.[Close Date]) from inventory i2 where i2.name = i.name and i2.Tested = 'Yes') as "Tested",
AVG(select DATEDIFF(i3.day,i3.[Open Date],i3.[Close Date]) from inventory i3 where i3.name = i.name and i3.Tested = 'No') as "Not Tested"
FROM Inventory i
Where [Close Date] IS NOT NULL AND [Open Date] IS NOT NULL
GROUP BY Name
Out of three columns if you trying to get two columns with its values, you have to specify those columns in your code.
Example:
SELECT column1, column2
FROM table_name
But if you want to find all the columns
Example:
SELECT * FROM table_name

In SQL how do I select the latest date that does not have a zero value in another column

I am trying to select the max date in a table that has a Booking Date and a Written Premium value for that date. I want the newest date that has Written Premium (not equal to Zero).
In the above table I want, or expect the 4th Row in my query (7/28/2021, 330000), but I get the first row
(8/20/21, 0)
This is the query I run:
SELECT
MAX(booking_date) AS [Max Booking Date]
FROM
DW.dbo.Table1
GROUP BY
booking_year
HAVING
SUM(written_premium) <> 0
AND booking_year = '2021'
I think this is summing all the written premium, not over the rows so I am just getting the max booking date. Maybe I need a PARTITION BY function or something? I am stuck on this and would appreciate any help on how to best do this.
Thanks,
Brian
I think there are multiple options, but one could be:
SELECT TOP 1 booking_date, written_premium
FROM DW.dbo.Table1
WHERE written_premium <> 0
ORDER BY booking_date DESC
If all you want is the date then there is no need of group by and a HAVING clause.
Set your conditions in the WHERE clause:
SELECT MAX(booking_date) AS [Max Booking Date]
FROM DW.dbo.Table1
WHERE booking_year = '2021' AND written_premium <> 0;
If you want both columns:
SELECT TOP 1 booking_date AS [Max Booking Date], written_premium
FROM DW.dbo.Table1
WHERE booking_year = '2021' AND written_premium <> 0
ORDER BY booking_date DESC;

SQL create column for every week (Loop?)

I need to make a report for weekly changes.
This is the code for todays amount
SELECT
[Entry No_],
[Customer No_],
[Posting Date],
[Description],
[Currency Code],
Trans_type = case when [Deposit]=1 then 'Deposit'
when [Imprest]=1 then 'Imprest'
else 'Other' end,
A.Amount
FROM Table1
LEFT JOIN
(
SELECT Distinct [Cust_ Ledger Entry No_],
SUM ([Amount EUR]) as 'amount'
FROM Table2
group by [Cust_ Ledger Entry No_]
having
SUM ([Amount EUR]) <> '0'
)A
on [Entry No_] = A.[Cust_ Ledger Entry No_]
Where
A.Amount is not NULL
Code to generate data for previous week is here (adding only where clause):
SELECT
[Entry No_],
[Customer No_],
[Posting Date],
[Description],
[Currency Code],
Trans_type = case when [Deposit]=1 then 'Deposit'
when [Imprest]=1 then 'Imprest'
else 'Other' end,
A.Amount
FROM Table1
LEFT JOIN
(
SELECT Distinct [Cust_ Ledger Entry No_],
SUM ([Amount EUR]) as 'amount'
FROM Table2
where [posting Date] < '2020-11-23'
group by [Cust_ Ledger Entry No_]
having
SUM ([Amount EUR]) <> '0'
)A
on [Entry No_] = A.[Cust_ Ledger Entry No_]
Where
A.Amount is not NULL
It would be enough to union both queries and then export to Excel and make pivot, but problem is that I need results of last 50 weeks. Is there any smart way to avoid union 50 tables and run one simple code to generate weekly report?
Thanks
it might be easier with sample, but I don't know how to paste table here..
Maybe it is true, i dont need union here, and group by would be enough, but it stills sounds difficult for me :)
Ok. Lets say table has such headers: Project | Country | date | amount
The code below returns amount for todays date
Select
Project,
SUM(amount)
From Table
Group by Project
I actually need todays date and also the results of previous weeks (What was the result on November 22 (week 47), November 15 (week 46) and so on.. total 50 weeks from todays date).
Code for previous week amount is here:
Select
Project,
SUM(amount)
From Table
Where Date < '2020.11.23'
Group by Project
So my idea was to create create 50 codes and join the results together, but i am sure it is a better way to do this. Besides i dont want to edit this query every week and add a new date for it.
So any ideas, to make my life easier?
if I have understood your requirement correctly, all you need to do is extract the week from the date e.g.
Select
Project,
datepart(week, date),
SUM(amount)
From Table
Where Date < '2020.11.23'
Group by Project, datepart(week, date)

How to return current and previous row in SQL?

How do I return the current row and the previous row in a SQL query that is organized by date on a join? I have to join the "Crew" table with its "Detail" table. When I execute the query using a subselect, I get the same data for each crew. I am not sure how to pass the current crew ID down to the subselect so that only the previous days work for the current crew is returned.
SELECT Spread_Crew.Description
, Sum(Abs(Daily_Progress.Station_Number_
Begin_Daily_Progress.Station_Number_End)) AS [Feet Total]
, Spread_Crew.Hourly_Employee_Count AS [Hourly]
, Spread_Crew.Salary_Employee_Count AS [Salary]
, (Spread_Crew.Hourly_Employee_Count +
Spread_Crew.Salary_Employee_Count)*10 AS [Weekly Hours]
, (Date() - Spread_Crew.Actual_Start_Date) AS [Crew Days to Date]
, Round(([Feet Total]/ [Crew Days to Date]),0) AS [FT/Day]
, (SELECT Sum(Abs(Daily_Progress.Station_Number_Begin
Daily_Progress.Station_Number_End))
FROM Spread_Crew INNER JOIN Daily_Progress ON Spread_Crew.ID =
Daily_Progress.Spread_Crew_Id
WHERE (((Daily_Progress.PROGRESS_DATE)=[Report Date]))
) AS [Previous Footage]
FROM Spread_Crew LEFT JOIN Daily_Progress ON Spread_Crew.ID =
Daily_Progress.Spread_Crew_Id
GROUP BY Spread_Crew.Description
, Spread_Crew.Hourly_Employee_Count
, Spread_Crew.Salary_Employee_Count
, Spread_Crew.Sort_Order
, Spread_Crew.Print_On_Daily_Report
, Spread_Crew.Actual_Start_Date
HAVING (((Spread_Crew.Print_On_Daily_Report)=True))
ORDER BY Spread_Crew.Sort_Order;
Your subquery probably wants to be a correlated subquery:
(SELECT Sum(Abs(dp.Station_Number_Begin - dp.Station_Number_End))
FROM Daily_Progress as dp
WHERE Spread_Crew.ID = dp.Spread_Crew_Id AND
dp.PROGRESS_DATE = [Report Date]
) AS [Previous Footage]
The expression Spread_Crew.ID refers to the column in the outer SELECT.

Scripting the latest month in the data set [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
In the following view,instead of specifying the actual dates in the where condition,I want sql server to recognize June and May as the latest month and the (latest month-1) as the view gets refreshed on a monthly basis and so does latest month and (latest month -1).
PS:- The latest Report month is June in the table
SELECT (A.[First Name])
,A.[Last Name]
,A.[Report Month]
FROM (
(
SELECT DISTINCT [First Name]
,[Last Name]
,[Report Month]
,[Bill To Code]
,[Region]
,[Area]
FROM dbo.Data
WHERE (
[Report Month] BETWEEN '2015-06-01'
AND '2015-06-30'
AND [FTE Status] = 'Inactive'
)
) A INNER JOIN (
SELECT DISTINCT [First Name]
,[Last Name]
,[Report Month]
,[Bill To Code]
,[Region]
,[Area]
FROM dbo.Data
WHERE (
[Report Month] BETWEEN '2015-05-01'
AND '2015-05-31'
AND [FTE Status] = 'Active'
)
) B ON A.[First Name] = B.[First Name]
AND A.[Last Name] = B.[Last Name]
)
Thank you,just learnt how to format better in SO.Thanks to Sean.Learning from my mistakes guys..:)
Hence i should write some function so that sql server reads the start
and end date of the latest month in the data set.
You say you need to read the start and end date, but if what you really need is just to get all the data that is in the latest month in your table, then this will do it:
select *
from dbo.Data
where DATEDIFF(month,[Report Month],(SELECT MAX([Report Month] FROM dbo.Data))=0
and [FTE Status]='Active'
Despite your rather vague question, I think this is what you are looking for.
This will return the first and last day for the max date in YourTable.
;with cte as (
select convert(date,left(convert(varchar,Max(Report_Month),112),6) + '01') startDate,
month(Max(Report_Month)) n
from YourTable
union all
select dateadd(month,n,convert(date,convert(varchar,year(startDate)) + '0101')) startDate,
(n+1) n
from cte
where n < month(startDate)
)
select startdate, dateadd(day,-1,dateadd(month,1,startdate)) enddate
from cte
How about:
SELECT MAX(MONTH(Report_Month))
FROM YourTable
GROUP BY YEAR(Report_Month)
HAVING YEAR(Report_Month) = MAX(YEAR(Report_Month))