How to correctly sum the values for a unique ID with the condition - sql

How to sum the values in Number field in table2 when the ID field is unique and field Type = 3 (range 1-5)?
SELECT TOP (100)
TB1.CarID
FROM table1 as TB1
LEFT JOIN table2 as TB2 on TB1.CarID = TB2.CarID
WHERE
GROUP BY
Table1
Table2
I have tried several solutions:
,SUM (CASE WHEN TB2.Type = 3 THEN TB2.Number END)
Return result is incorrect x2, possibly due to a large number of table joins. If you have any comment why the values are displayed x2, please give me a hint. I would like to add an additional condition, i.e. sum only when the value in the id column is unique. I believe this can solve the problem.
,SUM (CASE WHEN TB2.Type = 3 AND TB2.ID is UNIQUE THEN TB2.Number END) [incorrect]
I will be grateful for your help!

Part of the problem is likely that you join on carid, but that is not unique in Either table.
At present you have 5 copies of 'aaaad' in Table1 and 5 copies in Table2. When you join them, you get 25 rows back (each row in T1 matching against 5 rows in T2).
So, I'd start with aggregating the second table before joining on it...
SELECT
*
FROM
table1 AS t1
LEFT JOIN
(
SELECT
carid,
SUM(number) AS number
FROM
table2
WHERE
type = 3
GROUP BY
carid
)
AS t2
ON t1.CarID = t2.CarID
That way you avoid multiplying the number of rows.

Related

Comparing base table value with second table's sum of value with group by

I have two tables:
One is base table and second is transaction table. I want to compare base table value with second table's sum of value with group by.
Table1(T1Id,Amount1,...)
Tabe2(T2Id,T1ID,Amount2)
I want those rows from table 1 WHere SUM of Table2's SUM( Amount2) is greater or equal table1's Amount1.
*T1ID is in relation with both tables
* The SQL query have many joins with other table for data retriving.
One approach uses a join:
SELECT t1.T1Id, t1.Amount1
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.T1Id = t2.T1ID
GROUP BY
t1.T1Id, t1.Amount1
HAVING
SUM(t2.Amount2) >= t1.Amount1;
We can also try doing this via a correlated subquery:
SELECT t1.T1Id, t1.Amount1
FROM Table1 t1
WHERE t1.Amount1 <= (SELECT SUM(t2.Amount2) FROM Table2 t2
WHERE t1.T1Id = t2.T1ID);
I would use something similar to the query below:
SELECT
a.T1Id, a.Amount1, SUM(b.Amount2)
FROM Table1 a
INNER JOIN Table2 b on b.T1Id = a.T1Id
GROUP BY a.T1Id, a.Amount1
HAVING SUM(b.Amount2) >= a.Amount1;
Basically what the query above does is give you the ID, Amount from table 1 and the summed amount from table 2. The HAVING clause at the end of query filters out those records where the summed amount from the second table is smaller than the amount from the first one.
If you want to add further table joins to the query, you can do so by adding as many joins as you wish. I would recommend having a referenced ID for each table you are joining in the Table1 table.

SQL to sum a total of a column where 2 columns match in a different table

SO I have 2 tables and would like to SUM the total of a column in one table where 2 other columns match in another table.
In table1 I have acc_ref and bill_no.
acc_ref is different but bill_no could be 1-10 (so 2 or more acc_ref could have the same bill_no)
In table2 I have acc_ref, bill_no and tran_amnt.
Εach acc_ref has multiple rows and I want to SUM the tran_amnt but only if acc_ref and bill_no both match in table1.
I tried this but I get an error
'The columns in the SELECT clause must be contained in the GROUP BY
clause'
select a.acc_ref, a.bill_no
from table1 a
where exists (select acc_ref, bill_no, SUM (tran_amount)
from table2 b
where a.acc_ref = b.acc_ref
and a.bill_no = b.bill_no
group by acc_ref)
Apologies if this is very basic and obvious but I'm struggling!!
In you description it seems like table1 does not contain any useful information. Because both columns you give also exist in table2. So if nothing else from table1 is needed, you could just remove table1 from the query). Still with your problem you should do a simple join
SELECT a.acc_ref, a.bill_no, SUM(b.tran_amount)
FROM table1 a
JOIN table2 b ON b.acc_ref = a.acc_ref AND b.bill_no=a.bill_no
GROUP BY a.acc_ref, a.bill_no
I believe you should use case:
Sample:
SELECT
TABEL1.Id,
CASE WHEN EXISTS (SELECT Id FROM TABLE2 WHERE TABLE2.ID = TABLE1.ID)
THEN 'TRUE'
ELSE 'FALSE'
END AS NewFiled
FROM TABLE1

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);

matching value by non-unique id and minimum date difference

I'm using sqlite through the RSQLite package in R.
I have two tables:
Table 1 has important columns 'PERMCO' and 'Reporting_Period'.
('Reporting_Period' is an integer date)
Table 2 has important columns 'PERMCO' and 'date'.
('date' is an integer date)
I want to do a left join with table 1 as the left table.
Thing is that 'PERMCO' is not unique (row-wise, many duplicates) in the second table.
For a given row of table 1, I want the match from the second table to be the row from table 2 with matching PERMCO that is closest in absolute date to 'Reporting_Period' in the first table.
Not really sure how to do this...
Thank you
The Idea is a correlated subquery to get the closest day in table2 from Reporting_Period in table1
SELECT t1.*, t2.*
FROM table1 t1
LEFT JOIN table2 t2
ON t1.permco = t2.permco
WHERE ABS(t2."date" - t1.Reporting_Period) = (SELECT MIN(ABS("date" - t1.Reporting_Period) )
FROM table2
WHERE permco = t1.permco
)
OR t2.permco IS NULL --because you want a left join
;
I'm not familier with Sqlite, so you may need to change the query to subtract the two date.

Oracle: Check if rows exist in other table

I've got a query joining several tables and returning quite a few columns.
An indexed column of another table references the PK of one of these joined tables. Now I would like to add another column to the query that states if at least one row with that ID exists in the new table.
So if I have one of the old tables
ID
1
2
3
and the new table
REF_ID
1
1
1
3
then I'd like to get
ID REF_EXISTS
1 1
2 0
3 1
I can think of several ways to do that, but what is the most elegant/efficient one?
EDIT
I tested the performance of the queries provided with 50.000 records in the old table, every other record matched by two rows in the new table, so half of the records have REF_EXISTS=1.
I'm adding average results as comments to the answers in case anyone is interested. Thanks everyone!
Another option:
select O.ID
, case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
on O.id = N.ref_id
I would:
select distinct ID,
case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
then 1 else 0 end
from ID_TABLE
Provided you have indexes on the PK and FK you will get away with a table scan and index lookups.
Regards
K
Use:
SELECT DISTINCT t1.id,
CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
Added DISTINCT to ensure only unique rows are displayed.
A join could return multiple rows for one id, as it does for id=1 in the example data. You can limit it to one row per id with a group by:
SELECT
t1.id
, COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id
The group by ensures there's only one row per id. And count(distinct t2.ref_id) will be 1 if a row is found and 0 otherwise.
EDIT: You can rewrite it without a group by, but I doubt that will make things easer:
SELECT
t1.id
, CASE WHEN EXISTS (
SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
THEN 1 ELSE 0 END as REF_EXISTS
, ....
FROM TABLE_1 t1