sql combine only some duplicates - sql

I want to combine one set of duplicates from my table, but not all.
example:
acct date bal
--------------------
123 1/1/2013 40.00
123 1/1/2013 2.00
456 1/2/2013 50.00
456 1/1/2013 5.00
789 1/1/2013 10.00
789 1/1/2013 17.00
I would like to combine acct 123 to only one row, summing the balance of those rows, but leave the rest.
desired output:
acct date bal
--------------------
123 1/1/2013 42.00
456 1/2/2013 50.00
456 1/1/2013 5.00
789 1/1/2013 10.00
789 1/1/2013 17.00
Working in SQL Server 2005.

Use CASE in GROUP BY clause
SELECT acct, date, SUM(bal) AS bal
FROM dbo.tets73
GROUP BY acct, date, CASE WHEN acct != 123 THEN bal END
Demo on SQLFiddle

SELECT acct, date, SUM(bal)
FROM T
WHERE acct = 123
UNION
SELECT acct, date, bal
FROM T
WHERE acct <> 123

select acct, date, sum(bal) from table where acct = 123
union
select acct, date bal from table where acct <> 123

Related

find out the records - first two date records of each member of every year- db2udb

Need Help -
Scenario - I have a table testdata with columns
memberid (varchar) ,codetype(varchar),effectivedate(datetime)
this table having 20k records - from year 2015 to 2021
I need to find out the records - first two date records of each member of every year [ only memberid is unique)
eg.
member id
codetype
effectivedate
123
ABC
1/2/2015
123
ABC
1/2/2015
123
ABC
8/15/2015
123
EFG
9/15/2015
123
EFG
2/15/2018
345
EFG
3/14/2018
345
EFG
3/17/2018
345
ABC
9/19/2020
456
EFG
12/20/2021
result should be like below
member id
codetype
effectivedate
123
ABC
1/2/2015
123
ABC
1/2/2015
123
ABC
2/15/2018
345
EFG
3/14/2018
345
EFG
3/17/2018
345
ABC
9/19/2020
456
EFG
12/20/2021
tried lot of ways but no luck so far
Try this
with u as
(select memberid, codetype, effectivedate,
row_number() over(partition by memberid, year(effectivedate) order by
memberid) as rownum
from testdata)
(select memberid, codetype, effectivedate from u
where rownum <= 2)
Basically you get the row numbers of every record partitioned by memberid and the year of the record, then keep only the records where rownum is 1 or 2.

Continuous Date / Not continuous Date sql server

I'm encountering a problem with continous date / not cointinuous date on sql server 2012.
I have a table that looks like this :
Article
Creation date
1234
04/01/2021
1234
05/01/2021
1234
06/01/2021
1234
07/01/2021
1234
10/01/2021
1234
12/01/2021
12345
02/01/2021
12345
03/01/2021
12345
17/01/2021
123456
01/01/2021
123456
03/01/2021
123456
05/01/2021
The problem is :
I want to get the count of every article by continuous date with the min date of the range, it's a bit difficult to explain what I want but there is an example of the result :
Article
Creation date
Count
1234
04/01/2021
4
1234
10/01/2021
1
1234
12/01/2021
1
12345
02/01/2021
2
12345
17/01/2021
1
123456
01/01/2021
1
123456
03/01/2021
1
123456
05/01/2021
1
For example :
count of 1st row = 4 because there is 4 continous day on the range 04/01/2021 to 07/01/2021
count of 2nd row = 1 because there is only 1 day, 0 continuous day with 10/01/2021 for this article
count of 3rd row = 1 because there is only 1 day, 0 continuous day with 12/01/2021 for this article
I'm starting with that :
;WITH CTE AS (
SELECT Article, [Creation date], StartDate= Dateadd(day,-ROW_NUMBER() OVER (ORDER BY [Creation date]),[Creation date])
FROM MyTable
)
SELECT Article, min([Creation date]) as [Creation date], count(Article) as count
FROM CTE
GROUP BY StartDate, Article, [Creation date]
order by Article, [Creation date]
Output :
Article
Creation date
Count
1234
04/01/2021
1
1234
05/01/2021
1
1234
06/01/2021
1
1234
07/01/2021
1
1234
10/01/2021
1
1234
12/01/2021
1
12345
02/01/2021
1
12345
03/01/2021
1
12345
17/01/2021
1
123456
01/01/2021
1
123456
03/01/2021
1
123456
05/01/2021
1
but the result is wrong, I don't really know how to approach this problem. If someone can enlighten me, appreciate.
Thank you
This is an example of a gaps-and-islands problem. The simplest solution in this case is to subtract an increasing sequence of values and aggregate. This works because the difference is constant for incremental dates:
select article, min(creation_date), max(creation_date), count(*)
from (select t.*,
row_number() over (partition by article order by creation_date) as seqnum
from mytable t
) t
group by article, dateadd(day, -seqnum, creation_date)
order by article, min(creation_date);

Combine multiple records into one based on a condition

I want to combine each product_code's (comma-separated) in a single entry/record if all other values in multiple records are the same except the product_code
The dataset looks like below-
category_id subcat_id product_code customer_id quantity value
123 456 AB 111 2 1
123 456 CD 111 2 1
123 789 AB 111 2 2
123 789 CD 111 2 2
The result should look like-
category_id subcat_id product_code customer_id quantity value
123 456 AB,CD 111 2 1
123 789 AB,CD 111 2 2
Use string_agg();
select category_id, subcat_id, customer_id, quantity, value,
string_agg(product_code, ',')
from t
group by category_id, subcat_id, customer_id, quantity, value;
That said, I recommend arrays instead of strings for storing such values.

