mysql select where values are repeated - mysql

My table is similar to the one below. I would like to select records where city and town matches and code or area has repetition. In this case rows the result should be all rows except the ones with id 3 and 5. Thanks for looking at this
city town id code1 code2 code3 code4 area1 area2 area3 area4
----------------------------------------------------------------------------------
dublin town1 1 1 2 3 5 1 2 3 4
dublin town1 2 2 8 10 6 7 8 9
dublin town1 3 12 13 15 11 12 13 14
dublin town2 4 1 2 3 5 1 2 3 4
dublin town2 5 6 7 8 10 6 7 8 9
dublin town2 6 11 12 13 15 1 12 13 14
http://sqlfiddle.com/#!2/0bbe7/1/0

Using INNER JOIN,
select a.*
from bigcities a inner join bigcities b
on a.city = b.city
and a.town = b.town
and a.id != b.id
and (a.code1 = b.code1
or a.code2 = b.code2
or a.code3 = b.code3
or a.code4 = b.code4
or a.area1 = b.area1
or a.area2 = b.area2
or a.area3 = b.area3
or a.area4 = b.area4
);
Demo.

This is pretty much what the exists clause can do. Here is a solution for your conditions:
select t.*
from <table> t
where exists (select 1
from <table> t2
where t2.city = t.city and
t2.town = t.town and
t2.id <> t.id and
(t2.code1 = t.code1 or t2.code2 = t.code2 or t2.code3 = t.code3 or t2.code4 = t.code4 or
t2.area1 = t.area1 or t2.area2 = t.area2 or t2.area3 = t.area3 or t2.area4 = t.area4
)

You can do it with the following query
--We do a query to the table to get the rows and then we do a subquery
--to get all the rows with the same criteria. We know it is repeated
--because the counter of rows > 1.
--If you want to get only where it is repeated 2 o 3, etc, you only need to change
--the COUNT() > 1
SELECT *
FROM tableName t
WHERE (
SELECT COUNT(*) FROM tableName tRep WHERE
t.city = tRep.city AND
t.town = tRep.town AND
((t.code1 = tRep.code1 AND t.code2 = tRep.code2 AND t.code3 = tRep.code3 AND t.code4 = tRep.code4) OR
(t.area1 = tRep.area1 AND t.area2 = tRep.area2 AND t.area3 = tRep.area3 AND t.area4 = tRep.area4))
) > 1

Related

MySQL group by hour epoch time

So this is to show how many connection my platform had in a period in range of hour.
Where I comment "variable" it's what will be received from the front end, this query will run in the backend to populate a chart.
SELECT
count(server_events.event_type),
server_events.time_stamp,
hotspots.partner_id,
hotspots.partner,
hotspots.operator_id
FROM
`msp-data`.server_events
INNER JOIN
`adserver`.hotspots, `adserver`.operator
WHERE
server_events.time_stamp between "1591930800" and "1592017199" -- variable
and server_events.event_type = "auth_final"
and server_events.nas_id = adserver.hotspots.code
and hotspots.partner_id = "1" -- variable
and hotspots.operator_id = "2" -- variable
GROUP BY
server_events.time_stamp div 3600
ORDER BY
server_events.time_stamp
This is my current output
I posted the full query, but in this output I didn't get partner and filters of partner_id or operator_id
count time_stamp partner_id operator_id
6 1591944931 1 1
12 1591945711 1 5
6 1591952103 1 1
36 1591952621 1 1
18 1591956063 1 1
12 1591962118 1 4
6 1591966538 1 1
6 1591968554 1 1
12 1591973267 1 5
18 1591976918 1 1
18 1591978620 1 5
12 1591983139 1 5
12 1591984830 1 1
24 1591989873 1 1
12 1591993080 1 1
30 1591995612 1 1
output
Expected output would be
10 1591930800-1591934399
15 1591934400-1591937999
Try executing below. And try considering Strawberry's advice.
SELECT SUM(CNT), TM FROM(SELECT DISTINCT
count(server_events.event_type) OVER(PARTITION BY hotspots.partner_id,hotspots.partner,hotspots.operator_id,server_events.time_stamp/3600) CNT
server_events.time_stamp/3600 TM
FROM
`msp-data`.server_events
INNER JOIN
`adserver`.hotspots, `adserver`.operator
WHERE
server_events.time_stamp between "1591930800" and "1592017199" -- variable
and server_events.event_type = "auth_final"
and server_events.nas_id = adserver.hotspots.code
and hotspots.partner_id = "1" -- variable
and hotspots.operator_id = "2" -- variable
)
GROUP BY TM
ORDER BY
2
Under Mysql Version 12
SELECT SUM(CNT), TM FROM(SELECT
count(A.event_type) cnt,
hotspots.partner_id,hotspots.partner,hotspots.operator_id,tm
FROM
(SELECT A.time_stamp/3600 AS TM,A.* FROM `msp-data`.server_events A ) A
INNER JOIN
`adserver`.hotspots, `adserver`.operator
WHERE
A.time_stamp between "1591930800" and "1592017199" -- variable
and A.event_type = "auth_final"
and A.nas_id = adserver.hotspots.code
and hotspots.partner_id = "1" -- variable
and hotspots.operator_id = "2" -- variable
group by hotspots.partner_id,hotspots.partner,hotspots.operator_id,TM
) aliaz
GROUP BY TM
ORDER BY
2
#ismetguzelgun
SELECT SUM(CNT), TM FROM(SELECT
count(A.event_type) cnt,
hotspots.partner_id,
hotspots.partner,
hotspots.operator_id,
TM
FROM
(SELECT
A.time_stamp/3600 AS TM,
A.* FROM `msp-data`.server_events A
) A
INNER JOIN
`adserver`.hotspots,
`adserver`.operator
WHERE
A.time_stamp between "1591930800" and "1592017199" -- variable
and A.event_type = "auth_final"
and A.nas_id = adserver.hotspots.code
-- and hotspots.partner_id = "1" -- variable
-- and hotspots.operator_id = "2" -- variable
GROUP BY
hotspots.partner_id,
hotspots.partner,
hotspots.operator_id,
TM
) B
GROUP BY TM
ORDER BY
2
Gave this output now:
SUM(CNT) TM
6 442206.9253
6 442207.1419
6 442207.9306
6 442208.9175
6 442209.0614
6 442209.2531
6 442209.3533
6 442209.4050
6 442209.4150
6 442209.4969
6 442210.0175
6 442210.1089
6 442210.4747
6 442211.6994
6 442211.7619
6 442212.9272
6 442213.4872
6 442214.0711
6 442214.7964
6 442215.4461
6 442215.5736
6 442215.8106
6 442216.2833
6 442216.2908
6 442216.7419
6 442217.5386
6 442217.6267
6 442218.0083
6 442218.3764
6 442219.4092
6 442219.6553
6 442219.8953
6 442219.9933
6 442220.3000
6 442220.9611
6 442221.0033
6 442221.0297
6 442221.6656
6 442221.7533
6 442221.7897

Horizontal group by in SQL

SELECT status
, COUNT(*) total
, COUNT(s.group_id) totalByGrp
, s.group_id Groupe
FROM server s
, status st
WHERE s.id = st.server_id
AND st.created = (SELECT MAX(ss.created)
FROM status ss
WHERE ss.server_id = s.id)
GROUP
BY st.status
, s.group_id
this query return this table
status total totalByGrp Groupe
canc 3 3 10
canc 2 2 11
inst 1 1 10
inst 2 2 11
new 2 2 10
prod 1 1 10
prod 2 2 11
i want group by GROUP(Horizontal nit vertical like table above) return the table like :
status total Grp_10 Grp_11
canc 5 3 2
inst 3 1 2
new 2 2 0
prod 3 1 2
ret 4 2 2
toRet 2 2 0
There is no easy way to do this in Mysql query. you will have to use case statement and manually convert the rows in to columns. Still you will have to know all possible combinations
select sum(case when Groupe = 10 then Groupe else 0 end ) as Grp_10,
...
...
from ...
Otherwise you may export the results to a CSV and do the necessary pivoting in spreadsheet software like excel

MySQL combining multiple rows into one row

I've two tables as below:
1. tbl_student:
id name
1 raj
2 raja
3 raju
4 rajan
tbl_attendance
id student_id month attended_days
1 1 1 6
2 1 2 16
3 8 1 8
4 7 2 14
5 8 2 13
6 7 1 11
I need to join these two tables combining multiple rows for each month for each student from tbl_attendance into a single row to obtain a result like this:
id name month attended_days month attended_days
1 raj 1 6 2 16
7 raja 1 11 2 14
8 rajan 1 8 2 13
Thanks in advance for any help.
Instead of displaying month value in each of the records,
you can use them as column headers and attendance as their value.
Use pivot type solution to achieve required solution.
Example:
select s.id as student_id
, s.name as student_name
, max( case when a.month = 1 then a.attended_days else null end ) as month_1
, max( case when a.month = 2 then a.attended_days else null end ) as month_2
, max( case when a.month = 3 then a.attended_days else null end ) as month_3
-- ...
, max( case when a.month = 12 then a.attended_days else null end ) as month_12
from table_student s
left join table_attendance a on s.id = a.student_id
group by s.id, s.name
Your question is not very complete, but i think you want something like this:
select s.*,
coalesce(a1.month, a2.month, a3.month) as month,
coalesce(a1.attended_days , a2.attended_days , a3.attended_days ) as attended_days
from table_student s
left join table_attendance a1 on s.id = a1.student_id and a1.month = 1
left join table_attendance a2 on s.id = a2.student_id and a2.month = 2
left join table_attendance a3 on s.id = a3.student_id and a3.month = 3
The previous code is used if you want to show all months in one column. For multiple columns, you can use this example:
select s.*,
a1.month as month_1,
a2.month as month_2,
a3.month as month_3,
a1.attended_days as attended_days_1,
a2.attended_days as attended_days_2,
a3.attended_days as attended_days_3
from table_student s
left join table_attendance a1 on s.id = a1.student_id and a1.month = 1
left join table_attendance a2 on s.id = a2.student_id and a2.month = 2
left join table_attendance a3 on s.id = a3.student_id and a3.month = 3
Do this for all the 12 months. I used 3 as example.

Mysql get count of unique id that repeat in database

let say I have the following table:
#hotel_id #room_id #price
3 4 50.00
3 5 45.00
3 6 50.00
4 5 45.00
4 7 50.00
4 8 45.00
5 4 45.00
5 8 50.00
5 9 45.00
what query must I execute in order to get the number of unique #hotel_id - in this case it is 3,4,5 = 3 unique ids
May sound simple , but... :) thank you in advance
########### my query
select
Count(Distinct a.id),
rta.room_type_id,
IF(SUM(price = 0), 0, SUM(price))
from
adverts a,
rooms_to_adverts rta,
room_types rt,
prices_adverts pa
where
a.town = 'Sofia' and a.id = pa.advert_id
and rta.room_type_id = rt.id
and pa.room_type_id = rta.room_type_id
and rta.advert_id = a.id
and (pa.date >= '2013-09-20'
AND pa.date < '2013-09-23')
and rt.occupants >= '1'
GROUP BY a.id , rta.room_type_id
order by a.id , rt.occupants ASC
this query ouputs this
LOOKS like it is not so simple :)
Part of what you already have is the answer:
SELECT
COUNT(DISTINCT adverts.id)
FROM adverts
Or is there a complication that you haven't told us about?

