How can I display maximum OrderId for a CustomerId with many columns?
I have a table with following columns:
CustomerId, OrderId, Status, OrderType, CustomerType
A customer with Same customer id could have many order ids(1,2,3..) I want to be able to display the max Order id with the rest of the customers in a sql view. how can I achieve this?
Sample Data:
CustomerId OrderId OrderType
145042 1 A
110204 1 C
145042 2 D
162438 1 B
110204 2 B
103603 1 C
115559 1 D
115559 2 A
110204 3 A
I'd use a common table expression and ROW_NUMBER:
;With Ordered as (
select *,
ROW_NUMBER() OVER (PARTITION BY CustomerID
ORDER BY OrderId desc) as rn
from [Unnamed table from the question]
)
select * from Ordered where rn = 1
select * from table_name
where orderid in
(select max(orderid) from table_name group by customerid)
One way to do this is with not exists:
select t.*
from table t
where not exists (select 1
from table t2
where t2.CustomerId = t.CustomerId and
t2.OrderId > t.OrderId
);
This is saying: "get me all rows from t where there is no higher order id for the customer."
Related
Suppose I have a table
order id
item
1
A
1
B
5
A
3
B
I need to write a select query to get following output:
order id
item
order
1
A
1
5
A
2
1
B
1
3
B
2
Is there a way to achieve this?
You can use the ROW_NUMBER() rank function and write query like this:
create table orders
(
order_id int,
item nvarchar(max)
)
insert into orders values(1,'A');
insert into orders values(1,'B');
insert into orders values(5,'A');
insert into orders values(3,'B');
SELECT order_id, item, ROW_NUMBER() OVER ( PARTITION BY item ORDER BY item ASC, order_id ASC) as [order]
FROM ORDERS
order by item asc, order_id asc
Check the ranking functions: https://www.sqlshack.com/overview-of-sql-rank-functions/
Let's say there is a table of customers, each customer in this table has an id which is PK (integer).
What is the most efficient way to write a query that returns the 3rd highest id?
And I in here presume it's 3rd, but my intention is for N highest.
I wrote two queries and I wonder which one is better?
select top 1 Customer_Id
from customers c
where c.Customer_Id not in(
select top 2 cc.Customer_Id
from customers cc
order by cc.Customer_Id desc
)
order by c.Customer_Id desc
------------------------------
select top 1 temp.Customer_Id
from (
select top 3 c.Customer_Id
from customers c
order by c.Customer_Id desc) as temp
order by temp.Customer_Id
If someone here has a better approach, I will be glad to hear.
Just use an OFFSET, like I mentioned:
DECLARE #N int = 3; --Demonstrates that the OFFSET can be parametrised
SELECT CustomerID
FROM dbo.Customer C
ORDER BY CustomerID DESC
OFFSET #N-1 ROWS FETCH NEXT 1 ROWS ONLY;
Something like this using the Row_Number function to list them in order, giving you the ability to select the nth number:
DECLARE #TargetRowNum INT = 2;
WITH CustomerList
AS (
SELECT c.Customer_Id
, CustomerRowNum = ROW_NUMBER()OVER(PARTITION BY c.Customer_Id ORDER BY c.Customer_Id DESC)
FROM customers c
)
SELECT *
FROM CustomerList
WHERE CustomerList.CustomerRowNum = #TargetRowNum;
According to #Larnu, I hope this could be a solution:
select temp2.Customer_Id
from(
select temp.Customer_Id, ROW_NUMBER() over(partition by grp order by temp.Customer_Id desc) as rrank
from (
select c.Customer_Id, 1 as grp
from customers c
) as temp
) as temp2
where temp2.rrank = 3
I have a following tables:
TABLE A:
ID ID NAME PRICE CODE
00001 B 1000 1
00002 A 2000 1
00003 C 3000 1
Here is the SQL I use:
Select Min (ID),
Min (ID NAME),
Sum(PRICE)
From A
GROUP BY CODE
Here is what I get:
ID ID NAME PRICE
00001 A 6000
As you can see, ID NAME don't match up with the min row value. I need them to match up.
I would like the query to return the following
ID ID NAME PRICE
00001 B 6000
What SQL can I use to get that result?
If you want one row, use limit or fetch first 1 row only:
select a.*
from a
order by a.price asc
fetch first 1 row only;
If, for some reason, you want the sum() of all prices, then you can use window functions:
select a.*, sum(a.price) over () as sum_prices
from a
order by a.price asc
fetch first 1 row only;
You can use row_number() function :
select min(id), max(case when seq = 1 then id_name end) as id_name, sum(price) as price, code
from (select t.*, row_number() over (partition by code order by id) seq
from table t
) t
group by code;
you can also use sub-query
select t1.*,t2.* from
(select ID,Name from t where ID= (select min(ID) from t)
) as t1
cross join (select sum(Price) as total from t) as t2
https://dbfiddle.uk/?rdbms=postgres_10&fiddle=a496232b552390a641c0e5c0fae791d1
id name total
1 B 6000
I have a table like this in this there are duplicate records are there So my requirement is identify the duplicate records and store into another table i.e., Customer_duplicate
and distinct records into one table
Existing query:
Create proc usp_store_duplicate_into_table
as
begin
insert into Customer_Duplicate
select *
from Customer C
group by cid
having count(cid) > 1
What you have is fine, except that you can't select items that are not in your group by; for example, you could do:
insert into Customer_Duplicate
select cid, count(*)
from Customer C
group by cid
having count(cid) > 1
Depending on what Customer_Duplicate looks like. If you really need to include all the rows then something like this might work for you:
insert into Customer_Duplicate
select *
from customer c
where c.cid in
(
select cid
from Customer
group by cid
having count(cid) > 1
)
You can Use Row_Number() ranking Function With Partition By in SQL Server to Identify Duplicate rows.
In Partition By You can Define numbers of columns That you have to Find duplicate records.
For Example I am Using Name and No, You can Replace it with Your columns name.
insert into Customer_Duplicate
SELECT * FROM (
select * , ROW_NUMBER() OVER(PARTITION BY NAME,NO ORDER BY NAME,NO) AS RNK
from Customer C
) AS d
WHERE rnk > 1
For finding the duplicates, you can use the below code.
insert into Customer_Duplicate
SELECT c.name, c.othercolumns
(select c.name,c.othercolumns, ROW_NUMBER() OVER(PARTITION BY cid ORDER BY 1) AS rnk
from Customer C
) AS c
WHERE c.rnk >1;
If you want to insert distinct records into another table, you can use the below code.
insert into Customer_Distinct
SELECT c.name, c.othercolumns
(select c.name,c.othercolumns, ROW_NUMBER() OVER(PARTITION BY cid ORDER BY 1) AS rnk
from Customer C
) AS c
WHERE c.rnk = 1;
consider the below:
ProductID Supplier
--------- --------
111 Microsoft
112 Microsoft
222 Apple Mac
222 Apple
223 Apple
In this example product 222 is repeated because the supplier is known as two names in the data supplied.
I have data like this for thousands of products. How can I delete the duplicate products or select individual results - something like a self join with SELECT TOP 1 or something like that?
Thanks!
I think you want to do the following:
select t.*
from (select t.*,
row_number() over (partition by product_id order by (select NULL)) as seqnum
from t
) t
where seqnum = 1
This selects an arbitrary row for each product.
To delete all rows but one, you can use the same idea:
with todelete (
(select t.*,
row_number() over (partition by product_id order by (select NULL)) as seqnum
from t
)
delete from to_delete where seqnum > 1
DELETE a
FROM tableName a
LEFT JOIN
(
SELECT Supplier, MIN(ProductID) min_ID
FROM tableName
GROUP BY Supplier
) b ON a.supplier = b.supplier AND
a.ProductID = b.min_ID
WHERE b.Supplier IS NULL
SQLFiddle Demo
or if you want to delete productID which has more than onbe product
WITH cte
AS
(
SELECT ProductID, Supplier,
ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Supplier) rn
FROM tableName
)
DELETE FROM cte WHERE rn > 1
SQLFiddle Demo
;WITH Products_CTE AS
(
SELECT ProductID, Supplier,
ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY <some value>) as rn
FROM PRODUCTS
)
SELECT *
FROM Products_CTE
WHERE rn = 1
The some value is going to be the key that determines which version of Supplier you keep. If you want the first instance of the supplier, you could use the DateAdded column, if it exists.