How can i get all rows from two tables Postgres - postgresql

I have a problem with JOIN of two tables.
CREATE table appointment(
idappointment serial primary key,
idday int references days(idday),
worktime text
);
create table booking(
idbooking serial,
idappointment int references appointment(idappointment),
date date,
primary key(idappointment)
);
appointment
idappointment
idday
worktime
1
1
07:00-08:00
2
1
08:00-09:00
3
1
09:00-10:00
4
2
09:00-10:00
booking
idbooking
idappointment
date
1
1
2021-08-22
1
2
2021-08-2
And I want :
idbooking
idappointment
date
idbooking
idappointment
date
1
1
07:00-08:00
null
null
null
2
1
08:00-09:00
null
null
null
3
1
09:00-10:00
null
null
null
4
2
09:00-10:00
null
null
null
null
null
null
1
1
2021-08-22
null
null
null
1
2
2021-08-2
1
1
07:00-08:00
1
1
2021-08-22
2
1
08:00-09:00
1
2
2021-08-2
How can I get it ?

Related

Postgresql unique index: only one date for one foreign key

I have a table "foo":
ID PRODUCT_ID END_DATE
------------------------------
1 1 NULL
2 1 2022-02-02
3 1 2022-01-06 - This date could not be exists
4 2 NULL
5 2 2022-01-23
6 3 NULL
7 3 NULL
How can i make unique index for one product whith the same id only one date can exist?
Create a conditional unique index:
CREATE UNIQUE INDEX u_productid_end_date_not_null
ON foo(product_Id)
WHERE end_date IS NOT NULL; -- this one will do the trick

Flattening Nested CSV in Hierarchal order using Scala Spark

I am trying to flatten a nested csv in hierarchal order where 1 is the root node that can be repeatable . Rest of the nodes are children to its corresponding immediate parent and each node is having unique number(Id)
Example two 2s are siblings and 3 is the child of immediate last 2. Similarly node 3(1465) has child 4 (id:2345) and another 3 (0987) has child 4(3450)
label
desc
id
1
jhfdjhfd
1234
2
hdjhfdf
3456
2
mnvmcvn
8765
3
nvbvhv
1456
4
bvnvnv
2345
3
yrtuy
0987
4
uoio
3450
The output should be in following format
label
desc
id
L0
L1
L2
L3
L4
1
jhfdjhfd
1234
null
null
null
null
null
2
hdjhfdf
3456
1234
null
null
null
null
2
mnvmcvn
8765
1234
null
null
null
null
3
nvbvhv
1456
1234
8765
null
null
null
4
bvnvnv
2345
1234
8765
1456
null
null
3
yrtuy
0987
1234
8765
null
null
null
4
uoio
3450
1234
8765
0987
null
null

Map the column value against same sequences in PostgreSQL

I want to write a query as per below input and output
Input :-
Num Sr_no Exp_no
NULL 1 1
NULL 2 1
ABC_1 3 1
NULL 4 1
NULL 1 2
NULL 2 2
ABC_2 3 2
NULL 4 4
Expected Output:-
Num Sr_no Exp_no
ABC_1 1 1
ABC_1 2 1
ABC_1 3 1
ABC_1 4 1
ABC_2 1 2
ABC_2 2 2
ABC_2 3 2
ABC_2 4 4
As there is no details in question, this answer is on below assumptions
you want to fill num field based on exp_no grouping.
Assuming there is only one value in a exp_no group.
Try this:
with cte as
(
select distinct on (num,exp_no) num, exp_no
from test
where num is not null
order by 1)
select
coalesce(t1.num, cte.num),
t1.sr_no,
t1.exp_no
from test t1 left join cte on t1.exp_no=cte.exp_no
DEMO

PIVOT not producing data on a single row

