Selecting conditions only when both rows (not either) are met - mysql

Parts of the table that I am looking into is as follow:
table: store_inventories
+---------+----------+-------+----------+
| stor_id | title_id | qty | minStock |
+---------+----------+-------+----------+
| 8042 | TC7777 | 630 | 630 |
| 8042 | TH1217 | 0 | 630 |
| 9012 | AK1231 | -100 | 13 |
| 9012 | AK4153 | 5 | 1 |
| 9012 | BU2075 | 39 | 7 |
| 7131 | AW1234 | 10277 | 2055 |
| 7131 | AW5678 | 13150 | 2630 |
| 7131 | BU1032 | 545 | 109 |
| 7131 | BU2075 | 35 | 7 |
How can I select title_id from this table with where conditions that will meet both (not either) stor_ids 9012 and 7131.
The result should be
+----------+
| title_id |
+----------+
| BU2075 |
I tried inner join and using and statement but they either returning wrong result or empty set.

Use WHERE clause to filter the stor_ids and HAVING to count the instances of the rows return in the WHERE clause.
SELECT title_id
FROM store_inventories
WHERE stor_ids IN (9012, 7131) --
GROUP BY title_id
HAVING COUNT(*) = 2
Use DISTINCT if there title can have multiple rows of the same store.
HAVING COUNT(DISTINCT stor_ids) = 2
Here's a Demo.

You can try with a Join of subqueries:
SELECT a.title_id
FROM (select title_id
from store_inventories
where stor_id=9012) a
JOIN (select title_id
from store_inventories
where stor_id=7131) b
ON (a.title_id=b.title_id)

Related

MYSQL Select using Left Join, Count, Group by

I have this query:
SELECT c.`id`, w.`qty`, COUNT(c.`id`) AS pieces, c.`location`
FROM `control` AS c
LEFT JOIN `warehouse` AS w ON w.`id` = c.`id`
WHERE c.`code` = '40'
GROUP BY c.`id`
I have these tables:
`control` c `warehouse` w
+----+--------+------+----------+ +------+-------+
| id | pieces | code | location | | id | qty |
+----+--------+------+----------+ +------+-------+
| 112| 112-1 | 40 | london | | 112 | 3 |
| 112| 112-2 | 40 | london | | 113 | 3 |
| 112| 112-3 | 40 | london | | 114 | 1 |
| 113| 113-1 | 40 | italy | | 115 | 1 |
| 113| 113-2 | 40 | italy | +--------------+
| 113| 113-3 | 40 | italy |
| 114| 114-1 | 41 | france |
| 115| 115-1 | 41 | france |
| 112| 112-1 | 40 | germany |
| 112| 112-2 | 40 | germany |
| 112| 112-3 | 40 | germany |
| 113| 112-1 | 40 | russia |
| 113| 112-2 | 40 | russia |
| 113| 112-3 | 40 | russia |
| 112| 112-1 | 40 | poland |
| 112| 112-2 | 40 | poland |
| 112| 112-3 | 40 | poland |
+-------------------------------+
Im getting this:
actual output
+-----+-----+--------+----------+
| id | qty | pieces | location |
+-----+-----+--------+----------+
| 112 | 3 | 9 | poland |
| 113 | 3 | 6 | russia |
+-------------------------------+
I'm trying to get this result:
desired output
+-----+-----+--------+----------+
| id | qty | pieces | location |
+-----+-----+--------+----------+
| 112 | 3 | 3 | london |
| 113 | 3 | 3 | italy |
| 112 | 3 | 3 | germany |
| 113 | 3 | 3 | russia |
| 112 | 3 | 3 | poland |
+-------------------------------+
Is possible this result? maybe tweaking my query?
I tried without GROUP BY but in that case i just get 1 row totalizing pieces.
If you want to separate the different locations to different rows, you need to add that column to the group by clause:
SELECT c.`id`, w.`qty`, COUNT(c.`id`) AS pieces, c.`location`
FROM `control` AS c
LEFT JOIN `warehouse` AS w ON w.`id` = c.`id`
WHERE c.`code` = '40'
GROUP BY c.`id`, c.`location`
-- Here ---------^
I suspect that you just need to add qty and location to the group by clause:
SELECT c.`id`, w.`qty`, COUNT(*) AS pieces, c.`location`
FROM `control` AS c
LEFT JOIN `warehouse` AS w ON w.`id` = c.`id`
WHERE c.`code` = '40'
GROUP BY c.`id`, w.`qty`, c.`location`
Starting MySQL 5.7, it is mandatory to list all-non aggregated columns in the group by clause (unless you change default sql option ONLY_FULL_GROUP_BY); most other databases also implement this constraint. I would recommend getting used to it...
Side notes:
COUNT(c.id) is better written COUNT(*), since id seems like a not nullable column
generally spearking, you shoud avoid using backticks around table and column names unless when absolutly necessary.

