SQL Join Rows to column - sql

I have left join between two tables where it returns two records I need that record should be converted from rows to column.
SQL join as follows:
select (case when l.PatientVisitCluster=1 then t.Result end) as t1,
(case when l.PatientVisitCluster=2 then t.Result end) as t2
from tPatientLabTestData t left join
tPatientLabTest l
on t.tPatientLabTestId = l.Id
where l.PatientId = #PatientId and
l.Volgnar = #Volgnar and
l.TestTypeListId = #LabTestId
It returns result like this.
I need desired result like below:
t1 t2
22 120

Use aggregation:
select max(case when l.PatientVisitCluster = 1 then t.Result end) as t1,
max(case when l.PatientVisitCluster = 2 then t.Result end) as t2
from tPatientLabTestData t left join
tPatientLabTest l
on t.tPatientLabTestId=l.Id
where l.PatientId = #PatientId and
l.Volgnar = #Volgnar and
l.TestTypeListId = #LabTestId;
If you wanted this for all combinations of the three columns, include group by:
select l.PatientId, l.Volgnar, l.TestTypeListId,
max(case when l.PatientVisitCluster = 1 then t.Result end) as t1,
max(case when l.PatientVisitCluster = 2 then t.Result end) as t2
from tPatientLabTestData t left join
tPatientLabTest l
on t.tPatientLabTestId=l.Id
group by l.PatientId, l.Volgnar, l.TestTypeListId;

You can also use PIVOT
select PatientId, Volgnar, TestTypeListId, [1] t1, [2] t2
from tPatientLabTestData t
left join tPatientLabTest l on t.tPatientLabTestId=l.Id
pivot (max(result) for PatientVisitCluster in ([1], [2])) p

Related

SQL / Oracle SQL Code for looking data from other tables

How to write query to get data from other table for each columns in existing table.
You can left join three times on system_code:
select
d.id,
s_cat.full_name cat_code_full_name,
s_group.full_name group_code_full_name,
s_other.full_name other_code_full_name
from data_table d
left join system_code s_cat
on s_cat.value = d.cat_code and s.code = 1
left join system_code s_group
on s_group.value = d.group_code and s_group.code = 2
left join system_code s_other
on s_other.value = d.other_code and s_other.code = 3
To avoid repeating the joins, an alternative solution is to do conditional aggregation:
select
d.id,
max(case when s.value = d.cat_code and s.code = 1 then s.full_name end) cat_code_full_name,
max(case when s.value = d.group_code and s.code = 2 then s.full_name end) group_code_full_name,
max(case when s.value = d.other_code and s.code = 3 then s.full_name end) other_code_full_name
from data_table d
left join system_code s on s.value in (d.cat_code, d.group_code, d.other_code)
gtoup by d.id
I guess the problem you are facing here is, how to get full name for all 3 columns. 1 of the method is to join SYSTEM_CODE table thrice -
SELECT DT.ID
,SC1.FULL_NAME CAT_CODE_FULL_NAME
,SC2.FULL_NAME GROUP_CODE_FULL_NAME
,SC3.FULL_NAME OTHER_CODE_FULL_NAME
,DT.PRODUCT
FROM DATA_TABLE DT
JOIN SYSTEM_CODE SC1 ON SC1.VALUE = DT.CAT_CODE
JOIN SYSTEM_CODE SC2 ON SC2.VALUE = DT.CAT_CODE
JOIN SYSTEM_CODE SC3 ON SC3.VALUE = DT.CAT_CODE

Adding data into one table from two select queries targeting different number of columns from two different tables