I am trying to write PIVOT to generate a row of data that originally sits as multiple rows in the DB. The DB data looks like this (appended)
txtSchoolID txtSubjectArchivedName intSubjectID intGradeID intGradeTransposeValue
95406288448 History 7 634 2
95406288448 History 7 635 2
95406288448 History 7 636 2
95406288448 History 7 637 2
95406288448 History 7 638 2
95406288448 History 7 639 2
95406288448 History 7 640 2
95406288448 History 7 641 2
95406288448 History 7 642 2
95406288448 History 7 643 2
What I want to get to is 1 row for each subject and SchoolID with the grades listed as columns.
I have written the following pivot:
SELECT intSubjectID, txtSchoolID, [636] AS Effort, [637] AS Focus, [638] AS Participation, [639] AS Groupwork, [640] AS Rigour, [641] AS Curiosity, [642] AS Initiative,
[643] AS SelfOrganisation, [644] as Perserverance
FROM (SELECT txtSchoolID, intReportTypeID, txtSubjectArchivedName, intSubjectID, intReportProgress, txtTitle, txtForename, txtPreName, txtMiddleNames,
txtSurname, txtGender, txtForm, intNCYear, txtSubmitByTitle, txtSubmitByPreName, txtSubmitByFirstname, txtSubmitByMiddleNames,
txtSubmitBySurname, txtCurrentSubjectName, txtCurrentSubjectReportName, intReportCycleID, txtReportCycleName, intReportCycleType,
intPreviousReportCycle, txtReportCycleShortName, intReportCycleTerm, intReportCycleAcademicYear, dtReportCycleStartDate,
dtReportCycleFinishDate, dtReportCyclePrintDate, txtReportTermName, dtReportTermStartDate, dtReportTermFinishDate,
intGradeID, txtGradingName, txtGradingOptions, txtShortGradingName, txtGrade, intGradeTransposeValue FROM VwReportsManagementAcademicReports) p
PIVOT
(MAX (intGradeTransposeValue)
FOR intGradeID IN ([636], [637], [638], [639], [640], [641], [642], [643], [644] )
) AS pvt
WHERE (intReportCycleID = 142) AND (intReportProgress = 1)
However, this is producing this
intSubjectID txtSchoolID Effort Focus Participation Groupwork Rigour Curiosity Initiative SelfOrganisation Perserverance
8 74001484142 NULL NULL NULL NULL NULL NULL NULL NULL NULL
8 74001484142 NULL NULL NULL NULL NULL 2 NULL NULL NULL
8 74001484142 3 NULL NULL NULL NULL NULL NULL NULL NULL
8 74001484142 NULL 2 NULL NULL NULL NULL NULL NULL NULL
8 74001484142 NULL NULL NULL 2 NULL NULL NULL NULL NULL
8 74001484142 NULL NULL NULL NULL NULL NULL 2 NULL NULL
8 74001484142 NULL NULL 2 NULL NULL NULL NULL NULL NULL
8 74001484142 NULL NULL NULL NULL NULL NULL NULL NULL 2
8 74001484142 NULL NULL NULL NULL 2 NULL NULL NULL NULL
8 74001484142 NULL NULL NULL NULL NULL NULL NULL 2 NULL
What I want is
intSubjectID txtSchoolID Effort Focus Participation Groupwork Rigour Curiosity Initiative SelfOrganisation Perserverance
8 74001484142 3 2 2 2 2 2 2 2 2
Is there a way to get it like this.
I have never tried a PIVOT before, this is my first time, so all help welcome.
I think the reason you got the unexpected result is you have so many unwanted columns in the Select in the sub-query and the pivot will group them, too.
Your query might be very close to your ideal result: try:
SELECT intSubjectID, txtSchoolID, [636] AS Effort, [637] AS Focus, [638] AS Participation, [639] AS Groupwork, [640] AS Rigour, [641] AS Curiosity, [642] AS Initiative,
[643] AS SelfOrganisation, [644] as Perserverance
FROM (SELECT txtSchoolID, intReportTypeID FROM VwReportsManagementAcademicReports) p --just these two
PIVOT
(MAX (intGradeTransposeValue)
FOR intGradeID IN ([636], [637], [638], [639], [640], [641], [642], [643], [644] )
) AS pvt
WHERE (intReportCycleID = 142) AND (intReportProgress = 1)
As per the comment above - the solution was:
try stripping the inner select down to only the columns that will be used in the pivot and are expected in the output. intSubjectID, txtSchoolID, intGradeTransposeValue, and intGradeID. all other columns will act as a grouping column in the output and can cause this type of non grouped output.
pivot can't return such what you asking for, but you can use another approach:
--test dataset
declare #test as table
( txtSchoolID bigint,
txtSubjectArchivedName varchar(10),
intSubjectID int,
intGradeID int,
intGradeTransposeValue int)
insert into #test
Values
(95406288448,'History',7,634,2),
(95406288448,'History',7,635,2),
(95406288448,'History',7,636,2),
(95406288448,'History',7,637,2),
(95406288448,'History',7,638,2),
(95406288448,'History',7,639,2),
(95406288448,'History',7,640,2),
(95406288448,'History',7,641,2),
(95406288448,'History',7,642,2),
(95406288448,'History',7,643,2)
--conditional aggregation
select intSubjectID,
txtSchoolID,
count(case when intGradeID = 636 then 1 end) AS Effort,
count(case when intGradeID = 637 then 1 end) AS Focus,
count(case when intGradeID = 638 then 1 end) AS Participation,
count(case when intGradeID = 639 then 1 end) AS Groupwork,
count(case when intGradeID = 640 then 1 end) AS Rigour,
count(case when intGradeID = 641 then 1 end) AS Curiosity,
count(case when intGradeID = 642 then 1 end) AS Initiative,
count(case when intGradeID = 643 then 1 end) AS SelfOrganisation,
count(case when intGradeID = 644 then 1 end) as Perserverance
from #test
group by intSubjectID, txtSchoolID
test is here

