with t1 as (
SELECT *
from claim fc
inner join drug_product d
on d.drug_id = d.drug_id
AND d.id = d.id
inner join pharmacy pha
on fc.pharmacy_id = pha.pharmacy_id
and fcnum = pha.num
),
t2 as (
Select d_memberid,
fill_dt,
num,
d_drug_id,
count(distinct device_type) as device_count,
count(device_type),
count(distinct claim_ID)as claim_count
from t1
group by
d_member_id,
fill_dt,
num
)
Select t1.*,
t2.device_count,
d.*
from t1
inner join t2
on t1.num = t2.num
and t1.fill_dt = t2.fill_dt
and t1.d_member_id = t2.d_member_id
inner join drug_product d
on t1.d_drug_id = d.d_drug_id
order by claim_count desc
column ambiguouly defined. Im trying to find if there dup drug fill on the same day. line 54 column 32
column ambigously defined. I wonder if my joins are incorrect. for t1 i join 3 different table for t2 is from the first table. outcome should be a join of the t1 and t2
d_member_hq_id is not prefixed by a table alias, and could be causing the problem if the column name exists in more than 1 table in the from clause. There are other columns which are also not qualified, it is a good practice to qualify all columns to avoid this error.
Related
I am trying to select multiple values from two tables but i want to group by single value. I have tried using max(value) in select but max is returning the greatest one and not the exact one.
Here are my tables
The result i need is something like this
Result : HeadQuarterId - A, PropertyName - Name1, Amount - 102
HeadQuarterId - B, PropertyName - Name5, Amount - 30
Here is my query
SELECT Headquarterid,Max(PropertyName),sum(Amount)
FROM Table1 A LEFT OUTER JOIN Table2 B
ON A.Propetyid = B.PropertyId
GROUP BY Headquarterid
Here i have used Left Outer Join so that i will get all the data from left table even it is not available in right table.
Also i cannot use A.HeadquarterID = A.PropertyId in where condition since i have other dependency in that table. Please suggest someother way to achieve this result.
I think I understand. You want the headquarters with the maximum value, which happens to be A. If so:
select t1.*, sum(t2.amount) over () as total
from t1 left join
t2
on t2.PropertyId = t1.PropertyId
order by t2.amount desc
fetch first 1 row only;
Note: Not all databases support fetch first. It might be spelled limit or use select top (1) for instance.
I would recommend to get the headquartename per ID in a cte / subquery, then join it again to T1 and left join T1 to T2 in a second cte / subquery. This way you can calculate your sums basing on a single group:
WITH cte AS(
SELECT ROW_NUMBER() OVER (PARTITION BY t1.ID ORDER BY CASE WHEN t1.ID = t1.PROPERTYID THEN 0 ELSE 1 END) rn, t1.ID, t1.Name
FROM t1
),
cte2 AS(
SELECT c.name cName, t1.*, t2.Value
FROM t1
INNER JOIN cte c ON c.ID = t1.ID AND c.rn = 1
LEFT JOIN t2 ON t1.Propertyid = t2.propertyid
)
SELECT c2.id, c2.cname, sum(c2.value) value
FROM cte2 c2
GROUP BY c2.id, c2.cname
See SQLFiddle for details: http://sqlfiddle.com/#!18/8bf66/13/2
Of course you can build the first cte without the row_number only by using the WHERE ID = PROPERTYID - matter of taste I'd say...
As per your sample data you want window function :
select distinct t1.HeadQuarterId,
max(t1.PropertyName) over (partition by t1.HeadQuarterId) as PropertyName,
sum(t2.amount) over (partition by t1.HeadQuarterId) as amount
from t1 left join
t2
on t2.PropertyId = t1.PropertyId;
This provided the result i expected.
SELECT HQTRS1 AS headId,Max(LLORD1) AS headName, sum(Amount) AS amount
FROM
(SELECT DISTINCT HeadQuarterId AS HQTRS1, PropertyName AS LLORD1 FROM Table_1 WHERE HeadQuarterId = PropertyId) AS temp
INNER JOIN Table_1 AS A ON A.HeadQuarterId = temp.HQTRS1
LEFT OUTER JOIN Table_2 B
ON B.PropertyId = A.PropertyId
GROUP BY HQTRS1
SELECT a1,a2,a3,a4,count(a5),b1,b2,b3
FROM table1
LEFT JOIN table2 ON a1=b1 AND a2=b2 (*here i need to join
next columns a3=b3 only if from table2 will be returned more than 1 records
other wise first 2 columns will be enough*)
group by a1,a2,a3,a4,a5,b1,b2,b3
Anybody knows how to perform this trick ?
Well, if I understand correctly:
FROM table1 t1 LEFT JOIN
(SELECT t2.*, COUNT(*) OVER (PARTITION BY b1, b2) as cnt
FROM table2 t2
)
ON t1.a1 = t2.b1 AND t1.a2 = t2.b2 AND
(cnt = 1 OR t1.a3 = t2.a3)
I have the following 3 tables:
main_table:
id,name,table_type
1a,sas,1
2a,saw,1
3a,sdd,2
inst_table
id,inst_name,rating
1a,sdsdf,3
2a,erer,4
indv_table
id,ind_name,rating
3a,gbgbg,3
5a,gff,4
How to join the subtables based on main_table column:'table_type'?
I.e., if main table column: table_type = 1, then it has to join with table:'inst_table' else table:'indv_table'
SELECT *
FROM main_table t1
INNER JOIN inst_table t2 ON T1.ID = T2.ID where t1.table_type=1
UNION ALL
SELECT *
FROM main_table T1
INNER JOIN indv_table T3 ON T1.ID = T3.ID where t1.table_type=2
You can left join both sub-tables to main_table:
proc sql;
select m.*, i.*, d.*
from main_table as m
left join inst_table as i on m.id=i.id and m.table_type = 1
left join indv_table as d on m.id=d.id and m.table_type ne 1
;
quit;
I've two tables T1 and T2 with the following columns -
T1
Project_ID
Category
Column_X
Column_Y
Column_Z
T2
Proj_ID
Category
Parent_Project_ID
I want to write a query to get records from T1 with the following condition -
Get Projects with Category = "A" from T1
Get child projects of the above filtered projects
I'm not sure how to check the second condition only with the results coming out of first condition.
What is needed?
Projects from T1 where Category is A
Child projects of projects obtained from condition 1
Adding sample data and desired results as requested -
To get all records from second table then you can use the following query.
SELECT
t2.*
FROM T1 t1
RIGHT OUTER JOIN T2 t2 ON t1.Project_ID = t2.Project_ID
WHERE t1.Category = "A"
SELECT * FROM T2 WHERE T2.Proj_ID IN ( SELECT Project_ID FROM T1 WHERE Category = 'A' )
This should do the job needed.
SELECT * from T2 as d
WHERE EXISTS ( SELECT * from T1 as d1 where d1.Category = 'A' and d1.Project_ID = d.Proj_ID )
SELECT * from T1 as d1 right join T2 as d2 on d1.Project_ID = d2.Proj_ID
WHERE d1.CodTert = 500
I've made an update, these query give the same result, one uses the JOIN one doesn't.
I'm assuming that T2.Parent_Project_ID and T1.Project_ID are related. If so, you can use this:
Select T3.*
From T1
Join T2 On T2.Parent_Project_ID = T1.Project_ID
Join T1 T3 On T3.Project_ID = T2.Proj_ID
Where T1.Category = 'A'
This would get only child projects of projects that have a category of 'A'.
EDIT:
Based on the output format that has been added to the question, the following query, which uses a LEFT OUTER JOIN would render the exact result required:
SELECT
T2.PROJ_ID Project_ID,
T2.Category,
T1.Column_X,
T1.Column_Y,
T1.Column_Z,
T2.Parent_Project_ID
FROM T1 T1_PARENTS
INNER JOIN T2
ON T2.Parent_Project_ID = T1.Project_ID and T1.Category = 'A'
INNER JOIN T2 T2_CHILDREN
ON T2_CHILDREN.PROJ_ID = T2.Parent_Project_ID OR T2_CHILDREN.Parent_Project_ID = T2.Parent_Project_ID
LEFT OUTER JOIN T1
ON T2_CHILDREN.PROJ_ID = T1.Project_ID;
I have two tables, linked with an outer join. The relationship between the primary and secondary table is a 1 to [0..n]. The secondary table includes a timestamp column indicating when the record was added. I only want to retrieve the most recent record of the secondary table for each row in the primary. I have to use a group by on the primary table due to other tables also part of the SELECT. There's no way to use a 'having' clause though since this secondary table is not part of the group.
How can I do this without doing multiple queries?
For performance, try to touch the table least times
Option 1, OUTER APPLY
SELECT *
FROM
table1 a
OUTER APPY
(SELECT TOP 1 TimeStamp FROM table2 b
WHERE a.somekey = b.somekey ORDER BY TimeStamp DESC) x
Option 2, Aggregate
SELECT *
FROM
table1 a
LEFT JOIN
(SELECT MAX(TimeStamp) AS maxTs, somekey FROM table2
GROUP BY somekey) x ON a.somekey = x.somekey
Note: each table is mentioned once, no correlated subqueries
Something like:
SELECT a.id, b.*
FROM table1 a
INNER JOIN table2 b ON b.parentid = a.id
WHERE b.timestamp = (SELECT MAX(timestamp) FROM table2 c WHERE c.parentid = a.id)
Use LEFT JOIN instead of INNER JOIN if you want to show rows for IDs in table1 without any matches in table2.
select *
from table1 left outer join table2 a on
table1.id = a.table1_id
where
not exists (select 1 from table2 b where a.table1_id = b.table1_id and b.timestamp > a.timestamp)
The quickest way I know of is this:
SELECT
A.*,
B.SomeField
FROM
Table1 A
INNER JOIN (
SELECT
B1.A_ID,
B1.SomeField
FROM
Table2 B1
LEFT JOIN Table2 B2 ON (B1.A_ID=B2.A_ID) AND (B1.TimeStmp < B2.TimeStmp)
WHERE
B2.A_ID IS NULL
) B ON B.A_ID = A.ID