Postgres - Query that Join two tables - sql

I have two table that need to join them in one table.
1: First Query
SELECT cu.user_name,
li.successdate
FROM logininfo li
JOIN user_mapping um ON um.user_key = li.username
JOIN cwd_user cu ON um.username = cu.user_name
ORDER BY successdate;
Result:
user_name | successdate
---------------------+-------------------------
K_Daniel | 2018-09-02 13:38:22.331
2: Second Query
WITH last_login_date AS
(SELECT user_id
, to_timestamp(CAST(cua.attribute_value AS double precision)/1000) AS last_login
FROM cwd_user_attribute cua
WHERE cua.attribute_name = 'lastAuthenticated'
AND to_timestamp(CAST(cua.attribute_value AS double precision)/1000) < (CURRENT_DATE))
SELECT c.user_name
, g.group_name
FROM cwd_user c
INNER JOIN last_login_date l ON (c.id = l.user_id)
INNER JOIN cwd_membership m ON (c.id = m.child_user_id)
INNER JOIN cwd_group g ON (m.parent_id = g.id)
WHERE g.group_name LIKE '%CEO-%' ;
Result:
user_name | group_name
------------------+----------------------------------------------------
K_Daniel | CEO-Building1
3-Here is the expected result:
user_name | successdate | group_name
---------------------+-------------------------+-----------------------
K_Daniel | 2018-09-02 13:38:22.331 | CEO-Building1
what is the appropriate query to join these table?
Any idea
Thanks,

after serval workaround I found solution.
WITH last_login_date AS
(SELECT user_id
, to_timestamp(CAST(cua.attribute_value AS double precision)/1000) AS last_login
FROM cwd_user_attribute cua
WHERE cua.attribute_name = 'lastAuthenticated'
AND to_timestamp(CAST(cua.attribute_value AS double precision)/1000) < (CURRENT_DATE))
SELECT c.user_name
, li.successdate
, g.group_name
FROM cwd_user c
INNER JOIN last_login_date l ON (c.id = l.user_id)
INNER JOIN cwd_membership m ON (c.id = m.child_user_id)
INNER JOIN cwd_group g ON (m.parent_id = g.id)
INNER JOIN user_mapping um ON (c.user_name = um.username)
INNER JOIN logininfo li ON (um.user_key = li.username)
WHERE g.group_name LIKE 'CEO-%' ;

Related

Finding the count

I have the following SQL query and need to know the count of companyid as I can see repeating data. How do I find the count of it. Following is the query
SELECT a.companyId 'companyId'
, i.orgDebtType 'orgDebtType'
, d.ratingTypeName 'ratingTypeName'
, c.currentRatingSymbol 'currentRatingSymbol'
, c.ratingStatusIndicator 'ratingStatusIndicator'
, g.qualifierValue 'qualifierValue'
, c.ratingdate 'ratingDate'
, h.value 'outlook'
FROM ciqRatingEntity a
JOIN ciqcompany com
on com.companyId = a.companyId
JOIN ciqratingobjectdetail b ON a.entitySymbolValue = b.objectSymbolValue
JOIN ciqRatingData c ON b.ratingObjectKey = c.ratingObjectKey
JOIN ciqRatingType d ON b.ratingTypeId = d.ratingTypeId
JOIN ciqRatingOrgDebtType i ON i.orgDebtTypeId=b.orgDebtTypeId
JOIN ciqRatingEntityData red ON red.entitySymbolValue=a.entitySymbolValue
AND red.ratingDataItemId='1' ---CoName
LEFT JOIN ciqRatingDataToQualifier f ON f.ratingDataId = c.ratingDataId
LEFT JOIN ciqRatingQualifiervalueType g ON g.qualifiervalueid = f.qualifierValueId
LEFT JOIN ciqRatingValueType h ON h.ratingValueId = c.outlookValueId
WHERE 1=1
AND b.ratingTypeId IN ( '130', '131', '126', '254' )
-- and a.companyId = #companyId
AND a.companyId IN
(SELECT distinct TOP 2000000
c.companyId
FROM ciqCompany c
inner join ciqCompanyStatusType cst on cst.companystatustypeid = c.companystatustypeid
inner join ciqCompanyType ct on ct.companyTypeId = c.companyTypeId
inner join refReportingTemplateType rep on rep.templateTypeId = c.reportingtemplateTypeId
inner join refCountryGeo rcg on c.countryId = rcg.countryId
inner join refState rs on rs.stateId = c.stateId
inner join ciqSimpleIndustry sc on sc.simpleIndustryId = c.simpleIndustryId
ORDER BY companyid desc)
ORDER BY companyId DESC, c.ratingdate, b.ratingTypeId, c.ratingStatusIndicator
This will list where there are duplicate companyID's
SELECT companyId, count(*) as Recs
FROM ciqCompany
GROUP BY ciqCompany
HAVING count(*) > 1
I understand that you wish to add a column to the query with the count of each companyId, you can use COUNT() OVER():
select count(a.companyId) over (partition by a.companyId) as companyCount,
<rest of the columns>
from ciqRatingEntity a
join <rest of the query>
This would return in each row the count of the companyId of that row without grouping the results.

