Remove duplicates based on common where condition in sql [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Select * from Table_name i am getting below result.
S.no Emp_id Date Description Amount Splitup amount
2667737 12345 8/12/2019 Icecream 50 30
2667738 12345 8/12/2019 Icecream 50 20
2667739 12346 8/12/2019 Chocolate 50 20
But i need the result
S.no Emp_id Date Description Amount Splitup amount
2667737 12345 8/12/2019 Icecream 50 30
2667738 12345 Icecream 20
2667739 12346 8/12/2019 Chocolate 50 20
i need only the first as amount .For same s.no and same emp_id was to have only one date and amount, remaining rows i want to make it empty.

You can consider using lag() windows analytic function :
select [S.no], [Emp_id],
case when lag([Date],1,null) over
(partition by [Date] order by [S.no]) = [Date] then
null
else
[Date]
end as [Date], [Description],
case when lag([Amount],1,null) over
(partition by [Amount] order by [S.no]) = [Amount] then
null
else
[Amount]
end as [Amount], [Splitup amount]
from tab;
Demo

You can use conditional logic with row_number():
select s.s_no, s.emp_id,
(case when row_number() over (partition by emp_id, description order by s_no) = 1
then date
end) as date,
description,
(case when row_number() over (partition by emp_id, description order by s_no) = 1
then amount
end) as amount,
splitup
from t
order by emp_id, s_no;
Note the outer order by and how it matches the conditions in the window clause. SQL result sets are unordered unless there is an explicit order by. If you want the "first" row to have the values, then you need to be sure that the result set is in the right order.

Related

How to combine or merge columns with NULL in SQL Server? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
I'm trying to write a SQL query to take the below data and transform it into the expected result table.
INV
ITEM
Amount
INV123
null
12.00
INV123
null
96.00
INV123
abc
null
INV123
xyz
null
Expected result:
INV
ITEM
Amount
INV123
abc
12.00
INV123
xyz
96.00
Assuming mapping the "first" non-null item to the "first" non-null amount is actually arbitrary, here's one way:
WITH items AS
(
SELECT inv, item, r = ROW_NUMBER() OVER (PARTITION BY inv ORDER BY ##SPID)
FROM dbo.MyTable WHERE item IS NOT NULL
), amounts AS
(
SELECT inv, amount, r = ROW_NUMBER() OVER (PARTITION BY inv ORDER BY ##SPID)
FROM dbo.MyTable WHERE amount IS NOT NULL
)
SELECT inv = COALESCE(items.inv, amounts.inv),
items.item, amounts.amount
FROM items FULL OUTER JOIN amounts
ON items.inv = amounts.inv
AND items.r = amounts.r
ORDER BY COALESCE(items.r, amounts.r);
Working example in this fiddle.
The FULL OUTER JOIN is used because you probably won't always have the same number of non-null items and non-null amounts for a given inv. However you might also want to handle the case where both columns have a non-null value - do those columns stick together on the same output row, or no?
If the ordering needs to be more deterministic, you need to explain what other data exists in the table to allow you to rank those columns. Or if you want alphabetical for item and numerical for amount, just change ORDER BY ##SPID to ORDER BY item/ORDER BY amount respectively.

Create CASE WHEN labels based on DISTINCT values in a particular column [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have data of the following form:
ID
Category
Amount
1
A
100
1
B
200
1
B
150
1
C
500
2
B
20
3
A
100
1
B
100
I wish to GROUP BY the column ID, find out the DISTINCT types of Category present for each ID group and create a new column where I can create the following classification labels for each grouped ID based on the unique or distinct categories present and also calculate the corresponding sum of amount for each grouped ID. So the output should be the follows:
ID
Classification
Sum of Amount
1
ALL
950
1
B only
20
1
A and B only
200
I tried the following SQL code but it doesn't work, most likely because DISTINCT() command within a CASE WHEN statement cannot consider multiple values.
My query:
SELECT
ID,
(CASE WHEN DISTINCT(CATEGORY) IN ("A") then "A Only" WHEN WHEN DISTINCT(CATEGORY) IN ("B") THEN "B only"..........)
SUM(AMOUNT)
FROM Table
GROUP BY 1,2
I have tried multiple ways of using the DISTINCT statement with CASE WHEN but none of them works.
Hmmm . . . How about this?
select id,
(case when min(category) = max(category)
then min(category) || ' only'
when count(distinct category) = 3
then 'All'
when min(category) is NULL
then 'None'
else min(category) || ' and ' || max(category)
end)
from t
group by id;

How to find the 3rd largest population of a country by state [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a table where there are three columns zipcode, state, total_population.
ZIPCODE STATE POPULATION
11937 36 15511
11941 36 1822
11940 36 4933
12435 36 280
12063 36 441
64733 29 1251
64734 29 1952
64735 29 13653
I am looking for this
zipcode state third_highest_population
11941 36 1822
4733 29 1251
I cannot think of a way to find the third largest population each state..any help is much appreciated
You can use window functions to help rank zip code populations by state, then keep the third ranked for each state.
SELECT *
FROM (
SELECT zipcode,
state,
total_population,
DENSE_RANK() OVER (PARTITION BY state ORDER BY total_population DESC) as ziprank
FROM yourtable
) r
WHERE ziprank = 3
RANK(), DENSE_RANK() and ROW_NUMBER() may all work here depending on your data. DENSE_RANK() insures you will get at least 1 (but maybe more) ranked at 3. The reason you may get more is if two zip codes share the same population in the state. That is highly unlikely though, so DENSE_RANK() is a good fit.
Something like:
select * from (
select your_table.*, rank() over(partition by state order by totpop) rnk from your_table
) t
where
rnk = 3
Sample Data
DECLARE #Data AS TABLE (zipcode INT,
[state] VARCHAR(10),
[total_population] INT
)
INSERT INTO #Data
SELECT 500010,'Ap',24524540 UNION ALL
SELECT 500020,'KA',47857441 UNION ALL
SELECT 500030,'TN',89456655 UNION ALL
SELECT 500040,'KL',45775475 UNION ALL
SELECT 500050,'UP',47411189
DECLARE #N INT = 3 -- Specify highest total as you required
Using Co related sub query
SELECT * FROM #Data
Go
SELECT zipcode,
[state],
[total_population]
FROM #Data e1
WHERE #N-1 = ( SELECT COUNT(DISTINCT [total_population])
FROM #Data e2
WHERE e2.[total_population] > e1.[total_population] )

Select rows that if I sum their value = 0 from table [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Let's say I have a table like this:
ID. Location. Value.
1. AGF. 10.00
2. VHJ. -20.00
3. AGF. -20.00
4. AGF. 5.00
5. KLZ. 50.00
6. AGF. 10.00
I want to select the rows that have same Location AND whose Values sum to zero.
In this case the result should be:
1
3
6
because those rows are all in Location AGF and they sum to 0 (10 + -20 + 10).
Try:
Select ID from YourTable where Location IN(
Select location from YouTable
Group By Location
Having sum(Value) = 0
)
You need to find all locations with zero sum using grouping and group filters (group by and having clauses respectively). This can be done in a subquery. Then select all IDs with the just selected locations.
select ID
from YOUR_TABLE
where Location in (
select Location
from YOUR_TABLE
group by Location
having sum(Value) = 0
)
You could use GROUP BY and HAVING, like this:
Select ID from tablelocation where Location IN(
Select location from tablelocation
Group By Location
Having sum(Value) = 0
)

Group By from two tables [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a requirement to show a report in the following format from the two different tables as shown below, the below report should count the order numbers by branch.
===================================================================
Branch OrdersCountInTable1 OrdersCountInTable2
===================================================================
100 5 2
200 10 10
300 12 11
how can i achieve this using a sqlquery?
Following are the columns in the tables:
Table1:
________
- Branch
- OrderNo
Table2
__________
- Branch
- OrderNo
Table1 Data:
===============================
Branch OrderNo
===============================
100 1000
100 1001
200 2001
100 1003
Table2 Data:
===============================
Branch OrderNo
===============================
100 1000
200 2001
100 1003
We just want to reconcile orders from both the tables!!
Thanks for any valuable feedbacks.
One more or less generic way to do it
SELECT COALESCE(t1.branch, t2.branch) branch,
COALESCE(t1.ordercount, 0) OrdersCountInTable1,
COALESCE(t2.ordercount, 0) OrdersCountInTable2
FROM
(
SELECT branch, COUNT(orderno) ordercount
FROM Table1
GROUP BY branch
) t1 FULL JOIN
(
SELECT branch, COUNT(orderno) ordercount
FROM Table2
GROUP BY branch
) t2
ON t1.branch = t2.branch
Assumption is that tables may not have entries for all branches. That's why FULL JOIN is used.
Do like this using SUM aggregate function and UNION ALL operator
SELECT Branch,
SUM( CASE tag WHEN 'table1' THEN 1 ELSE 0 END) as OrdersCountInTable1,
SUM( CASE tag WHEN 'table2' THEN 1 ELSE 0 END) as OrdersCountInTable2
FROM
(
SELECT Branch,'table1' as tag
FROM Table1
UNION ALL
SELECT Branch,'table2' as tag
FROM Table2
) z
GROUP BY Branch
ORDER BY Branch
Try it with a union nested query:
select
Branch, count(Orders1) OrdersCountInTable1, count(Orders2) OrdersCountInTable2
from (
select Branch,OrderNo Orders1,NULL Orders2 from Table1
union
select Branch,NULL Orders1,OrderNo Orders2 from Table2
) t
group by Branch