I have two select queries having different number of columns in each query with different where conditions.I want to add data gathered from two select queries into one table. i have seen method of doing "UNION" but in that case columns in two queries need to be same in number how can i add data from two queries into single table. My queries are as under:
Select
Village_ID,
Village_Name,
RSP_ID,
Other_Loan_Source,
Informal_Money_Lender_Loans
from(
Select DISTINCT SETTLEMENT_ID as Village_ID,
SETTLEMENT_NAME as Village_Name,
RSP_ID,
(SELECT COUNT(*) FROM PscData where SETTLEMENT_ID = T.SETTLEMENT_ID
AND TAKEN_LOAN = 6 )as Other_Loan_Source,
(SELECT COUNT(*) FROM PscData where SETTLEMENT_ID = T.SETTLEMENT_ID
AND TAKEN_LOAN = 5 )as Informal_Money_Lender_Loans
FROM PscData as T
)tmp
and the second query is this:
SELECT
SUM(CASE WHEN t2.SEX = 1
THEN 1 ELSE 0 END) AS Total_Males,
SUM(CASE WHEN t2.SEX = 2
THEN 1 ELSE 0 END) AS Total_Females,
SUM(CASE WHEN t2.MARITAL_STATUS = 1
THEN 1 ELSE 0 END) AS Total_Married,
t1.SETTLEMENT_ID
FROM PScData t1
INNER JOIN PscMemberData t2
ON t2._PARENT_AURI = t1.URI
GROUP BY
t1.SETTLEMENT_ID
HAVING COUNT(*) > 1;
how do i combine results of these into one table.
You can first create a table using the union and only the fields that exist in both tables. Then you join this table to the original tables to add the remaining fields.
with cte as (
select Village_ID as village_settlement_id
from #tmp_1
union
select SETTLEMENT_ID as village_settlement_id
from #tmp_2
)
select *
, #tmp_1.Village_ID
, #tmp_1.Village_Name
, #tmp_1.RSP_ID
, #tmp_1.Other_Loan_Source
, #tmp_1.Informal_Money_Lender_Loans
, #tmp_2.Total_Males
, #tmp_2.Total_Females
, #tmp_2.Total_Married
from cte
left join #tmp_1 on cte.village_settlement_id = #tmp_1.Village_ID
left join #tmp_2 on cte.village_settlement_id = #tmp_1.SETTLEMENT_ID
Why don't you just add a dummy column to the second table?
SELECT
SUM(CASE WHEN t2.SEX = 1
THEN 1 ELSE 0 END) AS Total_Males,
SUM(CASE WHEN t2.SEX = 2
THEN 1 ELSE 0 END) AS Total_Females,
SUM(CASE WHEN t2.MARITAL_STATUS = 1
THEN 1 ELSE 0 END) AS Total_Married,
t1.SETTLEMENT_ID ,
'' Informal_Money_Lender_Loans
FROM PScData t1

whats wrong with my code(sub query - sql server)

I am getting incorrect syntax near ')', c an someone suggest what i am doing wrong? I am trying to get my self familiar with sub queries and thanks in advance!
attached is the sql that i wrote and trying to modify here us the SQL script
(
SELECT
APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 0 THEN CUST_APP_ID END) AS PRI_CUST_APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 1 THEN CUST_APP_ID END) AS SEC_CUST_APP_ID,
....
....
FROM
(
SELECT
APP_ID,
CUST.CUST_ID,
CUST_TYPE_ORD_NUM
..
FROM CDM_CUST_APP_MTRX CUST_APP_MTRX
LEFT JOIN CDM_CUST CUST ON CUST_APP_MTRX.CUST_ID = CUST.CUST_ID
) CUST_MTRX
GROUP BY APP_ID
) ABC
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL.CUST_APP_ID
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL2
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL2.CUST_APP_ID
It is a syntax issue. Write one more SELECT * FROM before first bracket in the first line of the query.
SELECT * FROM (
SELECT
APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 0 THEN CUST_APP_ID END) AS PRI_CUST_APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 1 THEN CUST_APP_ID END) AS SEC_CUST_APP_ID
FROM
(
SELECT
APP_ID,
CUST.CUST_ID,
CUST_TYPE_ORD_NUM,
..
FROM CDM_CUST_APP_MTRX CUST_APP_MTRX
LEFT JOIN CDM_CUST CUST ON CUST_APP_MTRX.CUST_ID = CUST.CUST_ID
) CUST_MTRX
GROUP BY APP_ID
) ABC
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL.CUST_APP_ID
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL2
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL2.CUST_APP_ID

