Symfony2 Finding Duplicate Rows and Summing Another Column - php

I am using Symfony2 and doctrine to grab all the duplicate rows and how many times they appear. That part I have down. Now, each of these rows has a qty field as well. What I am wanting to do is run my query and show how many times the duplicate row appears as well as sum the qty field for each of these rows:
My database table looks like this:
id | sku | qty
----------------------
1 A 1
2 B 1
3 A 3
4 A 5
5 A 1
6 A 1
7 B 2
8 A 1
9 A 1
Here is my initial query that grabs all duplicate rows:
SELECT o, count(o.id) as cnt
FROM WIC\APIBundle\Entity\FBAOrderHistory o
GROUP BY o.sku HAVING cnt > 1 order by cnt desc
It outputs this:
id | sku | cnt
----------------------
1 A 7
2 B 2
But what I want is this:
id | sku | cnt | qty
----------------------
1 A 7 13
2 B 2 3
Does anyone know how to do this. Thanks so much in advance for your help!

Use SUM()
SELECT o, count(o.id) as cnt ,sum(o.qty) as
FROM WIC\APIBundle\Entity\FBAOrderHistory o
GROUP BY o.sku HAVING cnt > 1 order by cnt desc
Using DQL
Mysql Demo

Related

MySQL - Get similarity score from where two different rows meet same condition from two columns

