Check duplication within the same MySQL table - mysql

id district icnum
1 10 111
2 10 112
3 10 113
4 10 114
5 10 111
6 20 115
7 20 116
8 20 117
9 20 111
10 20 111
11 30 118
12 30 119
13 30 111
14 30 111
15 30 120
I have the above sample table. I want to create a mysql query to check duplication of 'icnum', a summary/count and also a list of the duplication. What
I want is:
How many 'icnum' within district '10' is found in district '20'.
How many 'icnum' within district '10' is found in district '30'.
How many 'icnum' within district '20' is found in district '30'.
I've tried several queries found in stackoverflow but it doesn't give me the result I want. I'm a newbie in complex sql query.
So should I execute the query separately for every district to get the result. Please masters of MySQL in stackoverflow, help me with this. Tq.
Below is the sample output that i want:
district district count(*)
10 20 2
10 30 2
20 30 2

You can do this using a self-join:
select t1.district, t2.district, count(distinct t1.icnum)
from t t1 join
t t2
on t1.icnum = t2.icnum and t1.district < t2.district
group by t1.district, t2.district;
Notes:
If you don't have duplicates, then use count(*) instead of count(*).
This will not return pairs that have nothing in common (although that could be fixed).

Related

Mysql select result in one currency

I have to create a reports in one currency. I need to do query in MySQL without using PHP process. but unable to figure it out.
There is a table called currency_exchange_rate table as follows, (exchange rate in LKR to other currency).this table is updating like one record for each currency in LKR in every month
exchange_rates
id currency_id start_date exchange_rate
1 5 2017-01-2 155
2 4 2017-01-3 25
3 6 2017-01-3 53
4 5 2017-02-1 156
5 4 2017-02-1 24
6 6 2017-02-1 54
There is a project table as follows
pro_id name value currency_id status_id owner_id date
1 studio1 500 5 1 44 2017-01-20
2 lotus 120 5 1 42 2017-01-21
3 auro 300 4 2 45 2017-01-21
4 studio2 400 6 1 44 2017-01-22
5 holland 450 4 3 46 2017-02-05
6 studio3 120 4 3 47 2017-02-06
7 studio4 400 6 3 48 2017-02-06
how to generate reports in one currency(DKK but exchange rate in LKR) like status wise,monthly total, total by owner, etc..
and we have to consider currency id,currency to be convert and exchange rate for the month for those currency types to get relevant value for project row.
hope you are clear about my scenario. your help is much appreciated.
I don't need every report. just want a sql for convert values in project table using exchange rates table or status wise report as follows
status_id value_in_one_currency
1 xxxx
2 xxxx
3 xxxx
Try this:
SELECT A.status_id, A.`value` * B.exchange_rate `value_in_one_currency`
FROM project A JOIN exchange_rates B
ON A.currency_id=C.currency_id
AND DATE_FORMAT(A.`date`,'%m-%Y')=DATE_FORMAT(B.`start_date`,'%m-%Y');
See MySQL Join Made Easy for some insight.
This is what I finalize:
I took currency_id=5 as the final currency to be converted
SELECT A.*,C.exchange_rate AS DKK,D.exchange_rate AS LKR, (order_value * D.exchange_rate /C.exchange_rate ) AS `converted_value`
FROM projects A
LEFT JOIN exchange_rates C ON (DATE_FORMAT(C.start_date,'%Y-%m')=DATE_FORMAT(A.`date`,'%Y-%m') AND C.currency_id=5)
LEFT JOIN exchange_rates D ON DATE_FORMAT(D.start_date,'%Y-%m')=DATE_FORMAT(A.`date`,'%Y-%m') AND D.currency_id=A.currency_id

retrieve all rows from the table grouped by condition

I have the following mysql table:
products
with a fileds:
id, product_group_id, internal_product_id, version, platform_id, name
1 12 12 1 30 Megacalculator
2 12 12 2 30 Megacalculator
3 16 17 1 30 Calculator
4 16 17 2 30 Calculator
5 16 18 0.1 40 Calculator Linux
6 20 19 2.1 30 Converter Windows
7 20 20 2.1 40 Converter Linux
8 30 24 0.1 30 Editor
I need to retrieve all rows from this table grouped by 'product_group_id' but with a different 'internal_product_id' inside of the group. Also, the rows count in each group must be equal to some special number(the value must be supplied into the query as an external parameter)
For example:
external parameter = 2, result:
product_group_id
16
20
external parameter = 1, result:
product_group_id
12
30
Please help me with this sql query.
Try that:
for parameter = 2
select `product_group_id` from products
group by `product_group_id`
having count(distinct `internal_product_id`) = 2
for parameter = 1
select `product_group_id` from products
group by `product_group_id`
having count(distinct `internal_product_id`) = 1
DEMO HERE
You can do this:
select product_group_id from products
group by product_group_id;
having count(internal_product_id) = 2;
Or you can get the information in a table:
select product_group_id, count(internal_product_id) from products
group by product_group_id;

Find repeated battles

