SQL Subquery Join and Sum - sql

I have Table 1 & 2 with common Column name ID in both.
Table 1 has duplicate entries of rows which I was able to trim using:
SELECT DISTINCT
Table 2 has duplicate numeric entries(dollarspent) for ID's which I needed and was able to sum up:
Table 1 Table 2
------------ ------------------
ID spec ID Dol1 Dol2
54 A 54 1 0
54 A 54 2 1
55 B 55 0 2
56 C 55 3 0
-I need to join these two queries into one so I get a resultant JOIN of Table 1 & Table 2 ON column ID, (a) without duplicates in Table 1 & (b) Summed $ values from Table 2
For eg:
NewTable
----------------------------------------
ID Spec Dol1 Dol2
54 A 3 1
55 B 3 2
Notes : No. of rows in Table 1 and 2 are not the same.
Thanks

Use a derived table to get the distinct values from table1 and simply join to table 2 and use aggregation.
The issue you have is you have a M:M relationship between table1 and table2. You need it to be a 1:M for the summations to be accurate. Thus we derive t1 from table1 by using a select distinct to give us the unique records in the 1:M relationship (assuming specs are same for each ID)
SELECT T1.ID, T1.Spec, Sum(T2.Dol1) as Dol1, sum(T2.Dol2) as Dol2
FROM (SELECT distinct ID, spec
FROM table1) T1
INNER JOIN table2 T2
on t2.ID = T1.ID
GROUP BY T1.ID, T1.Spec
This does assume you only want records that exist in both. Otherwise we may need to use an (LEFT, RIGHT, or FULL) outer join; depending on desired results.

I can't really see your data, but you might want to try:
SELECT DISTINCT ID
FROM TblOne
UNION ALL
SELECT DISTINCT ID, SUM(Dol)
FROM TblTwo
GROUP BY ID

Pre-aggregate table 2 and then join:
select t1.id, t1.spec, t2.dol1, t2.dol2
from (select t2.id, sum(dol1) as dol1, sum(dol2) as dol2
from table2 t2
group by t2.id
) t2 join
(select distinct t1.id, t1.spec
from table1 t1
) t1
on t1.id = t2.id;
For your data examples, you don't need to pre-aggregate table 2. This gives the correct sums -- albeit in multiple rows -- if table1 has multiple specs for a given id.

Related

Select a value from a row that is matched to another value in the same table

Here is my issue:
I have the following table (truncated)
ID CustomerNumber ResellerID
1 12 NULL
2 56 1
As part of a Larger query - I'm doing this:
select customernumber,
case when ResellerID = id then customernumber end as 'Parent Account'
from table1
What I'm wanting to get is for rows with a resellerID, match that to the ID table and output the customernumber so the result would look like this:
CustomerNumber Parent Account
12 NULL
56 12
And I can't get the query to play nicely - I've tried running an outer left join but I just get NULL values - so I'm missing some syntax and logic somewhere.
You should use SELF JOIN
Join the same table by making alias with original table's ResellerID column and second table's ID column.
select t1.customernumber, t2.customernumber as 'ParentAccount'
from table1 t1 LEFT JOIN table1 t2 ON t1.ResellerID = t2.ID
do self(Left) join
select t1.CustomerNumber,t2.CustomerNumber as Parent_Account
from table1 t1
left join table1 t2
on t1.ResellerID=t2.id
CustomerNumber Parent_Account
12 NULL
56 12
DEMO IN DB FIDDLE

order by in UNION clauses existing a view in left join

I need to order the results by one attribute: Series (for each table). There is also a view in the queries...
The original query is:
select zz.Id
,t1.Series
,t1.SeriesType
from table 1 t1
inner join another_table (...)
left join view (...)
UNION
select zz.Id
,t2.Series
,t2.SeriesType
from table 2 t2
inner join another_table (...)
left join view (...)
UNION
select zz.Id
,t3.Series
,t3.SeriesType
from table 3 t3
inner join another_table (...)
left join view (...)
order zz.Id
this works, but only gives the order for zz.Id. How to achieve order for the Series column for each table?
I have tried with:
select *
from
(
SELECT TOP 100 PERCENT zz.Id
,t1.Series
,t1.SeriesType
from table 1 t1
inner join another_table (...)
left join view (...)
order by t1.Series) as table1
UNION
select *
from
(
SELECT TOP 100 PERCENT zz.Id
,t2.Series
,t2.SeriesType
from table 2 t2
inner join another_table (...)
left join view (...)
order by t2.Series) as table2
UNION
select *
from
(
SELECT TOP 100 PERCENT zz.Id
,t3.Series
,t3.SeriesType
from table 3 t3
inner join another_table (...)
left join view (...)
order by t3.Series) as table3
.
all tables are connected by one single table and this zz.id is unique for table1, table2, table3. (I see it is not possible to sort out at same time Id and series. so I will only sort out the series by each type of series). Thanks.
for example table 1 is:
zz.Id t1.series SERIES_Type
---------------------------------
1 4545 1
2 5655 1
3 2344 1
table 2
zz.Id t2.series SERIES_Type
---------------------------------
4 4546 2
table 3
zz.Id t3.series SERIES_Type
--------------------------------
5 545 3
6 343 3
7 2344 3
final result should be:
zz.Id series SERIES_Type
--------------------------------
3 2344 1
1 4545 1
2 5655 1
4 4546 2
6 343 3
5 545 3
7 2344 3
Have you tried two keys in the order by?
order Id, SeriestType
Based on your "expected result" all you need is:
order by SeriesType, Series
Am I correct or misunderstood...
Whenever it occurs to you to use "top 100 percent" - stop coding. This does nothing useful EVER. A resultset (which is the only way to look at rows) has no reliable or defined order unless the query that generated it included an order by clause. If you want to order rows according to each query within the union, then you need to add a column to each query that you can include in the final sort by clause.
As an example, this adds a column named srt (because "sort" is a reserved word - pick a name meaningful to you). Each participating query in the union is assigned a value that can be used to identify the "group". Again - make it meaningful to you. That column is included in the final sort by clause as the first column and will "group" rows.
use tempdb;
go
declare #tbl table (id int not null, series varchar(10) not null, seriestype varchar(10) not null);
insert #tbl(id, series, seriestype) values (1, '4521', 1), (1, '3011', 1), (2, '9999', 2), (3, '0000', 1), (3, '1111', 1);
select id, series, seriestype, 1 as srt from #tbl where id = 1
union all
select id, series, seriestype, 2 as srt from #tbl where id = 2
union all
select id, series, seriestype, 3 as srt from #tbl where id = 3
order by srt, id, series;
Now that you have updated your post, it seems you might be able to sort by seriestype. But that might be accidental due to your query logic and the data that exists in your tables. Only you can know if that is correct. TBH, I find the use of a union (vis-a-vis your sample output) suspicious.
And one final note. If you do not want to see the srt column in the final resultset, that can be arranged.

