Hi below is my sql query as
SELECT
o.OrderNumber,
oi.Sku,
Sum(Isnull(oi.Price * oi.Quantity,0)) as Price,
DENSE_RANK() over(partition by o.orderNumber order by oi.sku) as CouponRowId
from ac_OrderItems oi
inner join ac_Orders o on oi.OrderId = o.OrderId
Inner Join ac_OrderShipments os on oi.OrderShipmentId =os.OrderShipmentId
WHERE (oi.OrderItemTypeId IN (5))
group by o.OrderNumber, oi.Sku
and below is the record I am getting
OrderNumber Sku Price CouponRowId
90061 BLACKBERRY -5.6900 1
90061 LEMON -5.6900 2
90061 PEACH -5.6900 3
90061 SHIP100 -10.920 4
but I want my record as
OrderNumber Sku Price
90061 BLACKBERRY -5.6900
LEMON -5.6900
PEACH -5.6900
SHIP100 -10.920
I want that if order number is same in that case all detail record should come in 1st row and then after other record should only show Sku and price only and also we need to remove the DENSE_RANK() column
By seeing the query seems like Partition Clause can help you to
resolve the issue. Please look at the below query. I am not so sure
about the data model, but looks like you need to partition by using
the OrderNumber column. Please replace the query in the first CTE with your actual table which will be like the second query. I cant test it since I don't have the environment. Please test the query
;WITH CTE_Table
AS
(
SELECT 90061 'OrderNumber' , 'BLACKBERRY' Sku, -5.6900 'Price', 1 'CouponRowId' UNION
SELECT 90061, 'LEMON', -5.6900, 2 UNION
SELECT 90061, 'PEACH', -5.6900, 3 UNION
SELECT 90061, 'SHIP100', -10.920, 4 UNION
SELECT 90062 'OrderNumber' , 'BLACKBERRY' Sku, -5.6900 'Price', 1 'CouponRowId' UNION
SELECT 90062, 'LEMON', -5.6900, 2 UNION
SELECT 90062, 'PEACH', -5.6900, 3 UNION
SELECT 90062, 'SHIP100', -10.920, 4
),
CTE_New
AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY OrderNumber ORDER BY OrderNumber) Patrn FROM CTE_Table
)
SELECT CASE WHEN Patrn =1 THEN CONVERT(VARCHAR(10),OrderNumber) ELSE '' END OrderNumber, Sku, Price, CouponRowId FROM CTE_New
;WITH CTE_Table
AS
(
SELECT
o.OrderNumber,
oi.Sku,
Sum(Isnull(oi.Price * oi.Quantity,0)) as Price,
DENSE_RANK() over(partition by o.orderNumber order by oi.sku) as CouponRowId
from ac_OrderItems oi
inner join ac_Orders o on oi.OrderId = o.OrderId
Inner Join ac_OrderShipments os on oi.OrderShipmentId =os.OrderShipmentId
WHERE (oi.OrderItemTypeId IN (5))
group by o.OrderNumber, oi.Sku
),
CTE_New
AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY OrderNumber ORDER BY OrderNumber) Patrn FROM CTE_Table
)
SELECT CASE WHEN Patrn =1 THEN CONVERT(VARCHAR(10),OrderNumber) ELSE '' END OrderNumber, Sku, Price, CouponRowId FROM CTE_New
Seeing your comment this is an attempt to solve it on the query itself (I assumed CouponRowID might do the job, if OrderNumber is unique):
WITH
tmp AS (
SELECT o.OrderNumber, oi.Sku, SUM(ISNULL(oi.Price * oi.Quantity, 0)) AS Price, DENSE_RANK() OVER (PARTITION BY o.orderNumber ORDER BY oi.sku) AS CouponRowId
FROM ac_OrderItems oi
INNER JOIN ac_Orders o ON oi.OrderId=o.OrderId
INNER JOIN ac_OrderShipments os ON oi.OrderShipmentId=os.OrderShipmentId
WHERE(oi.OrderItemTypeId IN (5))
GROUP BY o.OrderNumber, oi.Sku
)
SELECT CASE WHEN tmp.CouponRowId=1 THEN tmp.OrderNumber END AS OrderNumber, tmp.Sku, tmp.Price
FROM tmp
ORDER BY tmp.OrderNumber, tmp.SKu;
Sorry....! I cant understand your explanations..
I just worked only for get your expected OP...
create table #ac_OrderItems(id varchar(20) --varchar, i used instead of int.Beside, varchar is easy to change to int.
, Sku varchar(20), Price decimal, CouponRowId int)
insert into #ac_OrderItems values(
90061 , 'BLACKBERRY' , -5.6900 , 1)
,(90061, 'LEMON', -5.6900, 2 )
,(90061, 'PEACH', -5.6900, 3 )
,(90061, 'SHIP100', -10.920, 4 )
,(90062 , 'BLACKBERRY' ,-5.6900 , 1 )
,(90062, 'LEMON', -5.6900, 2 )
,(90062, 'PEACH', -5.6900, 3 )
,(90062, 'SHIP100', -10.920, 4)
select * from #ac_OrderItems
;with
orders(id, sku, price, couponId, rn)
as
(
select *, ROW_NUMBER() over(partition by id order by id) from #ac_OrderItems
)select iif(rn = 1,id,''),sku,price,couponId from orders
-- if i used int, empty is denoted by 0. But you want '' this. So i used varchar id
let you know me, what you got.
Related
There is a table like this, how can I get customer_id, amount_spent, top_item out of it?
amount_spent the amount spent on all items by this customer
top_item, which displays the name of the item for which the customer has spent the most money
I have tried the following query, however I cannot output the top_1 item with it
select customer_id, sum(item_number * item_price) as amount_spent_1m
from temp
group by customer_id
Check the demo here.
You can achieve it as below :
select customer_id, sum(item_number * item_price) as amount_spent_1m,
item_name as top_item_1m
from temp
group by customer_id, item_name
order by amount_spent_1m desc;
It gives me the following result :
I am sure there is a way to do this with one less step but my brain is not seeing it right now -
SELECT customer_id, amount_spent, item_name AS top_item
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY item_total DESC) rn,
SUM(item_total) OVER (PARTITION BY customer_id) amount_spent
FROM (
SELECT customer_id, item_id, item_name, SUM(item_price * item_number) item_total
FROM table1
GROUP BY customer_id, item_id, item_name
) t1
) t2
WHERE rn = 1
db<>fiddle
In my query I am using rownumber to have a partition on customer id but i want it grouped by emailaddress. Is there a way to do it?
I have two tables, containing the following columns:
Customers:
EmailAddress,CustomerId
Orders:
OrderDate,CustomerId,OrderId,PaymentAmount
select
t.EmailAddress,
COUNT(t.OrderID) AS NumOrders,
SUM(t.PaymentAmount) as Total_Ordered,
max (case when t.rn = 2 then t.OrderDate end) as previous_date,
max (case when t.rn = 1 then t.Orderdate end) as last_date
from
(
select
c.EmailAddress,
o.OrderDate,
o.OrderID ,
o.PaymentAmount,
row_number() over (partition by c.CustomerID order by OrderDate desc) as rn
from
Customers c
Join Orders o
ON c.CustomerID=o.CustomerID
)t
group by
t.EmailAddress;
Note: My data is unique by EmailAddress and not by CustomerID
I have this query which does some calculations based on some derived tables that are linked with an INNER JOIN.
At the moment I have a WHERE clause which pulls out one id at a time. But how can I make it list all the ids?
I have tried GROUP BY in various places but can't figure it out.
My query so far is as follows:
SELECT
equipment_id,
service_duration,
available_duration,
(available_duration / service_duration)*100 AS availability
FROM (
SELECT
SUM(service_end_time - service_start_time) AS service_duration
FROM(
SELECT equipment_id,
(CASE
END) AS service_start_time,
(CASE
END) AS service_end_time
FROM t1
WHERE equipment_id = 'EX123'
)AS A
) AS B
JOIN(
SELECT equipment_id,
SUM(available_end_time - available_start_time) AS available_duration
FROM (
SELECT equipment_id,
(CASE
END) AS available_start_time,
(CASE
END) AS available_end_time
FROM t2
WHERE equipment_id = 'EX123'
) AS C
) AS D
ON equipment_id=D.equipment_id
What I want to do is replace the WHERE clause with a GROUP BY to list all the ids, or similar, but getting that to work is beyond my skill level... Any help greatly appreciated :)
Try below:
SELECT
equipment_id, service_duration, available_duration,
(available_duration / service_duration)*100 AS availability
FROM
(
SELECT equipment_id,
SUM(service_end_time - service_start_time) AS service_duration
FROM
(
SELECT equipment_id,
(CASE ... END) AS service_start_time,
(CASE ... END) AS service_end_time
FROM t1
) AS A
GROUP BY equipment_id
) AS B
JOIN
(
SELECT equipment_id,
SUM(available_end_time - available_start_time) AS available_duration
FROM
(
SELECT equipment_id,
(CASE ... END) AS available_start_time,
(CASE ... END) AS available_end_time
FROM t2
) AS C
GROUP BY equipment_id
) AS D
ON equipment_id=D.equipment_id
Try this (replace my field names with your field names):
SELECT
a.emp_id,
service_duration,
available_duration
FROM
(
SELECT
emp_id,
SUM(service_end_time - service_start_time) AS service_duration
FROM
data
GROUP BY
emp_id
) a
JOIN
(
SELECT
emp_id,
SUM(available_end_time - available_start_time) AS available_duration
FROM
data
GROUP BY
emp_id
) b
ON a.emp_id = b.emp_id
GROUP BY
a.emp_id
I have two SELECT statements that give the values "TotalSales" and "VendorPay_Com". I want to be able to subtract VendorPay_Com from TotalSales within the one MySQL statement to get the value "Outstanding_Funds" but I haven't found a reliable way to do so.
These are my two statements:
Query 1:
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold';
Query 2:
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
Any help on this matter would be greatly appreciated :)
You can do it as follows :
select (select ...) - (select ...)
In your example, simply :
select
(
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold'
)
-
(
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
) AS Outstanding_Funds
Try
SELECT TotalSales-VendorPay_Comm AS Outstanding_Funds
FROM
(SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold') t1,
(SELECT SUM(Amount) AS VendorPay_Comm
FROM (SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS Amount
FROM COMMISSION
WHERE Status = 'Paid') t0) t2
Here is sqlfiddle
I have table psc_Pro_ProfessorPositions(ProfessorID,PositionID,StartDate,EndDate). It have 2 primary key is ProfessorID,PositionID.
I want to check ProfessorID,PositionID not in table to insert.I wrote like this:
insert into CoreUIs.dbo.psc_Pro_ProfessorPositions
(
ProfessorID,PositionID,StartDate,EndDate
)
select a.MaQuanLy,b.MaQuanLy,convert(smalldatetime,NgayHieuLuc),convert(smalldatetime,NgayHetHieuLuc)
from inserted
inner join GiangVien a on a.MaGiangVien = inserted.MaGiangVien
inner join ChucVu b on b.MaChucVu = inserted.MaChucVu
where a.MaQuanLy not in (select ProfessorID from CoreUIs.dbo.psc_Pro_ProfessorPositions)
and b.MaQuanLy not in (select PositionID from CoreUIs.dbo.psc_Pro_ProfessorPositions)
But it's wrong.Can help me?Thanks all.
;WITH x AS
(
SELECT TeacherID, ClassID, ClassStuID, s = [SUM],
rn = ROW_NUMBER() OVER (PARTITION BY TeacherID ORDER BY ClassID)
FROM dbo.TB1
)
SELECT TeacherID, ClassID, ClassStuID,
[SUM] = CASE rn WHEN 1 THEN s ELSE NULL END
FROM x
ORDER BY TeacherID, [SUM] DESC;
You can employ CTEs with ROW_NUMBER()OVER() to identify the first row of each TeacherID:
; with a as (
select * from TB1
union
select * from TB2
)
, b as (
select *, r=ROW_NUMBER()over(partition by a.TeacherID order by a.TeacherID,
a.ClassID, a.ClassStuID) from a
)
select b.TeacherID, b.ClassID, b.ClassStuID
, [SUM]=case b.r when 1 then b.[SUM] else null end
from b
order by b.TeacherID, b.r
go
Result: