How to get count of records satisfying multipel critierias in SQL Server? - sql

I have an sql table with the below columns
OrderNo, GroupNum, ShipMethod, TrackingNo
I want to find number of orders that have multiple 'ShipMethod' for same groupnum?
Sample records wourld be:
Order123 1 DHL
Order123 2 DHL1
Order123 2 Fedex
Then i need to get result stating 2 or if possible output as below:
OrderNumer GroupNum Count
---------- ------- -----
Order123 2 2 (Because 2 shipmethods)

Group by the columns you want to be unique, use count() to get each groups count and use having to limit the output to only the relevant groups
select ordernum, groupnum, count(*) as cnt
from your_table
group by ordernum, groupnum
having count(*) > 1

If I understand correctly:
select OrderNumer, groupnum, count(*)
from t
group by OrderNumer, groupnum
having count(*) > 1;
You may also want count(distinct shipmethod), if you want to count the distinct values rather than the number of rows.

Related

COUNT of GROUP of two fields in SQL Query -- Postgres

I have a table in postgres with 2 fields: they are columns of ids of users who have looked at some data, under two conditions:
viewee viewer
------ ------
93024 66994
93156 93151
93163 113671
137340 93161
92992 93161
93161 93135
93156 93024
And I want to group them by both viewee and viewer field, and count the number of occurrences, and return that count
from high to low:
id count
------ -----
93161 3
93156 2
93024 2
137340 1
66994 1
92992 1
93135 1
93151 1
93163 1
I have been running two queries, one for each column, and then combining the results in my JavaScript application code. My query for one field is...
SELECT "viewer",
COUNT("viewer")
FROM "public"."friend_currentfriend"
GROUP BY "viewer"
ORDER BY count DESC;
How would I rewrite this query to handle both fields at once?
You can combine to columns from the table into a single one by using union all then use group by as below:
select id ,count(*) Count from (
select viewee id from vv
union all
select viewer id from vv) t
group by id
order by count(*) desc
Results:
This is a good place to use a lateral join:
select v.viewx, count(*)
from t cross join lateral
(values (t.viewee), (t.viewer)) v(viewx)
group by v.viewx
order by count(*) desc;
You can try this :
SELECT a.ID,
SUM(a.Total) as Total
FROM (SELECT t.Viewee AS ID,
COUNT(t.Viewee) AS Total
FROM #Temp t
GROUP BY t.Viewee
UNION
SELECT t.Viewer AS ID,
COUNT(t.Viewer) AS Total
FROM #Temp t
GROUP BY t.Viewer
) a
GROUP BY a.ID
ORDER BY SUM(a.Total) DESC

Counting how many items are repeated 1, 2 or 3 times

I have values
Contractor_Key
--
AAA
BBB
CCC
BBB
CCC
CCC
DDD
CCC
In this example, AAA and DDD repeated just once, this means that count of once repeated values is 2. BBB repeated twice and twice repeated items count here is just 1.
exactly tree times repeated values there are not at all and I don't want output CCC because it repeated more than 3 times.
I need calculate, how many values I have, which repeated exactly once, twice or three times.
I know this is something by using grouping, but don't realize how to get desirable result
Use two levels of aggregation:
select cnt, count(*), min(Contractor_Key), max(Contractor_Key)
from (select Contractor_Key, count(*) as cnt
from t
group by Contractor_Key
) c
group by cnt
order by cnt;
I call this a "histogram-of-histgrams" query. I include two examples of keys for each count for further investigation.
SELECT item_repeated_quantity, COUNT(*) FROM (
SELECT Contractor_Key, COUNT(*) AS item_repeated_quantity from t group by Contractor_Key HAVING COUNT(*) <= 3
)t
GROUP BY item_repeated_quantity
ORDER BY item_repeated_quantity
I think you want to do aggregation twice - first to find count for each contractor_key and then find count for each value of count (found in first aggregation):
select cnt,
count(*) as times
from (
select count(*) cnt
from your_table
group by contractor_key
) t
group by cnt;
Try this
;WITH CTE
AS
(
SELECT
Contractor_Key,
Cnt = COUNT(1)
FROM MyTable
GROUP BY Contractor_Key
)
SELECT
Cnt,
COUNT(1)
FROM CTE

