Get all records of n groups - mysql

I have a table with multiple Paths of shares i want the get all the paths where the first N different Servernames in these Paths as example here the whole table.
+----+--------------------------------+
| ID | BACKUPPATH |
+----+--------------------------------+
| 1 | //server.domain/share/folder |
| 2 | //server.domain/share/folder3 |
| 3 | //server.domain/share/folder2 |
| 4 | //server2.domain/share/folder1 |
| 5 | //server2.domain/share/folder2 |
| 6 | //server3.domain/share/folder1 |
| 7 | //server3.domain/share/folder2 |
| 8 | //server3.domain/share/folder3 |
+----+--------------------------------+
the Servernames could vary each time and the number the different Servenames could vary too. As example i want to get all Paths of the first 2 different Servernames i expect as Result:
+----+--------------------------------+
| ID | BACKUPPATH |
+----+--------------------------------+
| 1 | //server.domain/share/folder |
| 2 | //server.domain/share/folder3 |
| 3 | //server.domain/share/folder2 |
| 4 | //server2.domain/share/folder1 |
| 5 | //server2.domain/share/folder2 |
+----+--------------------------------+
as subquery i use the following query to get rowset of the Servernames:
select SUBSTRING_INDEX(BACKUPPATH,'/',3) as SERVERNAMES from(select BACKUPPATH from Backuppaths GROUP BY SUBSTRING_INDEX(BACKUPPATH,'/',3))as NUMEROFSERVERS LIMIT 2;
+------------------+
| SERVERNAMES |
+------------------+
| //server.domain |
| //server2.domain |
+------------------+
i am stuck now in how to use this subquery to get the results i expect.
Thanks for any help in this

You can join to inline view:
select s.*
from servernames s
join (select substring_index(backuppath, '/', 3) as servername
from servernames
group by servername
order by min(id) limit 2) v
on substring_index(backuppath, '/', 3) = v.servername
order by id
Fiddle: http://sqlfiddle.com/#!2/b6a16/1/0

Use Distinct
SELECT DISTINCT SUBSTRING_INDEX(BACKUPPATH,'/',3) AS SERVERNAMES FROM Backuppaths LIMIT 2;

Related

How to select the first match of a group of conditions in MySQL

I have a table like this:
MyTable
-------------------------------
| ID | from | to |
-------------------------------
| 1 | U_002 | C_005 |
| 2 | U_015 | C_004 |
| 3 | C_005 | U_011 |
| 4 | U_008 | C_001 |
| 5 | U_007 | C_005 |
| 6 | U_001 | C_005 |
| 7 | C_004 | U_015 |
| 8 | U_002 | C_002 |
| 9 | U_001 | C_009 |
| 10 | U_010 | C_005 |
| 11 | C_005 | U_001 |
| 12 | U_004 | C_003 |
| 13 | U_005 | C_005 |
| 14 | U_010 | C_001 |
| 15 | C_005 | U_001 |
-------------------------------
ID, is the Unique Incremental Key of the table.
The goal is:
By giving a value (for example: C_005, U_001, C_010, etc..) Obtain the first match of this two conditions: ((from == value) || (to == value)) starting from higher ID.
This means, that data can be "duplicate", but I only wants the first result of the group.
For example, C_004 and U_015, have TWO entries (C_004 -> U_015 and U_015 -> C_004). This should return only ONE.
Since we want to start from higher Id, that mean that it would return only 7 | C_004 | U_015.
Let's put an example:
Value = C_005
The expected output is:
15 | C_005 | U_001
13 | U_005 | C_005
10 | U_010 | C_005
5 | U_007 | C_005
3 | C_005 | U_011
1 | U_002 | C_005
The idea, is to get the ""last"" (because we are starting from higher Id) coincidence of TWO values.
As I have said, two values can have multiple coincidences, but I only want to get the "last" one (Higher Id).
use max()
select max(id) id,`from`,`to`
from table_name
group by `from`,`to`
Your data is messed up because you have duplicates and potentially cycles too. Arrggh. You should fix the data.
But you can still do what you want with a recursive CTE:
with recursive cte as (
select id, f, t, 1 as lev, cast(t as char(1000)) as visited
from t
where f in ('C_005') /*, 'U_001', 'C_010') */
union all
select t.id, t.f, t.t, lev + 1, concat_ws(',', cte.visited, t.f)
from cte join
t
on cte.f = t.t
where cte.visited not like concat('%', t.f, '%')
)
select distinct id, f, t
from cte
order by id desc;
Here is a db<>fiddle.

COUNT with multiple table query where I've got to display COUNT results