CTE Missing Records

The first query listed below returns some logistical data associated with hires that have been made within a particular period of time. The query returns 478 records.
SELECT c.candidate_id AS candidate_id
,o.name
,j.name AS job_title
,c.applied_from
,job_id AS job_id
,cjs.score AS smart_rank_score
,cjs.is_completed AS smartrank_completion_status
,c.hired_at
FROM candidate_jobs c
LEFT JOIN organizations o ON o.id = c.organization_id
LEFT JOIN candidate_job_surveys cjs ON cjs.candidate_job_id = c.id
LEFT JOIN jobs j ON j.id = c.job_id
WHERE o.name LIKE ANY ('{"%Tutor Doctor%"}')
AND c.hired_at :: date BETWEEN '2015-01-01' AND '2016-02-22'
ORDER BY 8 DESC
However, when I attempted to add a CTE (see below) that displays each hire's final "post hire check in score", the query only returns 236 records. Ideally, I'd like the query to either return a score or null value for each of the initial 478 hire records.
WITH final_post_hire_score (candidate_id, final_score) AS
(SELECT c.candidate_id
,p.score
FROM post_hire_followup_reviews p
LEFT JOIN candidate_jobs c ON c.id = p.candidate_job_id
WHERE p.check_in_number = 3)
SELECT c.candidate_id AS candidate_id
,o.name
,j.name AS job_title
,c.applied_from
,job_id AS job_id
,cjs.score AS smart_rank_score
,cjs.is_completed AS smartrank_completion_status
,c.hired_at
,final_score
FROM final_post_hire_score f
LEFT JOIN candidate_jobs c ON c.candidate_id = f.candidate_id
LEFT JOIN organizations o ON o.id = c.organization_id
LEFT JOIN candidate_job_surveys cjs ON cjs.candidate_job_id = c.id
LEFT JOIN jobs j ON j.id = c.job_id
WHERE o.name LIKE ANY ('{"%Tutor Doctor%"}')
AND c.hired_at :: date BETWEEN '2015-01-01' AND '2016-02-22'
ORDER BY 8 DESC
Missing records are due to the filter's, Move the filter's to ON condition else your LEFT OUTER JOIN will be implicitly converted to INNER JOIN
When you are using LEFT OUTER JOIN right table filter's should be present in ON condition else the NULL values for non matching records will get filtered
WITH final_post_hire_score (candidate_id, final_score)
AS (SELECT c.candidate_id,
p.score
FROM post_hire_followup_reviews p
LEFT JOIN candidate_jobs c
ON c.id = p.candidate_job_id
WHERE p.check_in_number = 3)
SELECT c.candidate_id AS candidate_id,
o.NAME,
j.NAME AS job_title,
c.applied_from,
job_id AS job_id,
cjs.score AS smart_rank_score,
cjs.is_completed AS smartrank_completion_status,
c.hired_at,
final_score
FROM final_post_hire_score f
LEFT JOIN candidate_jobs c
ON c.candidate_id = f.candidate_id
AND c.hired_at :: date BETWEEN '2015-01-01' AND '2016-02-22'
LEFT JOIN organizations o
ON o.id = c.organization_id
AND o.NAME LIKE ANY ( '{"%Tutor Doctor%"}' )
LEFT JOIN candidate_job_surveys cjs
ON cjs.candidate_job_id = c.id
LEFT JOIN jobs j
ON j.id = c.job_id
ORDER BY 8 DESC
I think there's an extra
WHERE p.check_in_number = 3
that isn't anywhere else.

Joining two SQL statements in postgres

How would I join both of these statements together so it comes up as one? The two counts are being done separately as it is coming from two different tables.
SELECT ril.invoice_label_id, ril.invoice_label, ril.invoice_label_code,
fp.price as fee, count(*) as ct, l.link_id
FROM consultation_chl c
INNER JOIN link_service_pct_location l on l.link_id=c.link_id
INNER JOIN medication m ON c.consult_id=m.consult_id
INNER JOIN ref_invoice_label ril ON m.formulary_id = ril.formulary_id
INNER JOIN pharmacy ph ON ph.pharmacy_id = l.id AND l.location_type_id = 3
INNER JOIN formulary f ON f.formulary_id=m.formulary_id
INNER JOIN formulary_price fp ON fp.formulary_id=f.formulary_id
WHERE l.pct_id = 1425
AND l.service_id = 4
AND c.invoice_period = '2015-04-30'
AND ril.section_id=2
AND ril.invoice_label_code in ('MEDTABS','MEDCAPS','DOXYCAPS','DOXYTABS')
AND fp.valid_from <= c.consult_date
AND (fp.valid_to >= c.consult_date OR fp.valid_to IS NULL) GROUP BY ril.invoice_label_id, ril.invoice_label, ril.invoice_label_code,
fp.price, l.link_id
SELECT ril.invoice_label_id, ril.invoice_label, ril.invoice_label_code,
ricf.fee, count(*) as ct, l.link_id
FROM consultation_chl c
INNER JOIN link_service_pct_location l on l.link_id=c.link_id
INNER JOIN medication m ON c.consult_id=m.consult_id
INNER JOIN ref_invoice_label ril ON m.formulary_id = ril.formulary_id
INNER JOIN pharmacy ph ON ph.pharmacy_id = l.id AND l.location_type_id = 3
INNER JOIN formulary f ON f.formulary_id=m.formulary_id
INNER JOIN formulary_price fp ON fp.formulary_id=f.formulary_id
INNER JOIN ref_invoice_consult_fee ricf ON ricf.invoice_label_id = ril.invoice_label_id
WHERE l.pct_id = 1425
AND l.service_id = 4
AND c.invoice_period = '2015-04-30'
AND ril.section_id=2
AND ril.invoice_label_code in ('MEDSUSP15-25','MEDSUSP16-35','MEDSUSP26-35','MEDSUSP36-45','MEDSUSP45+')
AND fp.valid_from <= c.consult_date
AND (fp.valid_to >= c.consult_date OR fp.valid_to IS NULL) GROUP BY ril.invoice_label_id, ril.invoice_label, ril.invoice_label_code,
ricf.fee, l.link_id
You should take a look at the UNION operator.
SQL UNION Operator at W3schools.com
As your selected columns each have same names
you should be able to concatenate the selects with a "UNION" keyword in between.

Subquery in from clause, Invalid Identifier in Where clause

