SQL - join multiplying data - sql

I need to produce a synthetic table from 2 tables but one of them is tricky.
First table (sample):
Second table (sample also) :
I want to use it to find the 'store' of each 'pers'
What i want at the end :
(and i want to keep the 'zero' if sum_of_duration is null)
My first code :
SELECT
QRT,
STORE,
sum(DURATION) as SUM_of_DURATION
FROM T1
LEFT JOIN T2
on T1.PERS=T2.PERS
group by QRT, STORE
But my 'Sum_of_durations' are out of the roof because of multiple joins induced by table 2 i guess.
Any help ?
Thanks

Remove duplicates before joining:
SELECT T1.QRT, T2.STORE,
SUM(T1.DURATION) as SUM_of_DURATION
FROM T1 LEFT JOIN
(SELECT DISTINCT QRT, PERS
FROM t2
) t2
ON T1.PERS = T2.PERS
GROUP BY T1.QRT, T2.STORE;

Related

SQL Query to Join Two Tables where data in one table is transposed

I'm trying to join two tables but not getting the desired results. Im new to SQL and will need help to joining these two tables.
The data in Table 2 is transposed and the table will only be populated only when the "value" field is populated with random values.
Details of Table 1 and Table 2 and expected output
You could use CTEs to split up the impact from outcome. Also, your screenshot had an error for task_id 6.
with t_impact as (
select task_id, value
from table2
where name = 'task_impact'
),
t_outcome as (
select task_id, value
from table2
where name = 'task_outcome'
)
select distinct t1.id,
t1.title,
i.value as task_impact,
o.value as task_outcome
from table1 t1
left join t_impact i
on t1.id = i.task_id
left join t_outcome o
on t1.id = o.task_id
order by t1.id
DB-fiddle found here.

Join table in oracle database

I have 2 tables that showing data Item master and BOM. I would like to join the tables between Item master as T1 and BOM as T2 and the additional table for table BOM as T3. Item master table containing ITM_CD, ITM_TYP (1,2,3,4) where each ITM_TYP represents a code for the first digit on ITM_CD. The thing that I want is like the picture below
CHILD_CD2 value replace to CHILD_CD1 value. So the data should be like this. What query should I fix ? I am very new using oracle query.
Here is mycode;
SELECT DISTINCT
T1.ITM_CD,
T2.C_ITM_CD AS CHILD_CD1,
T3.C_ITM_CD AS CHILD_CD2
FROM CM_HINMO_ALL T1
INNER JOIN (SELECT P_ITM_CD, C_ITM_CD, BOM_PTN FROM SM_BOM_ALL) T2
ON T1.ITM_CD = T2.P_ITM_CD
LEFT JOIN (SELECT P_ITM_CD, C_ITM_CD, BOM_PTN FROM SM_BOM_ALL) T3
ON T2.C_ITM_CD = t3.P_ITM_CD
WHERE 0=0
AND T2.BOM_PTN IN (1)
AND T1.ITM_TYP IN (1,2)
AND T1.ITM_CD = '110100370'
ORDER BY 2
Just use Case expression to replace the values.
SELECT ITM_CD, CASE WHEN CHILD_CD2 IS NULL THEN CHILD_CD2 ELSE CHILD_CD1 END AS CHILD_CD1
FROM TABLE1
If I understood, you want child_cd2 value should taken precedence over child_cd1 if available. If this assumption is right then we can use coalesce which returns the fist non null expression to achieve the same.
SELECT DISTINCT
T1.ITM_CD,
COALESCE(T3.C_ITM_CD,T2.C_ITM_CD) AS CHILD_CD1
FROM CM_HINMO_ALL T1
INNER JOIN SM_BOM_ALL T2
ON T1.ITM_CD = T2.P_ITM_CD
LEFT JOIN SM_BOM_ALL T3
ON T2.C_ITM_CD = t3.P_ITM_CD
WHERE T2.BOM_PTN IN (1)
AND T1.ITM_TYP IN (1,2)
AND T1.ITM_CD = '110100370'
ORDER BY 2

sql - ignore duplicates while joining