How do I solve this one? None of my queries works and I've tried few.
I've got to return details of two doctors who ordered the most analysis including the number of analysis they have ordered. That last part of the sentence is what really drives me mad.
To work with I've got these two tables:
mysql> select * from DOCTORES;
+-----------+---------------------------+--------------+-----------+
| DNI_DOC | NOMBRE_DOC | ESPECIALIDAD | TELEFONO |
+-----------+---------------------------+--------------+-----------+
| 22888444O | MATEO DÍAZ, RAMÓN | 3 | 659876457 |
| 22909456Y | HERAS PRADO, ANTONIA | 1 | 676234598 |
| 23456398F | GÓMEZ DAVID, ADRIÁN | 1 | 646768454 |
| 25349857H | BURGOS CASA, CANDY | 2 | 659758476 |
| 55776898K | RAMÓN CORONADO,LUIS | 3 | 654364736 |
| 78988484B | CONRADO ALONSO, JOSE | 2 | 645878745 |
| 88647389P | DOMÍNGUEZ GÓMEZ, MANUEL | 1 | 623787343 |
+-----------+---------------------------+--------------+-----------+
and:
mysql> select * from PETICIONES;
+--------+------------+--------+-----------+-----------+
| ID_PET | FECHA_PET | ID_ANA | DNI_PAC | DNI_DOC |
+--------+------------+--------+-----------+-----------+
| 1 | 2008-01-03 | 2 | 71515623A | 23456398F |
| 2 | 2008-05-10 | 2 | 33788976F | 55776898K |
| 3 | 2008-05-08 | 3 | 79876867X | 23456398F |
| 4 | 2008-05-11 | 4 | 44787345H | 55776898K |
| 5 | 2008-05-12 | 2 | 19887234W | 25349857H |
| 6 | 2008-05-05 | 4 | 22897576R | 55776898K |
| 7 | 2008-03-15 | 5 | 44787345H | 88647389P |
| 8 | 2008-03-19 | 1 | 71515623A | 23456398F |
| 9 | 2008-03-26 | 2 | 71515623A | 78988484B |
| 10 | 2008-03-15 | 2 | 19887234W | 88647389P |
| 11 | 2008-03-15 | 3 | 33788976F | 55776898K |
| 12 | 2008-03-26 | 2 | 44787345H | 23456398F |
+--------+------------+--------+-----------+-----------+
I tried this:
select
NOMBRE_DOC
from
DOCTORES
where
DNI_DOC IN (select DNI_DOC
from PETICIONES
group by ID_ANA
order by count(*) desc
limit 2)
group by
DNI_DOC;
and that:
SELECT
DNI_DOC, ID_ANA, COUNT(ID_ANA) AS count
FROM
TIPOS_ANALISIS
WHERE
ID_ANA = (SELECT ID_ANA
FROM
(SELECT
ID_ANA, COUNT(ID_ANA) as AnaCount
FROM
PETICIONES
GROUP BY
by ID_ANA
ORDER BY
AnaCount DESC
LIMIT 1) t1)
GROUP
BY ID_ANA;
and that:
select a.* from DOCTORES a
-> where a.DNI_DOC = ( SELECT b.DNI_DOC from PETICIONES b
-> group by d.ID_ANA
-> order by count(ID_ANA) DESC
-> limit 2 );
you can't even imagine how frustrating it is when you say it's a simple query... Why it isn't simple to me is a mystery (provided that I am really not a dummy).
Expected output would be something like this:
+-----------+---------------------------+--------------+-----------+
| DNI_DOC | NOMBRE_DOC | ID_ANA | count |
+-----------+---------------------------+--------------+-----------+
| 22888444O | MATEO DÍAZ, RAMÓN | 3 | 6 |
+-----------+---------------------------+--------------+-----------+
I believe you are severely overcomplicating this. Join the 2 tables on DNI_DOC field, group by the doctor's id and name (and any other details you may want to include in the select list), and count the number of distinct ID_ANAs.
SELECT d.DNI_DOC, d.NOMBRE_DOC, COUNT(distinct ID_ANA) AS count
FROM DOCTORES d
INNER JOIN PETICIONES t ON d.DNI_DOC=t.DNI_DOC
GROUP BY d.DNI_DOC, d.NOMBRE_DOC
ORDER BY COUNT(distinct ID_ANA) DESC
LIMIT 2
If you need the total number of peticiones per doctor, then remove the distinct from the count.
Here is what I would do :
select d.*, count(p.ID_PET) as TOTAL_PETICIONES from DOCTORES d
inner join PETICIONES p on p.DNI_DOC = d.DNI_DOC
group by d.DNI_DOC
order by count(ID_ANA) DESC
limit 2
This is not tested and write here so please correct me for typos ;)
Using a join will provide a nice output. Grouping by DOCTORES to be able to count the PETICIONES per DOCtORES
EDIT : Something like that. The output won't be good because I have issues to understand the column content.

SUM of Column where Multiple Rows Have Same Value

