Count each unique content - sql-server

How do I count how many times the content of a field nameappears in my table?
Name | Other
Brad | smth
Brad | smth
Daniel | smth
Matt | smth
Matt | smth
Matt | smth
For example,for the above table I would like to know how many times I have 'Brad',how many times 'Daniel' and how many times 'Matt'.How do I do this with just one select?
I'm interested in this because I want do display only the Names that appear more times than a given value.
My actual code:
select director.LastName,director.FirstName,count(director.FirstName)as counter,film.title
from director,film
where film.Id_Director=director.id
group by director.LastName,director.FirstName,film.title
having count(Director.FirstName)>2
Baz Luhrmann 1 Paranormal activity 4
Baz Luhrmann 1 Struck by lightning
Baz Luhrmann 1 The big bang theory
Baz Luhrmann 1 The family
Baz Luhrmann 1 The Quarterback
Brad Falchuk 1 A Kitty or a Gaga
Brad Falchuk 1 All or nothing
Brad Falchuk 1 Bridesmaids
Brian Dan 1 All or nothing
I was expecting it to count exactly how many times 'Baz' appears in the table(this should be done for every name) and display only if the value of count > the 3 for example.

Group by the name and use a count()
select name, count(*) as name_count
from your_table
group by name
Aggregate functions like count are applied for each group.
To display only names that appear more than 1 time you can do
select name, count(*) as name_count
from your_table
group by name
having count(*) > 1
Having is like a where clause but for groups.
Edit
select d.LastName, d.FirstName, count(f.Id_Director) as counter
from director d
inner join film f on f.Id_Director = d.id
group by d.LastName, d.FirstName
having count(f.Id_Director) > 2
You had grouped by the film too. That won't work. You basically queried for directors that are more than 2 times part of a film.

The problem is you are grouping by film. Since there are a director/film is ill away count as 1.
You you want to keep the film names in that select result set I suggest you make a select movies and a subquery to count how many times that director can be joined to other movies.
Just writed a example at SQLFiddle
Example

Related

Sql Server Weird CASE Statement

I am attempting to do something, but I am not sure if it is possible. I don't really know how to look up something like this, so I'm asking a question here.
Say this is my table:
Name | Group
-----+--------
John | Alpha
Dave | Alpha
Dave | Bravo
Alex | Bravo
I want to do something like this:
SELECT TOP 1 CASE
WHEN Group = 'Alpha' THEN 1
WHEN Group = 'Bravo' THEN 2
WHEN Group = 'Alpha' AND
Group = 'Bravo' THEN 3
ELSE 0
END AS Rank
FROM table
WHERE Name = 'Dave'
I understand why this won't work, but this was the best way that I could explain what I am trying to do. Basically, I just need to know when one person is a part of both groups. Does anyone have any ideas that I could use?
You should create a column to hold the values you want to sum and sum them, probably easiest to do this via a subquery:
Select Name, SUM(Val) as Rank
FROM (SELECT Name, CASE WHEN Group = 'Alpha' THEN 1
WHEN Group = 'Bravo' THEN 2
ELSE 0 END AS Val
FROM table
WHERE Name = 'Dave') T
GROUP BY Name
You can add TOP 1 and ORDER BY SUM(Val) to get the top ranked row if required.
After reading your comment, it could be simplified further to:
Select Name, COUNT([GROUP]) GroupCount
FROM table
GROUP BY Name
HAVING COUNT([GROUP]) > 1
That will simply return all names where they have more than 1 group.

SQL Server : count ProductID to get total times sold