Get email frequency using grouping sets

I have a table with emails logs and need to check the email frequency. using grouping sets retrieve email count hourly, daily, weekly, monthly and yearly.
Can anyone send me an example.
Thank you !
SELECT DATEPART(yyyy,create_time) [year]
, DATEPART(mm,create_time) [month]
, DATEPART(WEEK,create_time) [week]
, DATEPART(dd,create_time) [day]
, DATEPART(hour,create_time) [hour]
, COUNT(*) AS c
FROM your_table
GROUP BY GROUPING SETS (DATEPART(yyyy,create_time)
,DATEPART(mm,create_time)
,DATEPART(WEEK,create_time)
,DATEPART(dd,create_time)
,DATEPART(hour,create_time))
ORDER BY [year], [month], [week], [day], [hour]
To group by multiple fields, just group columns in parentheses:
,(DATEPART(yyyy,create_time), DATEPART(mm,create_time))
Here's sample output, including the year/month grouping:
year month week day hour c
NULL NULL NULL NULL 0 12
NULL NULL NULL NULL 1 1
NULL NULL NULL 1 NULL 219
NULL NULL NULL 2 NULL 467
NULL NULL 1 NULL NULL 124
NULL NULL 2 NULL NULL 216
NULL 1 NULL NULL NULL 1899
NULL 2 NULL NULL NULL 1419
2015 NULL NULL NULL NULL 3750
2016 NULL NULL NULL NULL 7446
2015 8 NULL NULL NULL 391
2015 9 NULL NULL NULL 891
Thank you for the reply !
I have added ID column to the grouping sets,not getting if it is Hourly/weekly/daily/monthly generated.
SELECT ID, DATEPART(yyyy,create_time) [year]
, DATEPART(mm,create_time) [month]
, DATEPART(WEEK,create_time) [week]
, DATEPART(dd,create_time) [day]
, DATEPART(hour,create_time) [hour]
, COUNT(*) AS c
FROM your_table
GROUP BY GROUPING SETS(
(DATEPART(yyyy,create_time),ID)
,(DATEPART(mm,create_time),ID)
,(DATEPART(WEEK,create_time),ID)
,(DATEPART(dd,create_time),ID)
,(DATEPART(hour,create_time) ,ID))
ORDER BY [year], [month], [week], [day], [hour],ID
Result
Month Week Daily Hour C
NULL NULL NULL 0 12
NULL NULL NULL 0 471
NULL NULL NULL 0 176
NULL NULL NULL 0 145
NULL NULL NULL 0 633
NULL NULL NULL 0 13
NULL NULL NULL 0 24
NULL NULL NULL 0 2
NULL NULL NULL 0 324
NULL NULL NULL 0 555