TSQL count rows for group by - sql-server

I need the count of rows after the group by.
SELECT COUNT(CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
Results:
Row 1 = 1
Row 2 = 15
Row 3 = 5
I also tried using DISTINCT
SELECT COUNT(DISTINCT CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
Results:
Row 1 = 1
Row 2 = 1
Row 3 = 1
I want the results to be 3

It seems to me the GROUP BY is entirely redundant based on what you say you want. Why not just:
SELECT COUNT(distinct CheckNumber)
FROM myTable
WHERE Status = 'Good'

If I understand correctly you could do this:
SELECT COUNT(*) FROM
(
SELECT COUNT(CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
) as myData
This should give you your total of 3 as requested.

Related

How to get all orders with maximum update_count value only?

I have laboratory orders system and these orders can be update more than one time for example
order_id test_id update_count
10 1 1
10 1 2
10 1 3
11 2 1
11 5 1
12 3 1
12 3 2
I want to select all orders without duplicates and select orders with maximum update count
I tried a lot and i checked WITH clients as and self join but always select statement returned all rows with all update counts not only maximum update count for each order_id
This is my Select statement:
SELECT LAB_RESULTS.ORDER_ID as 'Order Number'
,LAB_RESULTS.PATIENT_NO as 'Patient No'
,Patients.Patient_Name as 'Patient Name'
,Patients.Age as 'Patient Age'
,LabTests.TestName as 'Test Name'
,LAB_RESULTS.RESULT_NUMBER as 'Result'
,LAB_RESULTS.RESULT_REPORT as 'Text Result'
,LAB_RESULTS.APPROVED_DATE as 'Approved_Date'
,LAB_RESULTS.REQ_FORM_NO as 'Request Form Number'
,LAB_RESULTS.CUSTID as 'Customer Id'
,Machines.Machine_name as 'Machine Name'
,LAB_RESULTS.SAMPLE_ID as 'Sample Id'
,LAB_RESULTS.packageid as 'package id'
,LAB_RESULTS.GROUPID as 'group id'
,LAB_RESULTS.EXAMINED_BY as 'Examined By'
,LAB_RESULTS.EXAMINED_DATE as 'Examined Date'
,LAB_RESULTS.APPROVED_BY as 'Approved By'
,LAB_RESULTS.update_count
FROM LAB_RESULTS
inner join patients on LAB_RESULTS.patient_no = Patients.Patient_No
inner join labtests on LabTests.TestId = LAB_RESULTS.TESTID
inner join Machines on Machines.Machine_id = LAB_RESULTS.machine_id
where LAB_RESULTS.APPROVED_BY is not null
and LAB_RESULTS.SAMPLE_STATUS = 6
and LAB_RESULTS.update_count in (select max(update_count) from LAB_RESULTS where LAB_RESULTS.SAMPLE_STATUS = 6 and LAB_RESULTS.deptid = 2 )
and LAB_RESULTS.deptid = 2
I expect to get the following result :
order_id test_id update_count
10 1 3
11 2 1
11 5 1
12 3 2
then i added this condition but this return only the maximum update count only not group by each order_id only the maximum for all orders.
and LAB_RESULTS.update_count in (select max(update_count) from LAB_RESULTS where LAB_RESULTS.SAMPLE_STATUS = 6 and LAB_RESULTS.deptid = 2 )
How can I do this ?
then i added this condition but this return only the maximum update
count only not group by each order_id only the maximum for all orders.
The only reason your update_count in() didn't work is because you didn't correlate the subquery.
Instead of this:
and LAB_RESULTS.update_count in (
select max(update_count)
from LAB_RESULTS
where LAB_RESULTS.SAMPLE_STATUS = 6
and LAB_RESULTS.deptid = 2
)
You need this:
and LAB_RESULTS.update_count in (
select max(update_count)
from LAB_RESULTS l2
where l2.SAMPLE_STATUS = 6
and l2.deptid = 2
AND l2.order_id=LAB_RESULTS.order_id --correlate to outer query
)
Although I recommend also aliasing the table in the main query and using both aliases in the subquery.
Add this into your select statement:
,DENSE_RANK() OVER
(PARTITION BY LAB_RESULTS.ORDER_ID ORDER BY LAB_RESULTS.update_count DESC) AS rank
Then you will wrap that result in a WITH clause and select and filter doing something like this:
WITH base_query as (
the current query you have with the extra column I suggested before) Select order_id, test_id, update_count where rank=1
CREATE TABLE t1
(order_id INT, test_id INT, update_count INT)
INSERT INTO t1 VALUES
(10,1,1),
(10,1,2),
(10,1,3),
(11,2,1),
(11,5,1),
(12,3,1),
(12,3,2)
SELECT * FROM dbo.t1
SELECT order_id, test_id, MAX(update_count)
FROM dbo.t1
GROUP BY order_id, test_id
ORDER BY order_id, test_id
DROP TABLE dbo.t1

unique chat records sql

I have DB which having 5 column as follows:
message_id
user_id_send
user_id_rec
message_date
message_details
Looking for a SQL Serve Query, I want to Filter Results from two columns (user_id_send,user_id_rec)for Given User ID based on following constrains:
Get the Latest Record (filtered on date or message_id)
Only Unique Records (1 - 2 , 2 - 1 are same so only one record will be returned which ever is the latest one)
Ordered by Descending based on message_id
SQL Query
The main purpose of this query is to get records of user_id to find out to whom he has sent messages and from whom he had received messages.
I have also attached the sheet for your reference.
Here is my try
WITH t
AS (SELECT *
FROM messages
WHERE user_id_sender = 1)
SELECT DISTINCT user_id_reciever,
*
FROM t;
WITH h
AS (SELECT *
FROM messages
WHERE user_id_reciever = 1)
SELECT DISTINCT user_id_sender,
*
FROM h;
;WITH tmpMsg AS (
SELECT M2.message_id
,M2.user_id_receiver
,M2.user_id_sender
,M2.message_date
,M2.message_details
,ROW_NUMBER() OVER (PARTITION BY user_id_receiver+user_id_sender ORDER BY message_date DESC) AS 'RowNum'
FROM messages M2
WHERE M2.user_id_receiver = 1
OR M2.user_id_sender = 1
)
SELECT T.message_id
,T.user_id_receiver
,T.user_id_sender
,T.message_date
,T.message_details
FROM tmpMsg T
WHERE RowNum <= 1
The above should fetch you the results you are looking for when you query for a particular user_id (replace the 1 with parameter e.g. #p_user_id). The user_id_receiver+user_id_sender in the PARTITION clause ensure that records with user id combinations such as 1 - 2, 2 - 1 are not selected twice.
Hope this helps.
select * from
(
select ROW_NUMBER() over (order by message_date DESC) as rowno,
* from messages
where user_id_receiver = 1
--order by message_date DESC
) T where T.rowno = 1
UNION ALL
select * from
(
select ROW_NUMBER() over (order by message_date DESC) as rowno,
* from messages
where user_id_sender = 1
-- order by message_date DESC
) T where T.rowno = 1
Explanation: For each group of user_id_sender, it orders internally by message_date desc, and then adds row numbers, and we only want the first one (chronologically last). Then do the same for user_id_receiver, and union the results together to get 1 result set with all the desired rows. You can then add your own order by clause and additional where conditions at the end as required.
Of course, this only works for any 1 user_id at a time (replace =1 with #user_id).
To get a result from all user_id's at once, is a totally different query, so I hope this helps?

buLK Update duplicate row value

Update duplicate column value with
Suppose I have a table with follow column
ID, Code, IsDuplicate, Description
I have n records inside and I would like to bulk update the IsDuplicate value if there is duplicate code inside.
Example
1 ABC null null
2 DEF null null
3 DEF null null
4 ABC null null
5 FGH null null
ID 1, 2, 3, 4 IsDuplicate will be updated to true.
How could it be done?
This will update all duplicate codes :
UPDATE T
SET ISDUPLICATE = 'TRUE'
FROM YOURTABLE T
WHERE EXISTS (SELECT 1
FROM (SELECT *
FROM (SELECT ROW_NUMBER()
OVER (
PARTITION BY CODE
ORDER BY ID)RN,
*
FROM YOURTABLE)A
WHERE RN > 1)B
WHERE B.CODE = T.CODE)
You should use group by in select query.
SELECT code, COUNT(*) c FROM table GROUP BY code HAVING c > 1;
Then you can update it based on your requirements.

Use NOT Equal condition in sql?

I want to fetch orders that have a “Received” (ActivityID = 1) activity but not a “Delivered” (ActivityID = 4) activity on orders table. i.e orders that are received but not deliverd yet.
my query is
SELECT OrderID FROM tblOrderActivity
where (tblOrderActivity.ActivityID = 1 AND tblOrderActivity.ActivityID != 4)
GROUP BY OrderID
it is not returning desired result.
result should be orderID 2 and 4
Your query doesn't really make sense. Grouping happens after WHERE clause, so you're basically getting all orders that have ActivityID ==1 (because if activity Id is 1 there it's always not equal to 4).
After WHERE clause is applied you end up with following rows:
OrderID ActivityID
1 1
2 1
3 1
4 1
And these are the orders you group. No more condition is evaluated.
If 4 is the highest possible ActivityID you could do following:
SELECT OrderID
FROM tblOrderActivity
GROUP BY OrderID
HAVING MAX(ActivityID) < 4
HAVING condition is applied after grouping, which is what you want.
I don't think Group by is needed here. You can use a Subquery to find he order's which is not delivered. Try this.
SELECT *
FROM Yourtable a
WHERE a.ActivityID = 1
AND NOT EXISTS (SELECT 1
FROM yourtable b
WHERE a.OrderID = b.OrderID
AND b.ActivityID = 4)

How to count the number of rows with specific data in mssql

I have the following table:
Items:
ID Type StockExists
01 Cellphone T
02 Cellphone F
03 Apparrel T
I want to count the number of items with existing stocks, i.e., the number of rows with StockExists='T'. I was performing the query as;
Select count(StockExists)
From [Items] where StockExists='T'
but it is always returning 1. What is the right way to do it?
Edit:
Also, how to perform another such Count operation and add them together in one row, for example,
Select count(StockExists)
From [Items] where StockExists='T'` and `Select count(Type)
From [Items] where Type='Cellphone'` ?
SELECT
COUNT(*) As ExistCount
FROM
dbo.Items
WHERE
StockExists='T'
So your query should work.
Result:
EXISTCOUNT
2
Demo
Update
How to perform another such Count operation and add them together in
one row, for example, Select count(StockExists) From [Items] where
StockExists='T' and Select count(Type) From [Items] where
Type='Cellphone' ?
You can use SUM with CASE:
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE 0 END) ,
CellphoneCount = SUM(CASE WHEN Type='Cellphone' THEN 1 ELSE 0 END)
FROM
dbo.Items
Result:
EXISTCOUNT CELLPHONECOUNT
2 2
Demo
Select Sum(Case when field = 'this' then 1 else 0 end) as Total
from YourTable
When using CASE WHEN better to use NULL than 0 in ELSE case like below
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE NULL END) ,
TotalCount = COUNT(ID)
FROM
dbo.Items

Resources