Mysql query not giving the two rows with max numbers

I have query :-
select
CustomerName,
Scenario,
StepNo,
InTransit,
IsAlef,
RunNo,
count(1) as Total
from RequestInfo
group by CustomerName,
Scenario,StepNo,InTransit,
IsAlef,RunNo
order by Total DESC LIMIT 1;
which gives me output :-
+--------------+-------------+--------+-----------+--------+-------+-------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | Total |
+--------------+-------------+--------+-----------+--------+-------+-------+
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
+--------------+-------------+--------+-----------+--------+-------+-------+
the actual table is :-
+--------------+-------------+--------+-----------+--------+-------+----------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | count(1) |
+--------------+-------------+--------+-----------+--------+-------+----------+
| MMT | HotelBrowse | 1 | No | No | 1 | 206 |
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
| MMT | HotelBrowse | 1 | No | No | 3 | 206 |
| YATRA | HotelBrowse | 1 | No | No | 1 | 298 |
| YATRA | HotelBrowse | 1 | No | No | 2 | 206 |
| YATRA | HotelBrowse | 1 | No | No | 3 | 147 |
+--------------+-------------+--------+-----------+--------+-------+----------+
but i want output like below:-
+--------------+-------------+--------+-----------+--------+-------+----------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | count(1) |
+--------------+-------------+--------+-----------+--------+-------+----------+
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
| YATRA | HotelBrowse | 1 | No | No | 1 | 298 |
+--------------+-------------+--------+-----------+--------+-------+----------+
The idea is to get the rows with max count numbers of the last column "Total".
Check This.
select R1.* from RequestInfo R1
inner join
(
select CustomerName,MAX( `count(1)`) `count(1)`
from RequestInfo
group by CustomerName
)R2 on R1.CustomerName=R2.CustomerName and R1.`count(1)`=R2.`count(1)`
Demo : sqlfiddle here
Please try below query
select a.* from RequestInfo a,
(select CustomerName,max(Total) as total from RequestInfo group by CustomerName ) b
where a.customername=b.customername
and a.total=b.total;
Just set your 'TOTAL DESC LIMIT' as '2'
SELECT CustomerName, Scenario,StepNo,InTransit,IsAlef,RunNo, count(1) AS
Total FROM RequestInfo GROUP BY
CustomerName, Scenario,StepNo,InTransit,IsAlef,RunNo ORDER BY Total DESC LIMIT 2;
error because count is reserved keyword in mysql so you can write between count(1) not only count without acute
your query like this
select CustomerName,Scenario,StepNo,InTransit,IsAlef,RunNo,`count(1)` as Total from customer group by CustomerName;
check here

MySQL Limit Results Based on Join Table

I have 2 tables,but linked in many to many relations so 3 tables :
Table Author :
idAuthor,
Name
+----------+-------+
| idAuthor | Name |
+----------+-------+
| 1 | Renee |
| 2 | John |
| 3 | Bob |
| 4 | Bryan |
+----------+-------+
Table Publication:
idPublication,
Title,
Type,
Date,
Journal,
Conference
+---------------+--------------+------+-------------+------------+-----------+
| idPublication | Title | Date | Type | Conference | Journal |
+---------------+--------------+------+-------------+------------+-----------+
| 1 | Flower thing | 2008 | book | NULL | NULL |
| 2 | Bees | 2009 | article | NULL | Le Monde |
| 3 | Wasps | 2010 | inproceding | KDD | NULL |
| 4 | Whales | 2010 | inproceding | DPC | NULL |
| 5 | Lyon | 2011 | article | NULL | Le Figaro |
| 6 | Plants | 2012 | book | NULL | NULL |
+---------------+--------------+------+-------------+------------+-----------+
Table author_has_publication :
Author_idAuthor,
Publication_idPublication
+-----------------+---------------------------+
| Author_idAuthor | Publication_idPublication |
+-----------------+---------------------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 1 | 5 |
| 2 | 5 |
| 3 | 5 |
| 3 | 6 |
+-----------------+---------------------------+
What I want to do is get the top X author having the most publications.
I achieved to get the result avec the idAuthor having the most publications, using this request :
SELECT Author_idAuthor, COUNT(*) as count FROM Author_has_publication GROUP BY Author_idAuthor ORDER BY count DESC;
I get the list of the authors id, ordered by the number of publications :
+-----------------+-------+
| Author_idAuthor | count |
+-----------------+-------+
| 3 | 3 |
| 2 | 2 |
| 1 | 2 |
| 4 | 1 |
+-----------------+-------+
but then when I try to select the author corresponding to the top X of the result set of the previous query I have an error
I am Trying this SELECT TOP 2 FROM author WHERE (SELECT Author_idAuthor, COUNT(*) as count FROM Author_has_publication GROUP BY Author_idAuthor ORDER BY count DESC)=idAuthor;
I think it might be because my inside query return 2 rows, and I do a simple SELECT here or that I need a JOIN but i have no ideas how to use it here.
MySQL has no TOP keyword. It does however have a LIMIT keyword. Your query is invalid anyway.
There are a couple of options here. The following is an example of a correlated subquery: https://en.wikipedia.org/wiki/Correlated_subquery
SELECT
a.idAuthor,
a.Name ,
(SELECT COUNT(*) from author_has_publication ahp WHERE
ahp.Author_idAuthor = a.idAuthor) AS publication_count
FROM
author a
ORDER BY
publication_count DESC
LIMIT 2
As the referenced article notes, the above is inefficient as the subquery needs to be re-executed for each row of the result. If you do not actually need the count in the resultset then the below would be more efficient as the subquery is non-correlated and executed only once.
SELECT
a.idAuthor,
a.Name
FROM
author a
INNER JOIN
(select ahp.Author_idAuthor AS idAuthor, COUNT(*) as publication_count
FROM author_has_publication ahp GROUP BY ahp.Author_idAuthor LIMIT 2)
AS TEMP ON TEMP.idAuthor = a.idAuthor

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.

join with count on a joined table with group clause in mysql

I have 3 tables:
applications (has many votes)
votes (belongs to applications and questions)
questions (has many votes)
I need to get number of votes per application per question.
So, my attempt was:
SELECT applications.id, COUNT(votes.id), votes.question_id
FROM applications
LEFT OUTER JOIN votes ON (votes.application_id = application.id)
GROUP BY votes.question_id
However, it displays data only for a single application, so I assume my query is malformed:
+----+-----------------+-------------+
| id | COUNT(votes.id) | question_id |
+----+-----------------+-------------+
| 1 | 1185 | 1 |
| 1 | 1170 | 2 |
| 1 | 1209 | 3 |
| 1 | 1230 | 4 |
| 1 | 1213 | 5 |
+----+-----------------+-------------+
What I need:
+----+-----------------+-------------+
| id | COUNT(votes.id) | question_id |
+----+-----------------+-------------+
| 1 | 1185 | 1 |
| 1 | 1170 | 2 |
| 1 | 1209 | 3 |
| 1 | 1230 | 4 |
| 1 | 1213 | 5 |
| 2 | null | 1 |
| 2 | 50 | 2 |
| 2 | 333 | 3 |
| 2 | 1230 | 4 |
| 2 | 1213 | 5 |
| 3 | null | 1 |
| 3 | 50 | 2 |
| 3 | 333 | 3 |
| 3 | null | 4 |
| 3 | 5555 | 5 |
+----+-----------------+-------------+
The group by clause was missing applications.id.
SELECT applications.id, COUNT(votes.id), votes.question_id
FROM applications
LEFT OUTER JOIN votes ON votes.application_id = application.id
group by applications.id, votes.question_id
You should be grouping by the applications.id as well as the questions.id:
SELECT a.id, COUNT(votes.id), votes.question_id
FROM applications a LEFT OUTER JOIN
votes v
ON v.application_id = a.id
GROUP BY a.id, v.question_id;
However, this will not produce exactly what you want. You seem to want all the questions for the applications, regardless of whether or not there are any votes. If so, this is probably what you want:
SELECT a.id, q.question_id, COUNT(v.application_id)
FROM applications a CROSS JOIN
(SELECT DISTINCT question_id FROM votes) q LEFT JOIN
votes v
ON v.application_id = a.id and v.question_id = q.question_id
GROPU BY a.id, q.question_id;