I have one table with the following fields:
battle_id, winner, looser
1 200 44
2 55 366
3 44 200
4 123 200
5 200 44
6 55 366
7 177 205
8 188 211
9 366 55
10 55 366
right now it has about 1300 records (its small), and there are about 400 players, in each battle there can only be a winner and a looser (there are no draws)
how can i find all the repeated battles? i do not want to find all the repeated battles of one player, i do want to know all the repeated battles of all the players...i know that i cam make a recursive function in php that iterates over all the battles and assign them to a matrix, but just for fun...is there a way to do it only on mysql?
And how can i optimize the table to find the repeated battles more quickly?
regards
EDIT:
For example i want the query to show:
battle_id, winner, looser
1 200 44
2 55 366
3 44 200
5 200 44
6 55 366
9 366 55
10 55 366
This should work, using a self-join could result in many duplicated entries
SQLFIDDLE
SELECT
t1.battle_id,
t1.winner,
t1.loser
FROM
your_table t1
WHERE
EXISTS (
SELECT
1
FROM
your_table t2
WHERE
( ( t1.winner = t2.winner
AND t1.loser = t2.loser )
OR ( t1.loser = t2.winner
AND t1.winner = t2.loser ) )
AND t1.battle_id <> t2.battle_id
)
try this:
SELECT b1.battle_id,
b1.winner,
b1.looser
FROM battles as b1
group by b1.battle_id, b1.winner, b1.looser
having count(*)>=2

MySQL Select Last n Rows For List of ID'S

Fixture Table
uid home_uid away_uid winner date season_division_uid
1 26 6 6 2013-07-30 18
2 8 21 8 2013-06-30 18
3 6 8 8 2013-06-29 18
4 21 26 21 2013-05-20 18
5 6 26 6 2013-04-19 18
This table contains hundreds of rows.
Currently I have a query to select all the teams in a division, i.e.
SELECT team_uid
FROM Season_Division_Team
WHERE season_division_uid='18'
which lists the rows of team uid's i.e. [6,26,8,21,26].
Now for each of the unique team ids, I would like to return the last 3 winner values, ordered by the date column, that they were involved in (they could be an away_uid or home_uid).
So the returned value example would be:
team_id winner date
6 6 2013-07-30
6 8 2013-06-29
6 26 2013-04-19
26 6 2013-07-30
26 21 2013-05-20
26 6 2013-04-19
Any ideas? Thank you
Im not sure how to get it direct, a query like
select * from Season_division_Team where
`date >= (select min(`date`) from
(select `date` from season_division_team order by date desc limit 3))
and (home_uid = 6 or away_uid = 6)
Thats not going to be a good query. But only way i can think of currently
Its hard to get the 3rd largest value from SQL Example
the sub query is trying to get the date where the last win occured, and then getting all dates after that where the team played.
EDIT:
SELECT * FROM Season_Division_Team WHERE winner = 6 ORDER BY `date` DESC LIMIT 3
that sounds more like your latter comment

MSSQL Select Top 10 winning scores, including Ties and at least one from each category

I got some help finding the top 10 scores, including tied entries, using the following statement
select T.EntryID, T.CategoryID, T.Score
from (
select EntryID, CategoryID, Score,
dense_rank() over(order by Score) as rn
from YourTable
) T
where T.rn <= 10
(thanks [mikael-eriksson]: https://stackoverflow.com/users/569436/mikael-eriksson)
[question]: MSSQL Selecting top 10 but include columns with duplicate values Here is sample data:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3220 1 65
3080 1 65
3168 1 64
______________________
Total Entries >= 18
There is a requirement that there be at least one entry from each category in the top 10 (or top whatever it may be i.e. top 100), in this case there are 3 Categories.
Now all I need to do is to include at least one entry per category in the top 10. i.e. if all the top 10 scores are from Category 1, and there are 3 categories, I need to drop the 2 lowest scores from Category 1 and include the highest score entry for both Category 2 and 3.
As you can see from the results all the entries are from Category 1, so I need to drop EntryID's 3220, 3080 and 3168 from the resultset as they are the lowest scored, and include the highest scoring entry in Category 2 as well as the highest scoring entry in Category 3 so that the result looks something like this:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3019 3 60
3800 2 54
______________________
Total Entries >= 17
Same thing goes for the following scenario, let's look at the top 5 instead of top 10 to make it a little easier on the eye, as you can see in this example the Top 5 scores exclude entries from Category 2
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
In this case entries 3225 and 3045 needs to drop as they are the lowest scored entries (3047 needs to be included as even though it's the lowest scored entry I need an entry from all categories in the result) and I need to include the highest scored entry from Category 2, I would expect something like this:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3019 3 60
3800 2 54
______________________
Total Entries >= 6
And then there may be the scenario where there may not be an entry into a specific category, let say for example no Category 2 entries so the result should still have the top 5 as with the original result set for the top 5 above (included below as reference)
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
Please excuse if I'm repeating myself, I'm just trying to make it clear to understand ;)
I really Appreciate the help!
As I can see it, you need to rank your rows in a more sophisticated way, so that entries that are the top ones in every category are included regardless of their values, and entries that are not the top ones are included according to their overall rankings.
What I'm about to suggest may not be the most efficient solution, but it should work and, if nothing else can, might inspire someone else to come up with something better:
WITH ranked1 AS (
SELECT
*,
RankByCategory = DENSE_RANK() OVER (
PARTITION BY CategoryID
ORDER BY Score DESC
)
FROM YourTable
),
ranked2 AS (
SELECT
*,
FinalRank = DENSE_RANK() OVER (
ORDER BY
CASE RankByCategory WHEN 1 THEN 1 ELSE 2 END,
Score DESC
)
FROM ranked1
)
SELECT
EntryID,
CategoryID,
Score
FROM ranked2
WHERE FinalRank <= #top_n
;
The first CTE is ranking rows by categories, thus letting us find out which entries become the top ones in their respective categories. The next step (second CTE) is about obtaining global rankings, this time taking into account whether an entry is the top one in its category or not. The category top values receive lower rankings and thus are ensured to be included in the final results. (Of course, you need to make sure that the number of categories is not greater than the number of distinct values you want to receive in the output.)
Here's a live example at SQL Fiddle to play with.