Joining multiple tables with filter

I got multiple tables and i'm only using 3 for testing. I don't know if this is the right approach.
AccntTbl
id accnt amount date
---------------------------------
1 xxx 10.00 1/1/2016
2 yyy 20.00 1/1/2016
3 zzz 30.00 1/1/2016
SupplyTbl
id accnt supply date
-------------------------------
1 xxx 5.00 1/10/2016
1 xxx 5.00 2/14/2016
IssuedTbl
id accnt issued date
---------------------------------
1 xxx 3.00 1/9/2016
1 xxx 2.00 2/1/2016
and the result will be like this if filter to JANUARY
id accnt amount issued balance
--------------------------------------------
1 xxx 15.00 3.00 12.00
2 yyy 20.00 0.00 20.00
3 zzz 30.00 0.00 30.00
and if FEBRUARY
id accnt amount issued balance
---------------------------------------------
1 xxx 20.00 5.00 15.00
2 yyy 20.00 0.00 0.00
3 zzz 30.00 0.00 0.00
and here's my query that i've come up with
SELECT accnttbl.id,
accnttbl.accnt,
Sum(accnttbl.amount)
+ Sum(SupplyTbl.supply) AS amount,
issuedtbl.issued
FROM accnttbl
LEFT JOIN (SELECT id,
Sum(supply) AS supply,
date
FROM supplytbl
GROUP BY id,
date) AS SupplyTbl
ON accnttbl.id = SupplyTbl.id
AND Month(SupplyTbl.date) BETWEEN 1 AND 2
LEFT JOIN (SELECT id. Sum(issued) AS issued,
date
FROM issuedtbl
GROUP BY id,
date)
ON accnttbl.id = issuedtbl.id
AND Month(issuedtbl.date) BETWEEN 1 AND 2
WHERE Year(accnttbl.date) = 2016
GROUP BY accnttbl.id,
accnttbl.accnt
and i kinda mess up..glad for any help :)
the result be like this..in JANUARY
id accnt amount issued
1 xxx 30.00 10.00
2 yyy 20.00 0.00
and in FEBRUARY
1 xxx 60.00 20.00
2 yyy 20.00 0.00
with the value that i been given..it just..it doubled the amount on its own..the result are wrong..why is that ?
Try as below :
SELECT AccntTbl.id, AccntTbl.accnt
, SUM(AccntTbl.amount) + SUM(SupplyTbl.supply) as amount
, SUM(IssuedTbl.issued) as issued
, (SUM(amount) - SUM(issued)) as balance
FROM AccntTbl LEFT JOIN
(SELECT id, COALESCE(SUM(supply), 0) AS supply, date FROM SupplyTbl
GROUP By id, date) AS SupplyTbl
ON AccntTbl.id = SupplyTbl.id AND (MONTH(SupplyTbl.date) BETWEEN
1 AND 2)
LEFT JOIN
(SELECT id, COALESCE(SUM(issued),0) as issued, date from IssuedTbl
GROUP By id, date )
ON AccntTbl.id = IssuedTbl.id AND (MONTH(IssuedTbl.date) BETWEEN
1 AND 2)
WHERE (YEAR(AccntTbl.date) = 2016)
GROUP By AccntTbl.id, AccntTbl.accnt
;
In sql anything added with NULL is NULL . So in your subquery if you are not using COALESCE, you are adding your value with NULL, hence you are not getting your desired result.

joining multiple tables with filter by date

i got 3 tables..how do i join these tables with filter by date on each table
MainTbl
id accnt amount date
---------------------------------
1 xxx 10.00 1/1/2016
2 yyy 20.00 1/1/2016
3 zzz 30.00 1/1/2016
SupplyTbl - this table would add the value of supply to the amount in the MainTbl
id accnt supply date
-------------------------------
1 xxx 5.00 1/10/2016
1 xxx 5.00 2/14/2016
2 yyy 10.00 1/20/2016
IssuedTbl
id accnt issued dateIssue
------------------------------------------
1 xxx 5.00 1/10/2016
1 xxx 5.00 2/14/2016
2 yyy 10.00 2/15/2016
now i want to join these tables..with date range..if i filter the date to JANUARY it would result something like this
id accnt amount issued
-----------------------------
1 xxx 15.00 5.00
2 yyy 30.00 0.00
3 zzz 30.00 0.00
and when i filter to FEBRUARY..it will combine both from JANUARY to FEBRUARY
id accnt amount issued
-----------------------------
1 xxx 20.00 10.00
2 yyy 40.00 10.00
3 zzz 30.00 0.00
i'm struggling with this since the other night..glad with any help..tnx in advance :)
Try something like this
SELECT M.id,
M.accnt,
amount = M.amount + Isnull(s.supply, 0),
issued = Isnull(I.issued, 0)
FROM maintbl M
LEFT OUTER JOIN (SELECT id,
Sum(supply) AS supply
FROM supplytbl
WHERE Month(dates) = 1 -- Month filter for Jan - feb Month(dates) in (1,2)
GROUP BY id) S
ON s.id = M.id
LEFT OUTER JOIN (SELECT id,
Sum(issued) AS issued
FROM issuedtbl
WHERE Month(dateissue) = 1 -- Month filter
GROUP BY id) I
ON I.id = M.id
SQL FIDDLE DEMO