How to get count of ID's having status other then cancelled. If StatusType = Cancelled then that ID not be considered in the count in MemSQL.
Expected:
count =2
10004 = Available and Not started
10006 = Not started
ID StatusType
10001 NULL
10001 Available
10001 Not Started
10001 Cancelled
10002 Cancelled
10002 Not Started
10003 Available
10003 NULL
10003 Cancelled
10004 Available
10004 Not Started
10005 Cancelled
10006 Not Started
You can do it in two steps. First do a GROUP BY with HAVING to find ID's without Cancelled. Then count these ID's.
select count(*)
from (
select ID
from tablename
group by ID
having sum(case when StatusType = 'Cancelled' then 1 else 0 end) = 0
) dt
Or, do NOT EXISTS in a correlated subquery.
select count(distinct ID)
from tablename t1
where not exists (select 1 from tablename t2
where t1.id = t2.id
and t2.StatusType = 'Cancelled')
Related
I have a table of bank transactions, AccountTransaction, and rows with for e.g.
Amount
Payee_Name
Transaction_ID
Is_Corresponding_Transaction
69.00
Bob Jones
1
1
-69.00
Bob Jones
1
0
25.00
Bill
2
1
-25.00
Bill
2
0
297.00
Sally
3
1
-5.00
Ted
4
1
2.50
Ted
4
0
2.50
Ted
4
0
How do I select only (all) TS like Sally's where the Transaction ID only occurs once?
Bonus points: How do I select TS like Ted's where the sum of all Is_Corresponding_Transaction = 0 != the sum of Is_Corresponding_Transaction = 1 for a given TS_ID?
I was looking and found a Group by or where not exists, but couldn't figure out how to get that to work
Here's an e.g. of what I tried:
select
Full_Name, amount, a.Posted_Date,a.Payee_Name, a.Memo, Accounts.Account_Name
from AccountTransaction a
left join Accounts on Accounts.Account_Code = a.Account_Code
left join users on a.UserId = users.UserId
where not exists (select 1 from AccountTransaction b where a.Transaction_ID = b.Transaction_ID having count(*)>1)
and a.Pending= 0
ORDER by a.Posted_Date desc
Just to expand on Stu's comment. Here is one option that uses the window function
with cte as (
Select *
,NetSum = sum(Amount) over (partition by Transaction_ID)
,NetCnt = sum(1) over (partition by Transaction_ID)
From YourTable
)
Select *
From cte
Where NetSum<>0
or NetCnt<>2
I am building an application consisting of an SQL backend and several microservices that communicate with this backend. I am trying to get as little data as possible from the database over the wire so I am trying to fetch the exact records so I don't have to start looping in the application logic.
So this is the source table :
OrderID
Topic
hierarchyLevel
Responsible Person
Status
1234
A
0
Jason
Open
1234
A
0
Carol
Open
1234
A
1
Jeff
Open
1234
A
2
Alina
Open
1234
A
3
Eileen
Open
1234
B
0
John
Closed
1234
B
1
Danny
Open
1234
B
1
Celine
Open
1234
B
2
Corry
Open
1234
B
3
Logan
Open
1234
C
0
Jason
Closed
1234
C
1
Annisa
Open
1234
C
2
Cedric
Open
1234
D
0
Peter
Closed
1234
D
1
Joanna
Closed
1234
D
2
Freeke
Open
1234
E
0
Carol
Closed
1234
E
1
Cynthia
Closed
1234
E
2
Deidra
Open
Based on the "orderID" as input parameter for the query , I should get the for every topic the next persons in line , so with the lowest HierarchyLevel number for that topic, that has status "Open". So every topic can return multiple times as long as the returned records have the lowest possible value in "HierarchyLevel" and the status is "Open".
So I would expect this as output for the stored procedure :
OrderID
Topic
hierarchyLevel
Responsible Person
Status
1234
A
0
Jason
Open
1234
A
0
Carol
Open
1234
B
1
Danny
Open
1234
B
1
Celine
Open
1234
C
1
Annisa
Open
1234
D
2
Freeke
Open
1234
E
2
Deidra
Open
I tried to work with min() but with no luck:
Some things I tried :
select * from mytable as a
inner join (
select Topic, min(HierarchyLevel) as min_value
from mytable
group by Topic
) t on t.Topic = a.Topic and a.HierarchyLevel = min_value and a.OrderID = #OrderID and Status = 'Open'
select * from mytable as a
inner join (
select Topic, Status ,min(HierarchyLevel) as min_value
from mytable
group by Topic , Status HAVING Status = 'Open'
) t on t.Topic = a.Topic and a.HierarchyLevel = min_value and a.OrderID = #OrderID and a.Status = 'Open'
None with the desired result. Could anyone guide me in the right direction?
Thank you very much.
Lookup RANK() OVER (...). I guess something like:
SELECT OrderID, Topic, hierarchyLevel, Responsible_Person, Status
FROM (
SELECT OrderID, Topic, hierarchyLevel, Responsible_Person, Status
, RANK() OVER (PARTITION BY OrderID, Topic
ORDER BY hierarchyLevel) AS rnk
FROM t
WHERE Status = 'Open'
) AS T
WHERE rnk = 1;
One straight-forward solution is to use a correlated aggregate using exists:
select *
from t
where exists (
select * from t t2
where t2.OrderId = t.OrderId
and t2.Topic = t.Topic
and t2.Status = 'Open'
group by t2.OrdeRId, t2.Topic
having Min(t2.hierarchyLevel) = t.hierarchyLevel
);
Demo DB<>Fiddle
Result:
One way is to check if all the records with open status intersect with said records also having the lowest heirarchy_level per order_id and topic
select order_id, topic, heirarchy_level, responsible_person, status
from t
where status='Open'
intersect
select order_id, topic, min(heirarchy_level) over (partition by order_id, topic), responsible_person, status
from t
where status='Open'
I have a case expression in a stored procedure summing an account field, and then inserting into a user id. The logic works... until joining to another table.
I tried adding distinct counts, and additional tables to the query, but still when I join to another table it applies the 1 value when I want it to be 0 to the account.
This is the calculation in the stored proc;
INSERT INTO #SUMMARY_TEMP (USER_ID,FSN_CNT )
(SELECT USER_ID,
SUM(CASE WHEN A_GROUP_CD = 'RED' AND A_TYPE_CD = 'FSN' THEN REC_COUNT ELSE 0 END)
) AS 'FSN_CNT',
FROM (SELECT A_ACCOUNT_NBR,
A_USER_ID,
A_GROUP_CD,
A_TYPE_CD,
COUNT(*) AS REC_COUNT
FROM EXCEPTION_DETAIL
INNER JOIN #STAFF ON A_REPORT_DT = #REPORT_DT
AND (A_USER = B_USER_ID)
GROUP BY A_ACCOUNT_NBR,
A_USER_ID_ID,
A_GROUP_CD,
A_TYPE_CD) EXCEPTIONS
GROUP BY A_USER_ID,
A_ACCOUNT_NBR)
This is the result which is what I expect for 2 USER Ids
A_ACCOUNT_NBR USER_ID FSN_CNT
123456 HENRY 0
123498 HENRY 1
374933 JOE 1
474930 JOE 0
but when I join to another table the data looks like
A_ACCOUNT_NBR USER_ID FSN_CNT
123456 HENRY 1
123498 HENRY 1
374933 JOE 1
474930 JOE 1
Its applying the 1 value to account 123456 & 474930 when it should be 0.
I think its because the other table does not have the ACCOUNT_NBR column - I am joining on USER_ID and so it applies the 1 to all ACCOUNT_NBR from table A.
Thanks for all the suggestions, I tried using a CTE, and the counts now look good, but its created duplicate rows as shown below. Any suggestions on how to remove the duplication, below is the join I am using for the CTE;
select cte.*, jt.USER_ID
from cte
join EXCEPTION_DETAIL jt on cte.USER_ID=jt.USER_ID
USER ACCOUNT_NBR FSN_CNT
HENRY 123456 0
HENRY 123456 0
HENRY 123498 1
HENRY 123498 1
JOE 374933 1
JOE 374933 1
JOE 474930 0
JOE 474930 0
you can separate the 1st query by using cte and join with it next level like below
with cte as
(
(SELECT USER_ID,
SUM(CASE WHEN A_GROUP_CD = 'RED' AND A_TYPE_CD = 'FSN' THEN REC_COUNT ELSE 0 END)
) AS 'FSN_CNT',
FROM (SELECT A_ACCOUNT_NBR,
A_USER_ID,
A_GROUP_CD,
A_TYPE_CD,
COUNT(*) AS REC_COUNT
FROM EXCEPTION_DETAIL
INNER JOIN #STAFF ON A_REPORT_DT = #REPORT_DT
AND (A_USER = B_USER_ID)
GROUP BY A_ACCOUNT_NBR,
A_USER_ID_ID,
A_GROUP_CD,
A_TYPE_CD) EXCEPTIONS
GROUP BY A_USER_ID,
A_ACCOUNT_NBR)
) select cte.*,jt.USER_ID from cte join jointable_name jt on cte.USER_ID=jt.USER_ID
Ok so i have one table with lets call it A(there are more items here):
ITEMID NAME
10001 Boat
I have another table lets call it B(there are more items here):
Itemid Price Pricetype Dimension Valid_from Valid_To
10001 10 1 Allblank 2014-10-10 2014-10-25
10001 5 2 200 2014-10-09 2014-10-20
10001 99 2 200 2014-10-08 2014-10-10
10001 20 1 Allblank 2014-10-08 2014-10-10
10001 22 2 500 2014-10-10 2014-10-19
Price type determines wherever item is on sale or no so i want to list the regular price at its dimension and the sales price at the dimension so the table should look like this (assuming that 1 is regular price and 2 is sale price):
Itemid Itemname RegularPrice DiscountPrice200 DiscountPrice500
10001 boat 10 5 22
I've inner joined tables, but i cant manage to manage the fields right , case statement returns a lot of duplicates on inner join. I hope i made myself clear :)
My query:
SELECT a.itemid,
case when b.inventdimid = '00000101_090' and (b.labelissue ='1' or b.labelissue = '2' and (b.todate > getdate() or b.todate ='1900-01-01 00:00:00.000') ) then b.amount else null end as Price500
FROM a
inner join b
on a.itemid = b.itemrelation
Try this query:
SELECT b.itemid,
a.name,
b.price,
b200.price,
b500.price
FROM tb b
JOIN ta a
ON b.itemid = a.itemid
JOIN tb b200
ON b.itemid = b200.itemid
AND b200.valid_to > getdate()
AND b200.pricetype = 2
AND b200.dimension = 200
JOIN tb b500
ON b.itemid = b500.itemid
AND b500.valid_to > getdate()
AND b500.pricetype = 2
AND b500.dimension = 500
WHERE b.valid_to > getdate()
AND b.pricetype = 1
This is my orders table. I want to report all orders which all details are Ready For Shipment.
orderNo detailNo statusId status
10001 1 40 Ready For Shipment
10002 1 40 Ready For Shipment
10002 2 20 Canceled
10002 3 30 Pending
10003 1 40 Ready For Shipment
10003 2 40 Ready For Shipment
10004 1 10 New Order
10004 2 20 Canceled
10004 3 40 Ready For Shipment
10004 4 40 Ready For Shipment
Expected results are:
Orders Ready For Shipment
10001
10003
Are there any effective method to achieve ready orders list without using subqueries?
Group by the orderno and use a havingto get only those groups having no other status
select orderno
from your_table
group by orderno
having sum(case when status <> 'Ready For Shipment' then 1 end) = 0
or with the statusId
select orderno
from your_table
group by orderno
having sum(case when statusid <> 40 then 1 end) = 0
select Distinct a.orderId
from ordersTable a
inner join
(
select orderNo, Avg(statusId)
from ordersTable
group by orderNo
having Avg(statusId) = 40) b
on a.orderNo = b.orderNo
Have you tried this?
SELECT orderNo from <TABLE NAME>
WHERE status="Ready For Shipment" ORDER BY orderNo