select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from
iiasa_inventory.inv_device_2_persons_cc) dp
on dp.device_id = d.id
where dp.active = 1
I am trying to select my data but the where-clause says that "dp.active" is an INVALID Identifier. This is probably because the table dp is in the subquery. I have tried to give it an alias name and some other things I found while browsing stackoverflow, but I cant seem to find a solution. Any idea?
This is Oracle PL/SQL.
Put the check for active = 1 in the subquery as shown below.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from iiasa_inventory.inv_device_2_persons_cc where active = 1) dp on dp.device_id = d.id
That is because you are not selecting active column in dp.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id,active from iiasa_inventory.inv_device_2_persons_cc) dp on dp.device_id = d.id
where dp.active = 1
OR you can just filter from the subquery itself. Like:
left join (select distinct device_id
from iiasa_inventory.inv_device_2_persons_cc
where active=1) dp on dp.device_id = d.id

SQL Server 2008 Pivot table aggregate function issue

I have this query and I am trying to group by surveyname but im getting this error:
Msg 8120, Level 16, State 1, Line 1
Column 'pvt.Follow Up' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
This is the query:
SELECT
surveyname, [Follow Up] AS Follow_Up, [Ambiance] AS Ambiance,
[Consultation] AS Consultation, [Procedure/Service] AS Procedure_Service
FROM
(SELECT
s.name surveyname, q.question, subq.answer subquestion,aw.answerweight,
aw.score, rc.categoryname, sc.cweight
FROM survey.dbo.results r
JOIN survey.dbo.questions q ON r.questionidfk = q.id
LEFT JOIN survey.dbo.answers subq ON r.itemidfk = subq.id
LEFT JOIN survey.dbo.answers a ON r.answeridfk = a.id
JOIN survey.dbo.surveys s ON q.surveyidfk = s.id
join sigweb.dbo.survey_types_main stm on s.id = stm.surveyidfk
join survey.dbo.survey_results sr on r.owneridfk = sr.ownerid
join sigweb.dbo.BosleySurvey bs on bs.contactid = sr.contactid and stm.clientsurveytypeid = bs.surveytype
join sigweb.dbo.contact c on sr.contactid = c.contactid
join sigweb.dbo.patient p on p.contactid = c.contactid
join sigweb.dbo.doctor d on p.doctorid = d.doctorid
join sigweb.dbo.survey_tracking st on st.contactid = c.contactID and st.surveytypeid = stm.surveytypeid
left join survey.dbo.answerweighting aw on isnull(r.itemidfk, r.questionidfk) = aw.questionitemidfk and r.answeridfk = aw.answeridfk
left join survey.dbo.rating_categories rc on aw.categoryidfk = rc.id
left join survey.dbo.survey_categories sc on aw.categoryidfk = sc.categoryidfk and s.id = sc.surveyidfk
where
aw.answerWeight is not null) ps
PIVOT
(
AVG(score)
FOR categoryname IN
( [Follow Up], [Ambiance], [Consultation], [Procedure/Service])
) AS pvt
group by surveyname
This is an example of the results im getting
SURVEYNAME FOLLOW_UP Ambiance Consultation Procedure_Service
Review NULL NULL NULL 9.81
Review 9.54 NULL NULL NULL
Consultation 5 NULL NULL NULL
Consultation NULL 5 NULL NULL
Consultation NULL 5 NULL NULL
Consultation NULL 5 NULL NULL
Consultation NULL 5 NULL NULL
Consultation NULL 5 NULL NULL
Consultation NULL NULL 5 NULL
Consultation 5 NULL NULL NULL
Consultation NULL NULL 5 NULL
This is an example of the data before the pivot:
Review 6 Follow Up
Review 9 Procedure/Service
Consultation 5 Ambiance
Consultation 5 Ambiance
Consultation 5 Ambiance
Consultation 5 Ambiance
Consultation 5 Ambiance
Consultation 5 Ambiance
Consultation 5 Consultation
Consultation 5 Consultation
The idea is to group by the surveyname and have only two results in the end.
It appears that you are including too many columns in the inner SELECT, try to remove the columns:
q.question, subq.answer subquestion, aw.answerweight, sc.cweight
They are most likely making the rows DISTINCT so the GROUP BY does not work properly. So your query will be:
SELECT surveyname,
[Follow Up] AS Follow_Up,
[Ambiance] AS Ambiance,
[Consultation] AS Consultation,
[Procedure/Service] AS Procedure_Service
FROM
(
SELECT s.name surveyname,
aw.score,
rc.categoryname,
FROM survey.dbo.results r
JOIN survey.dbo.questions q
ON r.questionidfk = q.id
LEFT JOIN survey.dbo.answers subq
ON r.itemidfk = subq.id
LEFT JOIN survey.dbo.answers a
ON r.answeridfk = a.id
JOIN survey.dbo.surveys s
ON q.surveyidfk = s.id
join sigweb.dbo.survey_types_main stm
on s.id = stm.surveyidfk
join survey.dbo.survey_results sr
on r.owneridfk = sr.ownerid
join sigweb.dbo.BosleySurvey bs
on bs.contactid = sr.contactid
and stm.clientsurveytypeid = bs.surveytype
join sigweb.dbo.contact c
on sr.contactid = c.contactid
join sigweb.dbo.patient p
on p.contactid = c.contactid
join sigweb.dbo.doctor d on p.doctorid = d.doctorid
join sigweb.dbo.survey_tracking st
on st.contactid = c.contactID
and st.surveytypeid = stm.surveytypeid
left join survey.dbo.answerweighting aw
on isnull(r.itemidfk, r.questionidfk) = aw.questionitemidfk
and r.answeridfk = aw.answeridfk
left join survey.dbo.rating_categories rc
on aw.categoryidfk = rc.id
left join survey.dbo.survey_categories sc
on aw.categoryidfk = sc.categoryidfk and s.id = sc.surveyidfk
where aw.answerWeight is not null
) ps
PIVOT
(
AVG(score)
FOR categoryname IN
( [Follow Up], [Ambiance], [Consultation], [Procedure/Service])
) AS pvt
I am not sure where the error is coming from in what you have posted (I assume it is when you try and add GROUP BY SurveyName to the end of the query you have posted), but you need to remove the redundant columns from your subquery, so you only select the 3 columns you need, surveyname, score, and categoryname:
SELECT
surveyname, [Follow Up] AS Follow_Up, [Ambiance] AS Ambiance,
[Consultation] AS Consultation, [Procedure/Service] AS Procedure_Service
FROM
(SELECT
s.name surveyname, aw.score, rc.categoryname
FROM survey.dbo.results r
JOIN survey.dbo.questions q ON r.questionidfk = q.id
LEFT JOIN survey.dbo.answers subq ON r.itemidfk = subq.id
LEFT JOIN survey.dbo.answers a ON r.answeridfk = a.id
JOIN survey.dbo.surveys s ON q.surveyidfk = s.id
join sigweb.dbo.survey_types_main stm on s.id = stm.surveyidfk
join survey.dbo.survey_results sr on r.owneridfk = sr.ownerid
join sigweb.dbo.BosleySurvey bs on bs.contactid = sr.contactid and stm.clientsurveytypeid = bs.surveytype
join sigweb.dbo.contact c on sr.contactid = c.contactid
join sigweb.dbo.patient p on p.contactid = c.contactid
join sigweb.dbo.doctor d on p.doctorid = d.doctorid
join sigweb.dbo.survey_tracking st on st.contactid = c.contactID and st.surveytypeid = stm.surveytypeid
left join survey.dbo.answerweighting aw on isnull(r.itemidfk, r.questionidfk) = aw.questionitemidfk and r.answeridfk = aw.answeridfk
left join survey.dbo.rating_categories rc on aw.categoryidfk = rc.id
left join survey.dbo.survey_categories sc on aw.categoryidfk = sc.categoryidfk and s.id = sc.surveyidfk
where
aw.answerWeight is not null) ps
PIVOT
(
AVG(score)
FOR categoryname IN
( [Follow Up], [Ambiance], [Consultation], [Procedure/Service])
) AS pvt
In the background you are also grouping your end results by q.question, subq.answer subquestion,aw.answerweight, sc.cweight because they are included in the subquery, but because the are not in the select list you are not seeing immediately the effect this is having.