How to delete rows from two tables which are in common with single query in postgresql

I have two tables t1 and t2
table t1 as follows:
id name
1 x
2 y
3 z
table t2 as follows:
id name
1 a
121 b
131 c
Here I am selecting rows that are common in both the tables i.e.,
SELECT *
from t1,t2
where t1.id=t2.id;
Now I want to delete the rows when id=1 in both the tables at once. I have tried to delete the rows but I am able to delete only in one table but not both. Can anyone help me out in solving this.
You can do that with a data modifying common table expression
with common_ids as (
select id
from t1
intersect
select id
from t2
), t1_delete as (
delete from t1
where id in (select id from common_ids)
)
delete from t2
where id in (select id from common_ids);
Online example: http://rextester.com/NAQ26877

DISTINCT based on ID between Two table and SUM of the other exiting column in SQL

SELECT
SUM(amount), (DISTINCT table1.id)
FROM
table1
INNER JOIN
table2 ON table1.id = table2.id IS NULL;
Table1 id amount Table2 id product
1 40 5 10
2 364.25 2 20
3 704.5 8 30
4 404.5 3 40
5 580.5 2 20
The id is not unique or primary ------------------first i need to ignore all double entry ID from table2 then match id from table2 to table1 after that those ids will be match i need total of amount figure amount is a column name i will not calculate single the data will be more than 20000. please help me if you can
First compare match table2 id with table1 id if found any id match then those id amount need to be SUM i mean total. here match id is 2 and 3 according to table2 and then we will add this 2 and 3 id amount so result will be 364.25+704.5=1068.75 i am looking the result how can i do it using mysql.
I am trying to DISTINCT based on ID between two tables and SUM of the other existing column we have in table1. Can somebody help me how to do it?
Based on your latest comment try this
SELECT
SUM(amount)
FROM
table1
INNER JOIN
(Select Distinct ID From table2) T2 ON table1.id = T2.id
Lets leave a matter of performance beyond the topic:)
So according to this:
First compare match table2 id with table1 id if found any id match
then those id amount need to be SUM i mean total
it is possible to use correlated subquery:
select sum(t1.amount)
from table1 t1
where exists (select 1 from table2 t2 where t2.id = t1.id)
From what I understood, you need common IDs from both table and corresponding sum of amount.
SELECT
SUM(amount)
FROM
table1
WHERE
id IN (SELECT id
FROM table2);

Join table on Count

I have two tables in Access, one containing IDs (not unique) and some Name and one containing IDs (not unique) and Location. I would like to return a third table that contains only the IDs of the elements that appear more than 1 time in either Names or Location.
Table 1
ID Name
1 Max
1 Bob
2 Jack
Table 2
ID Location
1 A
2 B
Basically in this setup it should return only ID 1 because 1 appears twice in Table 1 :
ID
1
I have tried to do a JOIN on the tables and then apply a COUNT but nothing came out.
Thanks in advance!
Here is one method that I think will work in MS Access:
(select id
from table1
group by id
having count(*) > 1
) union -- note: NOT union all
(select id
from table2
group by id
having count(*) > 1
);
MS Access does not allow union/union all in the from clause. Nor does it support full outer join. Note that the union will remove duplicates.
Simple Group By and Having clause should help you
select ID
From Table1
Group by ID
having count(1)>1
union
select ID
From Table2
Group by ID
having count(1)>1
Based on your description, you do not need to join tables to find duplicate records, if your table is what you gave above, simply use:
With A
as
(
select ID,count(*) as Times From table group by ID
)
select * From A where A.Times>1
Not sure I understand what query you already tried, but this should work:
select table1.ID
from table1 inner join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1
Or if you have ID's in one table but not the other
select table1.ID
from table1 full outer join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1