What I want to do is generate a similarity percentage amount by comparing a ratings column from one table with the ratings column from another table.
However, this needs to be limited to instances where an id from one table matches an id in another table, is for a specific user and a rating exists in the ratings column from both tables.
For example, table1 has the following columns and data:
id | rate (out of 10)
=====================
1 | 8
2 | 10
3 | 5
4 | 4
5 | 0
6 | 9
7 | 8
And table2 has the following columns and data:
movid | userid | rating (out of 10)
================================
1 | 3 | 6
2 | 2 | 10
3 | 1 | 4
4 | 3 | 7
5 | 3 | 6
6 | 4 | 8
7 | 3 | 5
So lets say I want to use any rows where 'userid' = 3 and compare their 'rating' from table2 to the 'rate' column from table1 where 'rate' > 0 and id/movid from the two tables has the same number.
Using the example above, the results to compare should be limited to:
id | rate
=====================
1 | 8
4 | 4
7 | 8
movid | userid | rating
================================
1 | 3 | 6
4 | 3 | 7
7 | 3 | 5
Even though userid 3 had a rating for movid 5 in table2, it had a 0 rate (no rating) for id 5 in table1, so it will not compare those.
This would compare the ratings for each id/movid and then put it into an overall total. As the rating numbers are based on a score out of 10, I'm guessing the best way to determine the similarity percentage is to take the difference between each id/movid, subtract it from 10 to get the percentage number.
For id/movid 1, 'rate' in table1 is 8 and 'rating' in table2 is 6. The difference between those numbers is 2. We subtract 2 from 10, to get 80% similarity score for id/movid 1.
That would need to happen for each comparison and then total it all together.
So by my calculation, the similarity score for id/movid 1, 4 and 7 all combined would be 73% (rounded without decimals).
This total percentage amount is the end result I am trying to achieve. Can anyone help me out? I'm now bald after all of the hair I've pulled out trying to get this to work.
SELECT ROUND(SUM(10-ABS(table1.rate-table2.rating))*10/count(table1.id)) as per FROM table1 INNER JOIN table2 ON table1.id=table2.movieid WHERE userid=3 and table1.rate <> 0 GROUP BY userid
this will gives you what you need.
I suppose what you are looking for is:
SEELCT table1.id, table1.rate, table2.rating
FROM table1 INNER JOIN table2 ON table1.id=table2.movid
WHERE table1.rate>0 AND table2.userid=3
A simple INNER join plus filters in where clause to filter userid=3 and to show rates greater than zero
Following is not the best solution, but it should work:
select ROUND(sum(tmp.similarity_score)/max(tmp.cnt)) as Total_similarity_score
from
(
select t1.id,t1.rate,t2.movid,t2.rating,
(10 - abs(t1.rate-t2.rating))*10 as similarity_score,
(#cnt := #cnt +1) as cnt
from t1
inner join t2
on t2.movid = t1.id
cross join (select #cnt := 0)r
where userid = 3
and t1.rate <> 0
)tmp
;

(MySQL) Group by field and select both COUNT(field) and number of grouped rows

I have a many-to-many table with approximately this structure:
id | obj
----+---------
1 | 27
1 | 42
2 | 32
2 | 42
2 | 162
2 | 89
3 | 2
3 | 209
Essentially the table associates any number of objects (obj) with any number of collections (id).
I am trying to SELECT from this table in a way that will return the number of rows in a GROUP BY clause grouping by id, and also the number of grouped rows grouped by the number of rows in each group.
If I simply do SELECT COUNT(id) FROM table GROUP BY id, I naturally get the following:
id | COUNT(id)
----+---------
1 | 2
2 | 4
3 | 2
That is, there is one row where COUNT(id) = 4 and there are two rows where COUNT(id) = 2. So far so good. But not what I’m looking for here.
What I need is this: for each distinct value returned by COUNT(id) (2 and 4 in this case), select both COUNT(id) and the number of rows that match that value in their COUNT(id) column (in this case 2 and 1, respectively: 2 rows have COUNT(id) = 2 and 1 row has COUNT(id) = 4).
In other words, from the table above, I would want this:
id_cnt | grp_cnt
-------+---------
2 | 2
4 | 1
– since grouping the table by id, you get two rows where COUNT(id) is 2 (ids 1 and 3); and one row where COUNT(id) is 4 (id 2).
Wrack my brain as I may, though, I cannot figure out a way to do this in one single query.
The closest I’ve been able to get to something that made sense in my head was this:
SELECT COUNT(*), id_cnt FROM table JOIN (SELECT COUNT(id) id_cnt FROM table GROUP BY id) a
– but that gives:
count(*) | id_cnt
---------+---------
21100 | 2
– which I admit confuses me a bit.
Can it be done?
(I find it odd that I can’t find this question already asked—surely this must have been asked before? Perhaps I’m just wording my search queries poorly…)
You can add another level of grouping around your first grouped query.
SELECT id_cnt, COUNT(*) AS grp_cnt
FROM (
SELECT COUNT(*) AS id_cnt
FROM test.test GROUP BY id) id_cnts
GROUP BY id_cnt;
You can get the cont by id this way
select id, count(*) as ctn
from table
group by id
and the count of same count with a second level count
select ctn, count(*)
from ( select id, count(*) as ctn
from table
group by id) t
group by ctn

how to select from two table in sql

i am creating a voting application and i want to select from the database tables and display the result .1 want to get the candidate name form the first table which i call candidate.sql and then get the amout of votes from the second table called voter.
this is the candidate.sql table
id | candidate
1 |**mark**
2 |**david**
3 |**jeff**
voter.sql
voter_id | forr |user |candidate_id
1 |**mark** |tobe | 1
2 |**david** |sandra| 2
3 |**jeff** |john | 3
4 |**jeff** |steve | 3
5 |**david** |linda | 2
6 |**mark** |ken | 1
7 |**mark** |jacob | 1
My question is how do i join it so it can display like a list. e.g
mark 3
david 2
jeff 2
or is there a better way.
SELECT forr,count(*) FROM voter
GROUP BY forr
ORDER BY 2 DESC
SELECT c.candidate, count(*)
FROM candidate c
JOIN voter v ON v.forr = c.candidate
GROUP BY c.candidate
ORDER BY count(*) DESC, c.candidate ASC

SQL query to select only the maximum items?

I have this table: I want to search by UID
ID | VID | UID
1 | 1 | 5
1 | 1 | 6
1 | 2 | 6
2 | 3 | 5
2 | 3 | 6
2 | 4 | 6
I want to end up with this result:
ID | VID | UID
1 | 2 | 6
2 | 4 | 6
In other words, only select the entries where the VID is MAX of the UID but keeping in min NID could differ. Something like this I suppose:
select * from TABLE where uid = 6 and max(vid)
???
But this doesn't work?
One way is to order by the value in descending order (so the max is at the top), then just select the first result.
SELECT t.ID,
t.VID,
t.UID
FROM table t
WHERE t.ID = 1
ORDER BY t.VID DESC
LIMIT 1
Or do you mean you want all rows where t.VID is the highest value? In which case you could do something like this,
SELECT t.ID,
t.VID,
t.UID
FROM table t
WHERE t.ID = 1
AND t.VID = (SELECT MAX(VID) FROM table);
EDIT: Based on the edit to your question, it looks like you just want the max VID value for each ID? If I'm understanding you correctly, then this should give you what you need.
SELECT t.ID,
max(t.VID) as VID,
t.UID
FROM table t
WHERE t.UID = 6
GROUP BY t.ID
You need to have a subquery. This should work:
select * from TABLE where ID='1' AND VID=(select max(VID) from TABLE)
I expect your real-life example is more complicated (at least has more data).
This query will give you the row you want.
SELECT id,vid, uid
FROM TABLE
where id = 1
and vid in (select max(vid) from TABLE where id = 1)

SQL Statement, always list 3 entries of a sort

I have another Problem
I just can show you this on an example:
I got a Table called "myTable" with 7 entries
myTable | id | user_id |
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 2
9 2
10 2
Now i want to list just 3 entries of any user_id, but i cant find out myself how to.
Please help!
------- EDIT
My result have to look like this:
id=1 | user_id=1
id=2 | user_id=1
id=3 | user_id=1
id=5 | user_id=2
id=6 | user_id=2
id=7 | user_id=2
select * from table as t1
where (select count(*) from table as t2
where t1.user_id = t2.user_id and t2.id < t1.id) <3
SELECT *
FROM table
ORDER BY ...
LIMIT 3
The LIMIT clause takes two arguments: number of rows to return, and an offset if you want to display something other than the first X rows. Details here in the MySQL docs.
If you want only 3 rows, you can use limit :
select * from myTable limit 3;
SELECT * FROM table LIMIT 3
http://dev.mysql.com/doc/refman/5.0/en/select.html

Categories