displaying distinct column value with corresponding column random 3 values

I have a table employee with columns (state_cd,emp_id,emp_name,ai_cd) how can i display disticnt state_cd with 3 different values from ai_cd
the answer should be
state_cd ai_cd
------- --------
TX 1
2
5
CA 9
10
11
This type of operation is normally better done in the application. But, you can do it in the query, if you really want to:
select (case when row_number() over (partition by state_cd order by ai_cd) = 1
then state_cd
end) as state_cd,
ai_cd
from employee e
order by e.state_cd, e.ai_cd;
The order by is very important, because SQL result sets are unordered. Your result requires ordering in order to make sense.
Just group by state_id and then count using count(Distinct column_name_)
select state_id from (select state_id,COUNT(DISTINCT ai_cd) as cnt from employee group by state_id) where cnt==3

Find duplicate records in a table using SQL Server

I am validating a table which has a transaction level data of an eCommerce site and find the exact errors.
I want your help to find duplicate records in a 50 column table on SQL Server.
Suppose my data is:
OrderNo shoppername amountpayed city Item
1 Sam 10 A Iphone
1 Sam 10 A Iphone--->>Duplication to be detected
1 Sam 5 A Ipod
2 John 20 B Macbook
3 John 25 B Macbookair
4 Jack 5 A Ipod
Suppose I use the below query:
Select shoppername,count(*) as cnt
from dbo.sales
having count(*) > 1
group by shoppername
will return me
Sam 2
John 2
But I don't want to find duplicate just over 1 or 2 columns. I want to find the duplicate over all the columns together in my data. I want the result as:
1 Sam 10 A Iphone
with x as (select *,rn = row_number()
over(PARTITION BY OrderNo,item order by OrderNo)
from #temp1)
select * from x
where rn > 1
you can remove duplicates by replacing select statement by
delete x where rn > 1
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as cnt
FROM dbo.sales
GROUP BY OrderNo, shoppername, amountPayed, city, item
HAVING COUNT(*) > 1
SQL> SELECT JOB,COUNT(JOB) FROM EMP GROUP BY JOB;
JOB COUNT(JOB)
--------- ----------
ANALYST 2
CLERK 4
MANAGER 3
PRESIDENT 1
SALESMAN 4
Just add all fields to the query and remember to add them to Group By as well.
Select shoppername, a, b, amountpayed, item, count(*) as cnt
from dbo.sales
group by shoppername, a, b, amountpayed, item
having count(*) > 1
To get the list of multiple records use following command
select field1,field2,field3, count(*)
from table_name
group by field1,field2,field3
having count(*) > 1
Try this instead
SELECT MAX(shoppername), COUNT(*) AS cnt
FROM dbo.sales
GROUP BY CHECKSUM(*)
HAVING COUNT(*) > 1
Read about the CHECKSUM function first, as there can be duplicates.
Try this
with T1 AS
(
SELECT LASTNAME, COUNT(1) AS 'COUNT' FROM Employees GROUP BY LastName HAVING COUNT(1) > 1
)
SELECT E.*,T1.[COUNT] FROM Employees E INNER JOIN T1 ON T1.LastName = E.LastName
with x as (
select shoppername,count(shoppername)
from sales
having count(shoppername)>1
group by shoppername)
select t.* from x,win_gp_pin1510 t
where x.shoppername=t.shoppername
order by t.shoppername
First of all, I doubt that the result it not accurate? Seem like there are Three 'Sam' from the original table. But it is not critical to the question.
Then here we come for the question itself. Based on your table, the best way to show duplicate value is to use count(*) and Group by clause. The query would look like this
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as RepeatTimes FROM dbo.sales GROUP BY OrderNo, shoppername, amountPayed, city, item HAVING COUNT(*) > 1
The reason is that all columns together from your table uniquely identified each record, which means the records will be considered as duplicate only when all values from each column are exactly the same, also you want to show all fields for duplicate records, so the group by will not miss any column, otherwise yes because you can only select columns that participate in the 'group by' clause.
Now I would like to give you any example for With...Row_Number()Over(...), which is using table expression together with Row_Number function.
Suppose you have a nearly same table but with one extra column called Shipping Date, and the value may change even the rest are the same. Here it is:
OrderNo shoppername amountpayed city Item Shipping Date
1 Sam 10 A Iphone 2016-01-01
1 Sam 10 A Iphone 2016-02-02
1 Sam 5 A Ipod 2016-03-03
2 John 20 B Macbook 2016-04-04
3 John 25 B Macbookair 2016-05-05
4 Jack 5 A Ipod 2016-06-06
Notice that row# 2 is not a duplicate one if you still take all columns as a unit. But what if you want to treat them as duplicate as well in this case? You should use With...Row_Number()Over(...), and the query would look like this:
WITH TABLEEXPRESSION
AS
(SELECT *,ROW_NUMBER() OVER (PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier) --if you consider the one with late shipping date as the duplicate
FROM dbo.sales)
SELECT * FROM TABLEEXPRESSION
WHERE Identifier !=1 --or use '>1'
The above query will give result together with Shipping Date, for example:
OrderNo shoppername amountpayed city Item Shipping Date Identifier
1 Sam 10 A Iphone 2016-02-02 2
Note this one is different from the one with 2016-01-01, and the reason why 2016-02-02 has been filtered out is PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier, and Shipping Date is NOT one of the column that need to be took care of for duplicate records, which means the one with 2016-02-02 still could be a perfect result for your question.
Now summarize it little bit, using count(*) and Group by clause together is the best choice when you only want to show all columns from Group byclause as the result, otherwise you will miss the columns that do not participate in group by.
While For With...Row_Number()Over(...), it is suitable in every scenario that you want to find duplicate records, however, it is little bit complicated to write the query and little bit over engineered compared to the former one.
If your purpose is to delete duplicate records from table, you have to use the later WITH...ROW_NUMBER()OVER(...)...DELETE FROM...WHERE one.
Hope this helps!
You can use below methods to find the output
with Ctec AS
(
select *,Row_number() over(partition by name order by Name)Rnk
from Table_A
)
select Name from ctec
where rnk>1
select name from Table_A
group by name
having count(*)>1
Select *
from dbo.sales
group by shoppername
having(count(Item) > 1)
Select EventID,count() as cnt
from dbo.EventInstances
group by EventID
having count() > 1
The following is running code:
SELECT abnno, COUNT(abnno)
FROM tbl_Name
GROUP BY abnno
HAVING ( COUNT(abnno) > 1 )

Select rows based on number of duplicates, ordered alphabetically

I'm trying to select the x most "popular" records from a table where there are a number of duplicate entries. I've got so far as returning records based on the count of the duplicate fields, but I also need them in alphabetical order.
For example:
SELECT country, COUNT(*) TotalCount
FROM destinations
GROUP BY country
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
LIMIT 4
This would return records as:
country - TotalCount
Mexico - 15
Cuba - 12
USA - 10
Australia - 5
How would I go about returning them ordered by country? I've tried changing the ORDER BY to the country field, but that then ignores the popularity, returning records with any number of duplicates.
Would a select within a select be the answer/possible?
SELECT country, count
FROM
(SELECT country, COUNT(*) as count
FROM ...
HAVING ...) as Dup
ORDER BY
country
Can't mySQL just do this:
Select country
, count(*)
from theTable
group by country
having count(*) > 1
order by country