I am trying to get the sum of a single column from all rows that share similar data. For example, given the following data:
|ppID | cID | Count | NameSpace|
|-----|-------|-------|----------|
|586 | 18281 | 1 | LAB |
|587 | 18269 | 1 | LAB |
|588 | 18281 | 1 | LAB |
|589 | 17823 | 1 | IPB |
|590 | 18281 | 1 | LAB |
|591 | 18256 | 1 | LAB |
|592 | 18256 | 1 | LAB |
|593 | 18269 | 1 | IPB |
|-----|-------|-------|----------|
I'm hoping to get:
|ppID | cID | Count | NameSpace|
|-----|-------|-------|----------|
|586 | 18281 | 3 | LAB |
|587 | 18269 | 1 | LAB |
|589 | 17823 | 1 | IPB |
|591 | 18256 | 2 | LAB |
|593 | 18269 | 1 | IPB |
|-----|-------|-------|----------|
I've pieced together a couple of different things and come up with `
SELECT * FROM PopularPages
WHERE cID IN (SELECT cID FROM PopularPages
GROUP BY cID
HAVING COUNT(cID) > 1)
ORDER BY cID, Namespace
which will list out each of the rows but without counting up the sum of the Count column. Any help would be appreciated.
is this what you want ?
SELECT
MIN(ppID) as ppID,
cID,
SUM(`Count`) as COUNT,
NameSpace
FROM PopularPages
GROUP BY cID
HAVING Count > 1;

mysql: order -> limit -> sum... possible?

i am loosing it over the following problem:
i have a table with participants and points. each participant can have up to 11 point entries of which i only want the sum of the top 6.
in this example lets say we want the top 2 of 3
+----+---------------+--------+
| id | participantid | points |
+----+---------------+--------+
| 1 | 1 | 11 |
+----+---------------+--------+
| 2 | 3 | 1 |
+----+---------------+--------+
| 3 | 3 | 4 |
+----+---------------+--------+
| 4 | 2 | 3 |
+----+---------------+--------+
| 5 | 1 | 5 |
+----+---------------+--------+
| 6 | 2 | 10 |
+----+---------------+--------+
| 7 | 2 | 9 |
+----+---------------+--------+
| 8 | 1 | 3 |
+----+---------------+--------+
| 9 | 3 | 4 |
+----+---------------+--------+
as a result i want something like
+---------------+--------+
| participantid | points |
+---------------+--------+
| 2 | 19 |
+---------------+--------+
| 1 | 16 |
+---------------+--------+
| 3 | 8 |
+---------------+--------+
(it should be ordered DESC by the resulting points)
is this at all possible with mysql? in one query?
oh and the resulting participant ids should be resolved into the real names from another 'partcipant' table where
+----+------+
| id | name |
+----+------+
| 1 | what |
+----+------+
| 2 | ev |
+----+------+
| 3 | er |
+----+------+
but that should be doable with a join at some point... i know...
Using one of the answers from ROW_NUMBER() in MySQL for row counts, and then modifying to get the top.
SELECT ParticipantId, SUM(Points)
FROM
(
SELECT a.participantid, a.points, a.id, count(*) as row_number
FROM scores a
JOIN scores b ON a.participantid = b.participantid AND cast(concat(a.points,'.', a.id) as decimal) <= cast(concat(b.points,'.', b.id) as decimal)
GROUP BY a.participantid, a.points, a.id
) C
WHERE row_number IN (1,2)
GROUP BY ParticipantId
Had an issue with ties until I arbitrarily broke them with the id

COUNT reducing results?

A query without COUNT returns 3 records, with only 1.
SELECT `blog_cate` . * , COUNT( blogi.blog_cate ) AS num
FROM (
`blog_cate`
)
JOIN `blogi` ON `blogi`.`blog_cate` = `blog_cate`.`blogi_cate_url`
results:
+----+------------------+----------------+-----+
| id | blogi_cate_title | blogi_cate_url | num |
+----+------------------+----------------+-----+
| 1 | Базы данных | batabase | 3 |
+----+------------------+----------------+-----+
And the same query, but without a COUNT:
SELECT `blog_cate` . *
FROM (
`blog_cate`
)
JOIN `blogi` ON `blogi`.`blog_cate` = `blog_cate`.`blogi_cate_url`
That returns me 3 records:
+----+------------------+----------------+
| id | blogi_cate_title | blogi_cate_url |
+----+------------------+----------------+
| 1 | Базы данных | batabase |
| 1 | Базы данных | batabase |
| 3 | Разработка | razrabotka |
+----+------------------+----------------+
Is it possible to use a COUNT and have a normal results?
p.s. tables:
+----+------------+
| id | blog_cate |
+----+------------+
| 1 | batabase |
| 2 | batabase |
| 3 | razrabotka |
+----+------------+
+----+------------------+----------------+
| id | blogi_cate_title | blogi_cate_url |
+----+------------------+----------------+
| 1 | Базы данных | batabase |
| 2 | PHP | php |
| 3 | Разработка | razrabotka |
+----+------------------+----------------+
COUNT() with out a group by will group all records and produce a count of them. Adding more fields to the select will only show the details of the first record
You could build one query to get the three rows and one query to get the count result and join them via cross join to combine every detail row with the count row.