Inner join on a distinct set of parameters

I've tried a few of the similar SO questions, but I can't seem to figure it out.
On the first inner join, I only want to bring in DISTINCT function columns code and serial_id. So when I do my SUM selects, it calculates one per distinct. Ie there are multiple rows with the same func.code and func.serial_id. I only want 1 of them.
SELECT
sl.imp_id,
lat.version,
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN functions func ON sl.id = func.slot_id
INNER JOIN latest_status lat ON lat.code = func.code
AND lat.serial_id = func.serial_id
WHERE sl.id=55
GROUP BY sl.imp_id, lat.version
EDIT 2 - sample data explanation -------------------
slots - id, imp_id, name
functions - id, slot_id, code, serial_id
latest_status - id, code, serial_id, version, status
**slots**
id imp_id name
1 5 'the name'
2 5 'another name'
3 5 'name!'
4 5 'name!!'
5 5 'name!!!'
6 5 'testing'
7 5 'hi'
8 5 'test'
**functions**
id slot_id code serial_id
1 1 11HRK 10
2 2 22RMJ 11
3 3 26OLL 01
4 4 22RMJ 00
6 6 11HRK 10
7 7 11HRK 10
8 8 22RMJ 00
**latest_status**
id code serial_id version status
1 11HRK 10 1 F
1 11HRK 10 2 P
3 22RMJ 11 1 P
4 22RMJ 11 2 F
5 26OLL 01 1 F
6 26OLL 01 2 P
7 22RMJ 00 1 F
8 22RMJ 00 2 F
After running the query, the result should look like this:
imp_id version powered functional
5 1 1 3
5 2 2 2
The function table gets rolled up based on the code, serial_id. 1 row per code, serial_id.
It then gets joined onto the latest_status table based on the serial_id and code, which is a one (functions) to many (latest_status) relationship, so two rows come out of this, one for each version.
How about using DISTINCT?
SELECT
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN (Select DISTINCT id1, code, serial_id from functions) f On sl.rid = f.id1
INNER JOIN latest_status lat ON lat.code = f.code
AND lat.serial_id = f.serial_id
WHERE sl.id=55
GROUP BY sl.imp_id, lat.version
If you want only the distinct code and serial_id, you need to group by those not the imp_id and version. And end up with something like
SELECT
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN functions func ON sl.rid = func.id1
INNER JOIN latest_status lat ON lat.code = func.code
AND lat.serial_id = func.serial_id
WHERE sl.id=55
GROUP BY func.code, func.serial_id
However, this could all be rubish, without more data as tgo what some of those other columns are, but they dont seem to be the ones you wanted to group by.