I'm having trouble with what seems to be a simple query. I'm trying to get the amount of times an entire product has sold by counting and grouping by the ProductID. I've researched it online and every where I go it's just add a simple COUNT, but when I do it, it still outputs the same numbers of rows.
So if I don't use COUNT (for example) it outputs 1,000 rows, and if I DO use COUNT it outputs 1,000 rows and doesn't give me the correct times sold. They are all listed as "1" and not being grouped and counted. I'm guessing it has something to do with my joins but I can't figure it out.
Here's an example below of what I'm seeing after using the COUNT (I've removed brand and date_added just to make it easier to read). ProductID's are showing more than once even though they should be grouped together and counted.
times_sold | ProductID | title
---------- | --------- | ---------
1 | 17998 | title 2
1 | 13670 | title 3
1 | 17956 | title 4
1 | 4569 | title 5
1 | 12598 | title 1
1 | 12598 | title 1
1 | 17998 | title 2
And here's the query I'm running:
SELECT TOP (100) PERCENT
COUNT(s.ProductID) AS times_sold,
s.ProductID, p.title, p.brandname, p.date_added
FROM
dbo.TBL_OrderSummary AS s
INNER JOIN
dbo.jewelry AS p ON s.ProductID = p.ProductID
INNER JOIN
dbo.sent_items AS i ON s.InvoiceID = i.ID
GROUP BY
s.ProductID, p.title, p.brandname, p.flare_type, p.date_added,
i.date_order_placed, i.ship_code, p.jewelry
HAVING
(p.title LIKE '%stone%')
AND (i.date_order_placed > CONVERT(DATETIME, '2016-01-01 00:00:00', 102))
AND (i.ship_code = N'paid')
AND (p.flare_type = 'Single flare')
AND (p.jewelry LIKE '%plugs%')
Thanks for any help!
The reason why they aren't looking right is because the records aren't the same all the way across in the row. If you have a product name Widget 2 and year made is 2015 and you have another one product name widget and year made 2016 it is only going to count a 1 next to each product because the whole row only appears one time. You will need to limit your group by to get an accurate count.
GROUP BY s.productID, p.title, COUNT(s.productID)
This should give you an accurate count. You are just limiting your group by to a too large of sample to get any unique records. You will have to cut down what is in your select for this to work you need to have s.Product and p.title in your select to match the group by. Hope this helps.
Unless you are filtering by your aggregate function (ie. HAVING COUNT(s.ProductID) > 2) then you could move all of your selection criteria to the WHERE line.
So you could try:
select count(s.ProductID) times_sold, s.ProductID, p.title
from dbo.TBL_OrderSummary s inner join dbo.jewelry p on s.ProductID = p.ProductID
inner join dbo.sent_items i on s.InvoiceID = i.ID
where p.title like '%stone%'
and i.date_order_placed > CONVERT(DATETIME, '2016-01-01 00:00:00', 102)
and i.ship_code = N'paid'
and p.flare_type = 'Single flare'
and p.jewelry like '%plugs%'
group by s.ProductID, p.title

How to use group by in SQL Server query?

I have problem with group by in SQL Server
I have this simple SQL statement:
select *
from Factors
group by moshtari_ID
and I get this error :
Msg 8120, Level 16, State 1, Line 1
Column 'Factors.ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
This is my result without group by :
and this is error with group by command :
Where is my problem ?
In general, once you start GROUPing, every column listed in your SELECT must be either a column in your GROUP or some aggregate thereof. Let's say you have a table like this:
| ID | Name | City |
| 1 | Foo bar | San Jose |
| 2 | Bar foo | San Jose |
| 3 | Baz Foo | Santa Clara |
If you wanted to get a list of all the cities in your database, and tried:
SELECT * FROM table GROUP BY City
...that would fail, because you're asking for columns (ID and Name) that aren't in the GROUP BY clause. You could instead:
SELECT City, count(City) as Cnt FROM table GROUP BY City
...and that would get you:
| City | Cnt |
| San Jose | 2 |
| Santa Clara | 1 |
...but would NOT get you ID or Name. You can do more complicated things with e.g. subselects or self-joins, but basically what you're trying to do isn't possible as-stated. Break down your problem further (what do you want the data to look like?), and go from there.
Good luck!
When you group then you can select only the columns you group by. Other columns need to be aggrgated. This can be done with functions like min(), avg(), count(), ...
Why is this? Because with group by you make multiple records unique. But what about the column not being unique? The DB needs a rule for those on how to display then - aggregation.
You need to apply aggregate function such as max(), avg() , count() in group by.
For example this query will sum totalAmount for all moshtari_ID
select moshtari_ID,sum (totalAmount) from Factors group by moshtari_ID;
output will be
moshtari_ID SUM
2 120000
1 200000
Try it,
select *
from Factorys
Group by ID, date, time, factorNo, trackingNo, totalAmount, createAt, updateAt, bark_ID, moshtari_ID
If you are applying group clause then you can only use group columns and aggregate function in select
syntax:
SELECT expression1, expression2, ... expression_n,
aggregate_function (aggregate_expression)
FROM tables
[WHERE conditions]
GROUP BY expression1, expression2, ... expression_n
[ORDER BY expression [ ASC | DESC ]];

how to select column name that is not in group by clause

SELECT [a],[b],[c],COUNT(*) AS Hits
FROM [dbo].[ta] join [dbo].[tb] on [tb].[id] = [ta].[id]
where GROUP BY [a],[b],[c]
I want to select column c , but not in group by cluase?
because column "c" is returned a not suifficient record when as in group by clause
My current query is
SELECT top 20 [headshot],
[athleteId],
[athleteName],
COUNT() AS Hits
FROM [dbo].[tblRep_Usecase2]
join [dbo].[tblRep_Login] on [tblRep_Login].[ID] = [tblRep_Usecase2].[ID]
where athleteName != 'NULL'
and headshot != 'NULL'
and headshot != ''
and convert(date,[tblRep_Usecase2].[insertDate]) >='11/9/2015'
and convert(date,[tblRep_Usecase2].[insertDate]) <='11/9/2015'
and [tblRep_Usecase2].[appsportid]='41'
GROUP BY [headshot],[athleteId],[athleteName]
HAVING COUNT()>1 order by Hits DESC
Short answer : You can't.
Longer answer : You have to apply a formula to define how the "c" data is discriminated.
For instance, if you have a table about kids like
|a |b |c |
|-------|-------|---------|
|Bob |Sarah |Amanda |
|Bob |Sarah |Steve |
|Bob |Amanda |Sarah Jr.|
You ask him the number of kids of each couples (so Bob+Sarah = 2, Bob+Amanda=1), but then you also ask him the name of a kid. Since he cannot tell you which kid you want, he cannot give you your result.
In this case, maybe Bob, Sarah, Amada, Steve and Sarah Jr are in a table elsewhere with their age. so if you want only the oldest child, you would need to return a,b,"subquery","count". Depending on the situation, a simple aggregate function like MAX/MIN also works.

Apriori algorithm -Find 2 of combination

I have an Order table like this:
ORDER_ID PRODUCT_ID
1 1230
1 1231
1 1232
2 1231
2 2000
3 1230
3 3567
and a Product table:
PRODUCT_ID NAME
1230 A
1231 B
1232 C
My first question, how to get combination of 2 Product Table, then how my new table structure should be?
for example;
{1230,1231}, {1230,1232}, {1231,1232}
but I don't want to this {1231,1230} because it already added.
Second one, in Order table, I keep sold product one session. How will be my new table?
example;
orderid products
1 {1230,1231,1232}
Finally, I want to find product other sold together support value,
exp: {1231,1230} count : 2
{1230,1232 count : 0 }
thanks in advance.
edit: i want to do like this: http://webdocs.cs.ualberta.ca/~zaiane/courses/cmput499/slides/Lect10/sld054.htm
If I have interpreted your requirement correctly?
;WITH T(P1, P2, ORDER_ID)
AS (SELECT p1.PRODUCT_ID,
p2.PRODUCT_ID,
O.ORDER_ID
FROM Product p1
JOIN Product p2
ON p1.PRODUCT_ID < p2.PRODUCT_ID
JOIN [ORDER] o
ON o.PRODUCT_ID IN ( p1.PRODUCT_ID, p2.PRODUCT_ID )
GROUP BY p1.PRODUCT_ID,
p2.PRODUCT_ID,
O.ORDER_ID
HAVING COUNT(*) = 2)
SELECT P1,
P2,
COUNT(*) AS Cnt
FROM T
GROUP BY P1,
P2
I don't really understand questions 2 or 3, so please clarify in your question.
The first one is tricky, but I think you're looking for something like this:
SELECT * FROM products p1, products p2 GROUP BY ((p1.PRODUCT_ID*p2.PRODUCT_ID)+p1.PRODUCT_ID+p2.PRODUCT_ID)
Because it would group by rows only where the two numbers are the same, without caring about order. There might be a more elegant way to create what's basically a unique id for that combination, but I can't think of any.

Resources