SQl Error : Each GROUP BY expression must contain at least one column that is not an outer reference [duplicate]

This question already has answers here:
Each GROUP BY expression must contain at least one column that is not an outer reference
(8 answers)
Closed 6 years ago.
I get this error
Each GROUP BY expression must contain at least one column that is not an outer reference
while running this query:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN
#tmpInstallParts_Temp installpartdetails ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END
) = 1
INNER JOIN
partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN
partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN
partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y' AND
ima.ipp_ID IN (SELECT ipp.ipp_id
FROM partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp ON (ipp.ipp_id = tmp.InstallingPartIPPId OR
(CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1
)
GROUP BY
ima.ipp_id
Can someone help me?
This is the text of the query from the first revision of the question.
In later revisions you removed the last closing bracket ) and the query became syntactically incorrect. You'd better check and fix the text of the question and format the text of the query, so it is readable.
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
GROUP BY
ima.ipp_id
)
With this formatting it is clear now that there is a subquery with GROUP BY.
Most likely it is just a typo: you meant to write GROUP BY ipp.ipp_id instead of GROUP BY ima.ipp_id.
If you really wanted to have the GROUP BY not in a subquery, but in the main SELECT, then you misplaced the closing bracket ) and the query should look like this:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
)
GROUP BY
ima.ipp_id
In any case, proper formatting of the source code can really help.
Group By ima.ipp_id
should be applicable to outer query. Because of incorrect placement of '(' it was applying to inner query.
Now after correcting the query,it's working fine without any issues.
Final Query is :
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END ) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END ) =1)
)
GROUP BY ima.ipp_id
Thank you all.

Write query using JOINS

select
store, sum(value)
from
rms.sa_tran_head
where
store_day_seq_no in (select store_day_seq_no
from rms.sa_store_day
where store in (3003)
and business_date = '01-JAN-2015')
and tran_type in ('SALE', 'RETURN')
group by
store;
How to write the above query using JOINS..
SELECT
sd.store,
SUM(TH.VALUE) AS GROSS ,
SUM(ti.qty) AS QTY
FROM rms.sa_tran_head AS th
JOIN rms.sa_store_day AS sd
ON th.store_day_seq_no = sd.store_day_seq_no
JOIN rms.sa_tran_item AS ti
ON ti.tran_seq_no = th.tran_seq_no
WHERE sd.store in (3003) --in (3003) use in if more than 1 value
AND sd.business_date = '01-JAN-2015'
AND th.tran_type IN ('SALE','RETURN')
GROUP BY
sd.store;
When I add other columns of another table it is showing different values...
I assumed store_day_seq_no is FK for the table rms.sa_store_day and the query with JOIN like this,
SELECT
sd.store,
SUM(sd.value) AS [Sum]
FROM rms.sa_tran_head AS th
JOIN rms.sa_store_day AS sd
ON th.store_day_seq_no = sd.store_day_seq_no
WHERE
sd.store = 3003 --in (3003) use in if more than 1 value
AND sd.business_date = '01-JAN-2015'
AND th.tran_type IN ('SALE','RETURN')
GROUP BY
sd.store;
I think this is ok.
SELECT
t1.store,
SUM(t1.Value) AS Sum_Value
FROM rms.sa_tran_head t1
INNER JOIN sa_store_day t2 ON t1.store_day_seq_no = t2.store_day_seq_no
WHERE t2.store IN ( 3003 )
AND t2.business_date = '01-JAN-2015'
AND t1.tran_type IN ( 'SALE' , 'RETURN' )
GROUP BY t1.store