I have a table of clients and a table for events. The client is a FK in the events table. A user would select which client they are at on a particular day. I want my events table to have the fields Sunday, Monday, ....., Saturday so the user just has to select a client from a drop down list.
I've tried setting up my models like this but it didn't work when trying to migrate:
class Client(models.Model):
name = models.CharField(max_length=50)
class Event(models.Model):
week = models.DateField(blank=False)
sunday = models.ForeignKey(Client, on_delete=models.CASCADE)
monday = models.ForeignKey(Client, on_delete=models.CASCADE)
tuesday = models.ForeignKey(Client, on_delete=models.CASCADE)
wednesday = models.ForeignKey(Client, on_delete=models.CASCADE)
thursday = models.ForeignKey(Client, on_delete=models.CASCADE)
friday= models.ForeignKey(Client, on_delete=models.CASCADE)
saturday = models.ForeignKey(Client, on_delete=models.CASCADE)
I know of this way to allow choices as an example:
position = models.CharField(max_length=20, choices=POS_CHOICES)
But i want to use choices from my table "client" instead of hardcoding the choices.
Have to just use "related_name":
class Event(models.Model):
week = models.DateField(blank=False)
sunday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='sunday', null=True)
monday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='monday', default=0)
tuesday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='tuesday', default=0)
wednesday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='wednesday', default=0)
thursday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='thursday', default=0)
friday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='friday', default=0)
saturday = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='saturday', null=True)
Related
I have two tables. One with dates and the other with gift dates and gift types. The third table displays the results that I am looking to achieve.
I want to display a column on the table with the product dates called 'Results'. The results should return:
'Not a Donor' if there is no gift date before the product date.
'Products Donor' if there is only one gift type Product before the Date.
'Multiple Products Donor' if there are multiple Product gift types before the Date (but there cant be an 'Other' Gift Type).
'Other Donor' if there is an 'Other' Gift type, regardless of how many products came before.
Table 1
Donor Date
Steve 2/1/2020
Steve 3/1/2020
Steve 4/1/2020
Steve 5/1/2020
Steve 6/1/2020
Steve 7/1/2020
Steve 9/1/2020
Steve 10/1/2020
Bill 2/1/2020
Bill 3/1/2020
Bill 4/1/2020
Bill 5/1/2020
Bill 6/1/2020
Bill 7/1/2020
Bill 8/1/2020
Table 2
Donor Gift Date Gift Type
Steve 8/15/2020 Product
Steve 9/15/2020 Product
Bill 5/15/2020 Product
Bill 6/15/2020 Other
Bill 7/15/2020 Product
Expected Result
Donor Date Results
Steve 2/1/2020 Not A Donor
Steve 3/1/2020 Not A Donor
Steve 4/1/2020 Not A Donor
Steve 5/1/2020 Not A Donor
Steve 6/1/2020 Not A Donor
Steve 7/1/2020 Not A Donor
Steve 9/1/2020 Products Donor
Steve 10/1/2020 Multiple Products Donor
Bill 2/1/2020 Not A Donor
Bill 3/1/2020 Not A Donor
Bill 4/1/2020 Not A Donor
Bill 5/1/2020 Not A Donor
Bill 6/1/2020 Products Donor
Bill 7/1/2020 Other Donor
Bill 8/1/2020 Other Donor
You can use a Case statement to consider each possible output:
select T.Donor,
T.Date,
Results = Case when not exists (Select top 1 1 From table2 where Donor = T.Donor and [Gift Date] < T.[Date]) then 'Not A Donor'
when exists (Select top 1 1 From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Other') then 'Other Donor'
when (Select count(1) From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Product') = 1 then 'Products Donor'
when (Select count(1) From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Product') > 1 then 'Multiple Products Donor'
end
from table1 T
I don't know the name of your tables so you'll have to replace them.
I have the following table:
Person
userID
Name
date_created
date_left
My rows:
-- Datetime format MM-DD-YYYY
userID Name date_created date_left
1 aa 01-01-2018 NULL
2 bb 01-01-2018 11-15-2018
3 cc 06-20-2018 NULL
4 dd 03-03-2018 11-13-2018
5 ee 11-08-2018 11-30-2018
6 ff 12-01-2018 NULL
I also have a invoice period date (month and year).
What I'm trying to do is to get a list of active users based on the invoice period!.
MY IDEAL RESULT:
If invoice month = 11 and year = 2018:
users 1,3,5 should be shown
Reason user 5 is selected:
If a user join and leaves in the same month, he is seen as active but if a user leaves on the month and has a join date smaller than the invoice month, it's not active (since it left on the month of invoicing but joined earlier)
if invoice month = 12 and year = 2018:
users 1,3,6 should be shown
Therefor:
I also want to retrieve the results for the users that are already left (and check if they were active based on the passed month and year). This means that I also want to be able to dynamically check the users that were active
This is my query:
GO
DECLARE #month int, #year int;
SET #month = 12;
SET #year = 2018;
SELECT * FROM PERSON
WHERE (month(date_created) = #month -1 ) OR (MONTH(date_created) < #month AND YEAR(date_created) = #year AND date_left = null)
but this still returns everyone.
What am I doing wrong?
Something like this should work:
DECLARE #month int, #year int, #dateToCheck datetime;
SET #month = 12;
SET #year = 2018;
SET #dateToCheck = dateadd(month, 1, datefromparts(#year, #month, 1))
SELECT *
FROM PERSON
WHERE date_created < #dateToCheck
AND (date_left is null or date_left >= #dateToCheck)
So if your month is 11 and year 2018 #datetocheck will be 2018-12-01 and you will get anyone created on or before 2018-11-30 and have a null date_left or a date left on or after 2018-12-01.
If your month is 12 and year 2018, #datetocheck will be 2018-12-31 and you will get anyone created on or before 2018-12-31 and that have a date_left = null or a date left on or after 2019-01-01
Assuming that you want to compare with the current date. Then try like this
SELECT * FROM Person
WHERE DATEDIFF(m,date_created,GETDATE())=1 AND date_left IS NULL
The active users are considered as the one who is date_created is a month before
We are trying to do an analysis of how many staff are there in each department in every hour for trending and forecasting purposes.
The image below is the outcome I would like to get
http://i.stack.imgur.com/iMtaP.png
2am means the number of employees clocked in from 2:00am to 2:59am
We would be putting the query into tableau software for analyzing. Btw I am using mssql 2014.
We have the following columns to do the query
SHIFTA_Start = Clock in Time (VARCHAR)
SHIFTA_End = Clock out Time (VARCHAR)
EMPLOYEENAME = Name of the Employee
DEPARTMENT = Department of the Employee
ATTENDANCEDATE = Date the employee come for work (VARCHAR)
WEEKDAYSTR = Mon, Tues, Wednesday, Thursday, Friday
I hope this helps, modify based on your requirement.
SELECT DEPARTMENT,
(SELECT COUNT(EMPLOYEENAME) FROM TABLE WHERE DATEPART(HH,SHIFTA_START) <= 1 AND DATEPART(HH,SHIFTA_END) >= 2 AND DEPARTMENT = T.DEPARTMENT) AS '2AM',
(SELECT COUNT(EMPLOYEENAME) FROM TABLE WHERE DATEPART(HH,SHIFTA_START) <= 2 AND DATEPART(HH,SHIFTA_END) >= 3 AND DEPARTMENT = T.DEPARTMENT) AS '3AM',
.
.
.
.
FROM TABLE T
WHERE ATTENDANCEDATE = GETDATE()
GROUP BY DEPARTMENT
ORDER BY DEPARTMENT
can you please assist
I have a query that shows number of teachers, the site the visited and when date they visited. This query looks at all teachers visits for the past week.
I want to split the dateattended field into columns to show daily visit for the past week. Below is how it looks.
EmployeeNumber Name HomeSite Site Attended Day Attended
TP-000322789 Samuel Mohlamnyane Teacher Port Elizabeth 2014-10-18 07:23
TP-000148774 Jean Smoothie Teacher Hennopsview 2014-10-13 08:55
TP-000148774 Jean Smoothie Teacher Hennopsview 2014-10-16 08:43
TP-000148122 Anthony Mike Teacher Tzaneen 2014-10-19 09:19
TP-000148122 Anthony Mike Teacher Tzaneen 2014-10-15 08:26
TP-000328452 Geneve Gorridon Teacher Tzaneen 2014-10-14 07:44
TP-000346529 Edmos Dube Teacher Melrose 2014-10-18 07:47
TP-000321374 Anita Rene Classen Teacher Johannesburg 2014-10-17 07:57
TP-000324511 Anthonysia White Teacher Durbanville 2014-10-15 07:53
TP-000324511 Anthonysia White Teacher Durbanville 2014-10-18 12:26
TP-000327471 Moses Mathebula Teacher Polokwane 2014-10-13 05:50
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging 2014-10-15 07:06
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-13 07:26
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-16 06:51
TP-000323384 Lerato Manyanka Teacher Bedfordview 2014-10-17 08:57
Now I want to split Day attended to show date in different columns from yesterday going down to the last seven days.
Below is the code I used to get the above result set. And how the result should look like.
EmployeeNumber Name HomeSite Site Attended Day 1 Day2 Day 3 Day 4 Day 5 Day 6 Day 7
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging 2014-10-15 07:06
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-17 08:57 2014-10-16 06:51 2014-10-13 07:26
SELECT mdet.MemRefNo AS 'EmployeeNumber'
, cont.FirstName + ' ' + cont.LastName AS Name
, s.Name AS 'HomeSite'
, Attend.VisitedSite AS 'Site Attended'
, Attend.Weekdays AS 'Day Attended'
FROM MemberDetail mdet
INNER JOIN MembershipHistory mhis ON mdet.CurrentMembershipID = mhis.ID32
INNER JOIN contacts cont ON cont.GUID = mdet.ContactGUID
INNER JOIN Sites s ON s.id = cont.HomeSiteID
INNER JOIN Packages pg ON pg.ID = mhis.PackageID
CROSS APPLY
(
SELECT min(a1.attenddate) AS Weekdays , a1.contactguid, a1.SiteID , s.Name as VisitedSite FROM dbo.attendance a1
INNER JOIN Sites s ON s.id = a1.Siteid
WHERE DATEDIFF(DAY,a1.attenddate,GETDATE()) <= 7
and ContactGuid = mdet.ContactGuid
AND a1.isswipesuccessful = 1
GROUP BY a1.ContactGuid, DATEPART(DW, a1.attenddate),a1.SiteID , s.Name
) Attend
WHERE pg.Description LIKE '%Teacher%'
I think this is the query you want, it uses a pivot with the results from your existing query as source through a common table expression. Ideally the code could be merged into one query, but as you didn't provide any test data from the source tables, but only the output I didn't try to rewrite it. Note that if a person visited the same site more than one time in a single day, only the latest time will be shown.
-- using original query as source
;WITH visits AS (
SELECT mdet.MemRefNo AS 'EmployeeNumber'
, cont.FirstName + ' ' + cont.LastName AS Name
, s.Name AS 'HomeSite'
, Attend.VisitedSite AS 'Site Attended'
, Attend.Weekdays AS 'Day Attended'
FROM MemberDetail mdet
INNER JOIN MembershipHistory mhis ON mdet.CurrentMembershipID = mhis.ID32
INNER JOIN contacts cont ON cont.GUID = mdet.ContactGUID
INNER JOIN Sites s ON s.id = cont.HomeSiteID
INNER JOIN Packages pg ON pg.ID = mhis.PackageID
CROSS APPLY
(
SELECT min(a1.attenddate) AS Weekdays , a1.contactguid, a1.SiteID , s.Name as VisitedSite FROM dbo.attendance a1
INNER JOIN Sites s ON s.id = a1.Siteid
WHERE DATEDIFF(DAY,a1.attenddate,GETDATE()) <= 7
and ContactGuid = mdet.ContactGuid
AND a1.isswipesuccessful = 1
GROUP BY a1.ContactGuid, DATEPART(DW, a1.attenddate),a1.SiteID , s.Name
) Attend
WHERE pg.Description LIKE '%Teacher%'
)
-- query to produce results
SELECT
EmployeeNumber,
Name,
HomeSite,
[Site Attended],
[1] AS 'Day 1',
[2] AS 'Day 2',
[3] AS 'Day 3',
[4] AS 'Day 4',
[5] AS 'Day 5',
[6] AS 'Day 6',
[7] AS 'Day 7'
FROM (
SELECT *, DATEDIFF(day, [Day Attended], GETDATE()) diff
FROM visits
WHERE [Day Attended] > (GETDATE()-7) -- adjust this to limit date range
) a
PIVOT (
MAX([Day Attended]) FOR [diff] in ([1],[2],[3],[4],[5],[6],[7])
) AS Pivoted;
It would probably be trivial to modify the existing query to get the desired results.
Sample SQL Fiddle (using the sample output data as source).
Sample results:
EmployeeNumber Name HomeSite Site Attended Day 1 Day 2 Day 3 Day 4 Day 5 Day 6 Day 7
-------------------- ---------------------------------------- -------------------- -------------------- ----------------------- ----------------------- ----------------------- ----------------------- ----------------------- ----------------------- -----------------------
TP-000148122 Anthony Mike Teacher Tzaneen NULL 2014-10-19 09:19:00.000 NULL NULL NULL 2014-10-15 08:26:00.000 NULL
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging NULL NULL NULL NULL NULL 2014-10-15 07:06:00.000 NULL
TP-000148774 Jean Smoothie Teacher Hennopsview NULL NULL NULL NULL 2014-10-16 08:43:00.000 NULL NULL
TP-000321374 Anita Rene Classen Teacher Johannesburg NULL NULL NULL 2014-10-17 07:57:00.000 NULL NULL NULL
TP-000322789 Samuel Mohlamnyane Teacher Port Elizabeth NULL NULL 2014-10-18 07:23:00.000 NULL NULL NULL NULL
TP-000323383 Lerato Manyanka Teacher Bedfordview NULL NULL NULL 2014-10-17 08:57:00.000 2014-10-16 06:51:00.000 NULL NULL
TP-000324511 Anthonysia White Teacher Durbanville NULL NULL 2014-10-18 12:26:00.000 NULL NULL 2014-10-15 07:53:00.000 NULL
TP-000346529 Edmos Dube Teacher Melrose NULL NULL 2014-10-18 07:47:00.000 NULL NULL NULL NULL
I have a problem on my hand. I am working on an application where user wants to send the wish cards to his clients whose birthday is within user provided FROM and TO date , irrespective of the year. I.e. the search results should be on the basis of the Month and date only. e.g my input parameteres are from date: "12/05" (December 05)and To Date: "01/04" (January 04). Please help. Thanks in advance
You can use extract function of PLSQL:
extract(MONTH FROM DATE '2003-08-22') would return 8
extract(DAY FROM DATE '2003-08-22') would return 22
http://www.techonthenet.com/oracle/functions/extract.php
You should use this query condition. It selects birthdate if it is in one month interval from now. Birthdate can be from any year:
where
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE(TO_CHAR(sysdate,'dd.mm')||'.1900','DD.MM.YYYY')
and ADD_MONTHS(TO_DATE(TO_CHAR(sysdate,'dd.mm')||'.1900','DD.MM.YYYY'),1)
If user inputs date range as for example '02/03' and '23/06' ('P1' and 'P2' in this query) then use following condition.
where
(
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE('P1'||'.1900','DD.MM.YYYY')
and
TO_DATE('P2'||'.1900','DD.MM.YYYY')
)
OR
(
(TO_DATE('P1'||'.1900','DD.MM.YYYY')
> TO_DATE('P2'||'.1900','DD.MM.YYYY') )
and
(
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE('P1'||'.1900','DD.MM.YYYY')
and
TO_DATE('31.12.1900','DD.MM.YYYY')
OR
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1901','DD.MM.YYYY') ,
between
TO_DATE('01.01.1901','DD.MM.YYYY')
and
TO_DATE('P2'||'.1901','DD.MM.YYYY')
)
)
assuming you've stored DOB as a DATE lets say column = "DOB" in table PPL.
ie for the raw set:
FIRSTNAME LASTNAME DOB
-------------------------------- -------------------------------- ---------
Joe Bloggs 03-JAN-90
Jane Doe 05-JAN-40
Adam West 05-DEC-76
we get
SQL> select firstname, lastname, dob, next_bday
2 from (select firstname, lastname, dob,
3 case when to_date(to_char(dob, 'mmdd'), 'mmdd') < trunc(sysdate)
4 then add_months(to_date(to_char(dob, 'mmdd'), 'mmdd'), 12)
5 else to_date(to_char(dob, 'mmdd'), 'mmdd')
6 end next_bday
7 from ppl)
8 where next_bday < add_months(trunc(sysdate), 1);
FIRS LASTNA DOB NEXT_BDAY
---- ------ --------- ---------
Joe Bloggs 03-JAN-90 03-JAN-13
Adam West 05-DEC-76 05-DEC-12