My SQL code produce per_month, per_month min, per_month max and per_month standard deviation. But i have done it with CTE. now i want to do without CTE.
;WITH QTY_T AS(
SELECT
YEAR(SHIP_DATE) [Year],
MONTH(SHIP_DATE) [Month],
T1.PLANT AS PLANTS,
WC AS W_C,
T2.SHIP_TO AS SHIP_TO,
T1.PARTS AS PARTS,
SUM([QTY_MII]) AS [QTY_MONTH]
FROM TABLE1 T1
INNER JOIN
TABLE2 T2
ON
T2.OBD = T1.OBD
INNER JOIN
TABLE3 T3
ON T1.OBD=T3.OBD AND T1.ITEM = T3.ITEM AND T1.PLANT = T3.PLANT
INNER JOIN
TABLE4 T4
ON T3.SHIP_LBL = T4.HU_CODE AND T4.STATUS ='SHIPPED'AND T4.PLANT = T3.PLANT
GROUP BY
T1.PLANT,WC,SHIP_TO,T1.PARTS,YEAR(SHIP_DATE),MONTH(SHIP_DATE)
) SELECT
PLANTS,W_C,PARTS,SHIP_TO,
ROUND(AVG(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH,
ROUND(MIN(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_MIN,
ROUND(MAX(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_MAX,
ROUND(AVG(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_AVG,
ROUND(STDEV(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_STD
FROM QTY_T
GROUP BY PLANTS,W_C,QTY_T.SHIP_TO,QTY_T.PARTS
you can use subquery without cte
SELECT
PLANTS,W_C,PARTS,SHIP_TO,
ROUND(AVG(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH,
ROUND(MIN(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_MIN,
ROUND(MAX(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_MAX,
ROUND(AVG(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_AVG,
ROUND(STDEV(QTY_MONTH),3) AS QTY_SHIPPED_PER_MONTH_STD
FROM (
SELECT
YEAR(SHIP_DATE) [Year],
MONTH(SHIP_DATE) [Month],
T1.PLANT AS PLANTS,
WC AS W_C,
T2.SHIP_TO AS SHIP_TO,
T1.PARTS AS PARTS,
SUM([QTY_MII]) AS [QTY_MONTH]
FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T2.OBD = T1.OBD
INNER JOINTABLE3 T3 ON T1.OBD=T3.OBD AND T1.ITEM = T3.ITEM AND T1.PLANT = T3.PLANT
INNER JOIN TABLE4 T4 ON T3.SHIP_LBL = T4.HU_CODE AND T4.STATUS ='SHIPPED'AND T4.PLANT = T3.PLANT
GROUP BY
PLANT,WC,SHIP_TO,T1.PARTS,YEAR(SHIP_DATE),MONTH(SHIP_DATE)
) as QTY_T
GROUP BY PLANTS,W_C,QTY_T.SHIP_TO,QTY_T.PARTS
Related
Currently struggling with a second subquery (t3) which is giving me a syntax error. The query works fine if t3 is excluded.
SELECT switch(LEFT(t1.[treatment],1)='C',"Complaint",LEFT(t1.[treatment],1)='P',"Post") AS Treatment, count(t1.[ID]) AS Total_Vol, count(t2.[event]) AS Total_Posted, format(count(t2.[event]) / count(t1.[ID]),"0.00%") AS Percentage, COUNT(IIF(t1.[requirements]='1',1,)) AS Special _Population,count(t3.[approved]) as Approved_vol
FROM Main_audit_table_v3 AS t1 LEFT JOIN (SELECT t2.[ID], t2.[event] FROM Main _table AS t2 WHERE t2.event Not Like ('NA')) AS t2 ON t1.[ID] = t2.[ID]
LEFT JOIN (SELECT t3.[ref],t3.[requirement],t3.[approved] from Main_table AS t3 where
t3.[requirement] = '1' and t3.[approved] not like ('NA')) as t3
t2.[ID] = t3.[ID]
GROUP BY LEFT(t1.[treatment],1);
The expected output is that the [approved] column will provide a count of records where requirement = 1 and approved not like NA.
In MS Access you need additional parentheses for JOINs. And you are missing ON:
SELECT . . .
FROM (Main_audit_table_v3 AS t1 LEFT JOIN
(SELECT t2.[ID], t2.[event]
FROM Main _table AS t2
WHERE t2.event Not Like ('NA')
) AS t2 ON t1.[ID] = t2.[ID]
) LEFT JOIN
(SELECT t3.[ref], t3.[requirement], t3.[approved]
FROM Main_table AS t3
WHERE t3.[requirement] = '1' and t3.[approved] not like 'NA'
) as t3
ON t2.[ID] = t3.[ID]
GROUP BY LEFT(t1.[treatment], 1);
I am trying to sum the total value of a column for a specific ID after multiple left joins.
The below code gives me what I am looking for but across multiple rows, I need the value for T3.C_Amt and T4.E_Amt to be totaled.
SELECT
T1.ID,
T2.Unique_ID,
T3.C_Date,
T3.C_Amount,
T4.D_Date,
T4.D_Amount
FROM
TABLE_1 T1
LEFT JOIN DATABASE1.TABLE_2 T2
ON T1.ID = T2.UNIQUE_ID
LEFT JOIN DATABASE1.TABLE_3 T3
ON T2.Unique_ID = T3.Unique_ID
AND T3.C_Date = '2019-04-11'
LEFT JOIN DATABASE1.TABLE_4 T4
ON T2.Unique_ID = T4.Unique_ID
AND T4.D_Date= '2019-04-11'
--this needs to be summed to have the total amount
I want it to return one row for the Unique ID with total C_Amount and total D_Amount for the specific date
Use aggregation with group by
SELECT T2.Unique_ID,T3.C_Date,sum(T3.C_Amount),
T4.D_Date,sum(T4.D_Amount)
FROM TABLE_1 T1
LEFT JOIN DATABASE1.TABLE_2 T2
ON T1.ID = T2.UNIQUE_ID
LEFT JOIN DATABASE1.TABLE_3 T3
ON T2.Unique_ID = T3.Unique_ID AND T3.C_Date = '2019-04-11'
LEFT JOIN DATABASE1.TABLE_4 T4
ON T2.Unique_ID = T4.Unique_ID AND T4.D_Date= '2019-04-11'
group by T2.Unique_ID,T3.C_Date,T4.D_Date
I would do it this way. Since Teradata is a MPP, there should not be much of a performance impact as well.
SELECT Unique_ID,C_Date,sum(C_Amount),D_Date,sum(D_Amount)
FROM
(
SELECT
T1.ID ID,
T2.Unique_ID Unique_ID,
T3.C_Date C_Date,
T3.C_Amount C_Amount,
T4.D_Date D_Date,
T4.D_Amount D_Amount
FROM
TABLE_1 T1
LEFT JOIN DATABASE1.TABLE_2 T2
ON T1.ID = T2.UNIQUE_ID
LEFT JOIN DATABASE1.TABLE_3 T3
ON T2.Unique_ID = T3.Unique_ID
AND T3.C_Date = '2019-04-11'
LEFT JOIN DATABASE1.TABLE_4 T4
ON T2.Unique_ID = T4.Unique_ID
AND T4.D_Date= '2019-04-11'
) ABC
GROUP BY Unique_ID,C_Date,D_Date
I would add a concern of 1-to-many causing a false total. What if table 3 has 10 records for a given T2.UniqueID and another 5 for the T4 table. You have just compounded your total completely out of range.
As such, I would pre-aggregate from the child tables grouped by the unique ID filtered on the date. Also, you can remove the T2 table due to associative properties.
T1.ID = T2.Unique_ID = T3.Unique_ID = T4.Unique_ID
to T1.ID = T3.Unique_ID = T4.Unique_ID
SELECT
T1.ID,
T3.C_Date,
T3.C_Amount,
T4.D_Date,
T4.D_Amount
FROM
TABLE_1 T1
LEFT JOIN
( Select Unique_ID, sum( C_Amount ) as T3Sum
from DATABASE1.TABLE_3
where T3.C_Date = '2019-04-11'
group by Unique_ID ) T3
ON T1.ID = T3.Unique_ID
LEFT JOIN
( select Unique_ID, sum( D_Amount ) T4Sum
from DATABASE1.TABLE_4
where D_Date= '2019-04-11'
group by Unique_ID ) T4
ON T1.ID = T4.Unique_ID
Now, your ambiguity on table names might help being more real-life descriptive. Your summary amounts are based on a single date, but how many records in T1 that are applicable? If you have 5k rows in T1 and only 450 entries total between tables T3 and T4, your result set would still give you all the rows. That being said, you probably dont want the bloat of records that don't have any such details in the secondary sum subqueries. I would add a WHERE clause at the end
WHERE
T3.Unique_ID IS NOT NULL
OR T4.Unique_ID IS NOT NULL
image of what I want
I have tried the join on x or y and it didn't work, even the group by didn't work.
What almost gave me the result is the query below
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id, B.AccNo1, B.AccNo2, B.Name,
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
After getting the query correct I want to show only the exceptions where there was no link between the tables and its kind of difficult if the T1.ID is repeated
You seem to want a left join:
select t1.*, t2.*
from table1 t1 left join
table2 t2
on t1.id in (t2.accno1, t2.accno2);
Try:
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B
ON A.AccNo = (CASE WHEN A.AccNo = B.AccNo1 THEN B.AccNo1 ELSE B.AccNo2 END)
You may nest your original query, and then use max aggregate function with grouping :
SELECT Id ,AccNo ,Name, max(Id2) as Id2, max(Name2) as Name2,
max(AccNo1) as AccNo1, max(AccNo2) as AccNo2
FROM
(
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2 ,B.AccNo1 ,B.AccNo2 ,B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2, B.AccNo1, B.AccNo2, B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
) q
GROUP BY Id ,AccNo ,Name;
SQL Fiddle Demo
Do a LEFT JOIN to return the table1 values along with matching table2 values (where t2.accno2 = t1.accno):
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno = t2.accno2
Or, perhaps you want table2 values for matching accno1's as well?
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno in (t2.accno1, t2.accno2)
It this way to resolve:
SELECT
t1.id,
t1.accno,
t1.name,
(
SELECT DISTINCT
id
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
name
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno1
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno2
FROM
table2
WHERE
accno2 = t1.accno
) FROM
table1 t1
LEFT JOIN table2 t2 ON t1.accno = t2.accno1 OR t1.id = t2.id
When a subquery is not introduced with EXISTS, only one expression can be specified in the selection list.error. Not sure how to do the if exist statement.
SELECT DISTINCT
t1.id,t1.scn,t1.vsl_name,case when t1.id = t1.id THEN 'IMPORT' ELSE '0' END AS import_export,
dbo.fn_format_datetime(t1.act_arr_dt_tm) AS act_arr_dt_tm,
dbo.fn_format_datetime(t1.act_dept_dt_tm) AS act_dept_dt_tm,
( SELECT t1.scn, COUNT(t1.id) AS total_count_bl_status_c
FROM ccosbl t1
INNER JOIN vesvoy t2 ON t2.scn= t1.scn
WHERE t1.status_ind= 'C'
GROUP BY t1.scn)
FROM vesvoy t1
INNER JOIN ccosbl t2 ON t2.scn = t1.scn
WHERE t2.status_ind = 'C'
GROUP BY t1.scn,t1.vsl_name,t1.act_arr_dt_tm,t1.act_dept_dt_tm,t1.id
I need to combine both select statement as one. Is there any other ways to do that in sql?
If you insist on using a correlated subquery then you need to make sure that only one column is included into the select:
SELECT DISTINCT
t1.id,t1.scn,t1.vsl_name,case when t1.id = t1.id THEN 'IMPORT' ELSE '0' END AS import_export,
dbo.fn_format_datetime(t1.act_arr_dt_tm) AS act_arr_dt_tm,
dbo.fn_format_datetime(t1.act_dept_dt_tm) AS act_dept_dt_tm,
( SELECT COUNT(t4.id) AS total_count_bl_status_c
FROM ccosbl t4
INNER JOIN vesvoy t5 ON t4.scn= t5.scn
WHERE t1.status_ind= 'C' and t4.scn = t2.scn)
FROM vesvoy t1
INNER JOIN ccosbl t2 ON t2.scn = t1.scn
WHERE t2.status_ind = 'C'
GROUP BY t1.scn,t1.vsl_name,t1.act_arr_dt_tm,t1.act_dept_dt_tm,t1.id
However, the better approach will be to use a subquery with the join:
SELECT DISTINCT
t1.id,t1.scn,t1.vsl_name,case when t1.id = t1.id THEN 'IMPORT' ELSE '0' END AS import_export,
dbo.fn_format_datetime(t1.act_arr_dt_tm) AS act_arr_dt_tm,
dbo.fn_format_datetime(t1.act_dept_dt_tm) AS act_dept_dt_tm,
t3.total_count_bl_status_c
FROM vesvoy t1
INNER JOIN ccosbl t2 ON t2.scn = t1.scn
LEFT JOIN
( SELECT t4.scn, COUNT(t4.id) AS total_count_bl_status_c
FROM ccosbl t4
INNER JOIN vesvoy t5 ON t4.scn= t5.scn
WHERE t4.status_ind= 'C'
GROUP BY t4.scn) t3
ON t2.scn = t3.scn
WHERE t2.status_ind = 'C'
GROUP BY t1.scn,t1.vsl_name,t1.act_arr_dt_tm,t1.act_dept_dt_tm,t1.id
Try this:
SELECT t3.id t3.scn,total_count_bl_status_c,act_arr_dt_tm,act_dept_dt_tm,vsl_name,case when t3.id = t3.id THEN 'IMPORT' ELSE '0' END AS import_export,
dbo.fn_format_datetime(t3.act_arr_dt_tm) AS act_arr_dt_tm,
dbo.fn_format_datetime(t3.act_dept_dt_tm) AS act_dept_dt_tm from
(SELECT t2.scn, COUNT(t2.id) AS total_count_bl_status_c
FROM ccosbl t1
INNER JOIN
vesvoy t2
ON t2.scn= t1.scn
WHERE t1.status_ind= 'C'
GROUP BY t1.scn)as t3
inner join
(SELECT * from ccosbl) as t4 on
ON t4.scn = t3.scn
I have this SELECT query which works perfectly:
SELECT T1.Account, T1.Total, T2.Account, T2.Total
FROM tSummary2 as T1
INNER JOIN
(SELECT tSummary2.Account,
Count(FinalData.ID) AS Total
FROM tSummary2
INNER JOIN FinalData
ON tSummary2.Account = FinalData.Account
GROUP BY tSummary2.Account) as T2
ON T2.Account = T1.Account
I need to make T1.Total = T2.Total.
But every attempt to turn this into an update query is failing with "SYNTAX ERROR (missing operator).
Here is what I am trying:
UPDATE T1
SET T1.Total = T2.Total
FROM tSummary2 as T1
INNER JOIN
(SELECT tSummary2.Account,
Count(FinalData.ID) AS Total
FROM tSummary2
INNER JOIN FinalData
ON tSummary2.Account = FinalData.Account
GROUP BY tSummary2.Account) as T2
ON T2.Account = T1.Account
What am I missing?
You are missing a SELECT clause it seems.
UPDATE T1
SET T1.Total = (SELECT T2.Total
FROM tSummary2 as T1
INNER JOIN
(SELECT tSummary2.Account,
Count(FinalData.ID) AS Total
FROM tSummary2
INNER JOIN FinalData
ON tSummary2.Account = FinalData.Account
GROUP BY tSummary2.Account) as T2
ON T2.Account = T1.Account)
I just added the SELECT before T2.Total