I have two tables.
Table1 is 1591 rows. Table2 is 270 rows.
I want to fetch specific column data from Table2 based on some condition between them and also exclude duplicates which are in Table2. Which I mean to join the tables but get only one value from Table2 even if the condition has occurred more than time. The result should be exactly 1591 rows.
I tried to make Left,Right, Inner joins but the data comes more than or less 1591.
Example
Table1
type,address,name
40,blabla,Adam
20,blablabla,Joe
Table2
type,currency
40,usd
40,gbp
40,omr
Joining on 'type'
Result
type,address,name,currency
40,blabla,name,usd
20,blblbla,Joe,null
try this it has to work
select *
from
Table1 h
inner join
(select type,currency,ROW_NUMBER()over (partition by type order by
currency) as rn
from
Table2
) sr on
sr.type=h.type
and rn=1
Try this. It's standard SQL, therefore, it should work on your rdbms system.
select * from Table1 AS t
LEFT OUTER JOIN Table2 AS y ON t.[type] = y.[type] and y.currency IN (SELECT MAX(currency) FROM Table2 GROUP BY [type])
If you want to control which currency is joined, consider altering Table2 by adding a new column active/non active and modifying accordingly the JOIN clause.
You can use outer apply if it's supported.
select a.type, a.address, a.name, b.currency
from Table1 a
outer apply (
select top 1 currency
from Table2
where Table2.type = a.type
) b
I typical way to do this uses a correlated subquery. This guarantees that all rows in the first table are kept. And it generates an error if more than one row is returned from the second.
So:
select t1.*,
(select t2.currency
from table2 t2
where t2.type = t1.type
fetch first 1 row only
) as currency
from table1 t1;
You don't specify what database you are using, so this uses standard syntax for returning one row. Some databases use limit or top instead.

SQL Tables need to be appended, but not like JOINS

I've a scenario as below.
I've two tables, and a Common column/Key between the two.
I need Table2 data to be just appended to Table1 without repetition like JOINs.
If there are more rows in one table, other table rows can be NULL.
As shown in figure, Result Table has NULLs when there is no corresponding row count from Table2.
I tried using Joins, but I'm getting a result of 45 rows. But I should get 9 rows.
Thanks in advance.
Edit: Added my queries
SELECT DISTINCT
APPT.PRSN_ID
,APPT.SCHEDULEDAPPOINTMENTS
,APPT.OVERDUEAPPOINTMENTS
,Visit.ENCOUNTER_CATEGORY
,Visit.ENCOUNTER_TYPE
,Visit.ENCOUNTER_DATE
,Visit.ENCOUNTER_FOLLOWUP_DATE
FROM
APPOINTMENTS APPT
OUTER APPLY dbo.fn_GetVisitsOfAPerson(PROV.PRSN_ID) AS Visit
/***********************************************************/
--IN THE ABOVE QUERY, THE FUNCTION IS DEFINED AS BELOW
CREATE FUNCTION dbo.fn_GetVisitsOfAPerson(#PrsnID AS bigint)
RETURNS TABLE
AS
RETURN
(
SELECT
VISITS.PVISITS_PRSN_KEY
,DATA.HE_Category_Description AS 'ENCOUNTER_CATEGORY'
,DATA.HE_Type_Description AS 'ENCOUNTER_TYPE'
,VISITS.PVISITS_DATE AS 'ENCOUNTER_DATE'
,VISITS.PVISITS_FOLLOWUP_DATE AS 'ENCOUNTER_FOLLOWUP_DATE'
FROM
[HS_PRSN_HEALTH_VISITS] VISITS INNER JOIN
[HS_HealthEncounter_Table] DATA ON
ENCOUNTER.PVISITS_CATEGORY = DATA.HE_Category_Code AND
ENCOUNTER.PVISITS_TYPE = DATA.HE_Type_Code
WHERE
PVISITS_PRSN_KEY = #PrsnID
AND PVISITS_VOID = 0
)
GO
I cannot read your data tables, but I think you just need to introduce a row number.
It would be something like this:
select . . .
from (select t1.*, row_number() over (partition by key order by ??) as seqnum
from table1 t1
) full join
(select t2.*, row_number() over (partition by key order by ??) as seqnum
from table1 t2
) t2
on t1.key = t2.key and t1.seqnum = t2.seqnum;
Based on you wanting the 9 rows present in the Visit table it looks like you need an OUTER JOIN, something like:
SELECT DISTINCT
APPT.PRSN_ID
,APPT.SCHEDULEDAPPOINTMENTS
,APPT.OVERDUEAPPOINTMENTS
,Visit.ENCOUNTER_CATEGORY
,Visit.ENCOUNTER_TYPE
,Visit.ENCOUNTER_DATE
,Visit.ENCOUNTER_FOLLOWUP_DATE
FROM Visit
LEFT OUTER JOIN
APPOINTMENTS APPT
ON Visit.key = APP.key

How to summarize two tables in teradata

I have the following two tables
I need to create a table that would summarize points for each date
How can I do this . I have updraded to Teradata 14 . And I am not quite familiar with all the new functions
If table1 is actually only a few rows you don't need any fancy query.
Assuming table1.caseid is a byteint this will result in a product join:
Select t2.datex, t2.caseid, sum(t1.points)
from table1 as t1 join table2 a t2
on position(trim(t1.caseid) in t2.caseid) > 0
group by 1,2
Of course if this was a properly normalized table you could simple use a t1.caseid = t2.caseid join instead.