Can I make one query with this two conditions? And if yes, which way should I dig?
SELECT c.ID, c.DateEnd FROM conference c WHERE DateEnd = DATE_ADD(CURDATE(),INTERVAL 1 DAY)
SELECT a.ID, a.IDConf FROM application a GROUP BY a.IDConf HAVING COUNT(a.IDConf) >= 2
if you want join only the result for HAVING COUNT(a.IDConf) >= 2 you could use a inner join on subselect
SELECT c.ID, c.DateEnd
FROM conference c
INNER JOIN (
SELECT a.ID, a.IDConf
FROM application a
GROUP BY a.IDConf
HAVING COUNT(a.IDConf) >= 2
) t ON c.ID=t.IDConf
WHERE c.DateEnd = DATE_ADD(CURDATE(),INTERVAL 1 DAY)
You can use a left join. Try this:
SELECT c.ID, a.ID a_ID, c.DateEnd
FROM conference c LEFT JOIN application a
ON c.ID=a.IDConf
WHERE DateEnd=DATE(DATE_ADD(CURDATE(),INTERVAL 1 DAY))
GROUP BY c.ID, a.ID
HAVING COUNT(a.IDConf)>=2;
See MySQL Join Made Easy for insight on using joins.
Related
...
Trying to learn SQL and the following query:
SELECT a.id, a.name, w.channel, COUNT(*) use_of_channel
FROM accounts a
JOIN web_events w
ON a.id = w.account_id
GROUP BY a.id, a.name, w.channel
HAVING COUNT(*) > 6 AND w.channel = 'facebook'
ORDER BY use_of_channel;
returns 46 results (first query results), JUST ADDING A JOIN of an unrelated table returns 220 results.
Its not a CROSS JOIN since it seems properly formatted, just added down here at line 5 a JOIN with "orders" table
SELECT a.id, a.name, w.channel, COUNT(*) use_of_channel
FROM accounts a
JOIN web_events w
ON a.id = w.account_id
JOIN orders o
ON o.account_id = a.id
GROUP BY a.id, a.name, w.channel
HAVING COUNT(*) > 6 AND w.channel = 'facebook'
ORDER BY use_of_channel;
...but why would another table compromise the results?
It is a cross join. That is, each account has multiple events. And each account has multiple orders. So within each account you are getting a Cartesian product.
A quick way to fix this is to use count(distinct) on a primary key:
SELECT a.id, a.name, w.channel,
COUNT(w.id) as use_of_channel
I have this query
SELECT
equipe_id
FROM
user
GROUP BY
equipe_id
HAVING
COUNT(*) >= 5
and it returns 1 and 3.
I want to use this next query using the previous query
SELECT
name,
location
FROM
equipe
WHERE
equipe_id IN ??? previous query result (1,3) ???
I hope that makes sense. Thank you
SELECT name
, location
FROM equipe
WHERE equipe_id in (SELECT equipe_id FROM user GROUP BY equipe_id HAVING COUNT(*) >= 5);
We can also try doing this via joining to a subquery:
SELECT e1.name, e1.location
FROM equipe e1
INNER JOIN
(
SELECT equipe_id
FROM user
GROUP BY equipe_id
HAVING COUNT(*) >= 5
) e2
ON e1.equipe_id = e2.equipe_id;
As an alternative, this can be done also without the inner subquery, like this:
SELECT
e.name,
e.location
FROM
equipe AS e
INNER JOIN
user AS u ON u.equipe_id = e.equipe_id
GROUP BY
e.equipe_id, e.name, e.location
HAVING
COUNT(*) >= 5
I have good working sql query but I need to select also atribute from table advert. I tried with inner join but it wasn't successful. So this query is ok but I need to select one atribute from table advert.
SELECT D.* FROM details
WHERE (D.name LIKE ?) AND (D.id_advert IN(
SELECT A.id
FROM advert A
WHERE A.status=1 and duration >= CURDATE()
ORDER BY duration DESC ))
You can change the in (subquery ) in a proper inner join and the is simple use the columns form table A
SELECT D.* , A.*
FROM details
INNER JOIN advert A ON D.id_advert = A.id
AND A.status=1
AND duration >= CURDATE()
WHERE D.name LIKE ?
SELECT *
FROM details D
INNER JOIN advert A ON D.id_advert = A.id
INNER JOIN place P ON A.id_place = P.id
WHERE (D.NAME LIKE ?)
AND ( D.id_advert IN (
SELECT A.id
FROM advert A
WHERE A.STATUS = 1 AND duration >= CURDATE()
ORDER BY duration DESC
)
)
Here "?" is for search key. This query work perfect.
Table A
id(UNIQUE) name
1 tomato
2 potato
Table B
id AID buy_date buy_money
6 1 2015-01-01 100
7 1 2015-02-02 200
I want to select all A's record filtered with name, and with the latest buy_date and buy_money like this:
A.id A.name B.buy_date B.buy_money
1 tomato 2015-02-02 200
2 potato NULL NULL
How can I write the SQL script? I have tried:
select A.id, A.name, MAX(B.buy_date)
from A left join B on A.id = B.AID
where A.name like '%to%'
Group by A.id
But this only get the right buy_date, but no buy_money.
http://sqlfiddle.com/#!9/bee19b/1
SELECT A.id, A.name, t.*
FROM A
LEFT JOIN (
SELECT B.*
FROM B
LEFT JOIN B b_
ON b.AID = b_.AID
AND b.buy_date<b_.buy_date
WHERE b_.id IS NULL
) t
ON A.id = t.AID
WHERE A.name LIKE '%to%'
2 basic methods here.
Firstly, if the buy date is unique for an AID then you can get the latest buy_date for each AID using a sub query and join that against the B table to get the rest of the details.
Down side of this is that if there are multiple records for an AID with the same buy_date you will get multiple records back
SELECT A.id, A.name, B.buy_date, B.buy_money
FROM A
LEFT OUTER JOIN
(
SELECT AID, MAX(buy_date) AS max_buy_date
FROM B
GROUP BY AID
) AS sub_B
ON A.id = sub_B.AID
LEFT OUTER JOIN B
ON B.AID = sub_B.AID
AND B.buy_date = sub_B.max_buy_date
WHERE A.name like '%to%'
Second solution is to use GROUP_CONCAT to get all the values back, ordered by buy_date descending, then use SUBSTRING_INDEX to get everything up to the first delimiter. Default delimiter for GROUP_CONCAT is a comma but if you values might contain a comma you can easily change that. Down side of this is that it is forcing a conversion of the date and money fields to strings.
SELECT A.id,
A.name,
SUBSTRING_INDEX(GROUP_CONCAT(B.buy_date ORDER BY B.buy_date DESC), ',', 1),
SUBSTRING_INDEX(GROUP_CONCAT(B.buy_money ORDER BY B.buy_date DESC), ',', 1)
FROM A
LEFT OUTER JOIN B
ON B.AID = A.id
WHERE A.name like '%to%'
GROUP BY A.id, A.name
I have the 2 following Queries:
This table can have multiple lines per user (many photos) and I just want to return the number/count of photos:
SELECT COUNT(*) FROM photos WHERE photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1 AND userid='1000000002';
This table(s) is only one per user:
SELECT a.userid,a.profile_username,a.profile_gender,a.photo_name,a.photo_verified,b.profile_headline,
YEAR(DATE_SUB(NOW(), INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,d.city,c.english AS country
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
Is it possible to combine these 2 queries?
This is at my limit of ability so any advice would be great :) thx
SELECT
a.userid,
a.profile_username,
a.profile_gender,
a.photo_name,
a.photo_verified,
b.profile_headline,
YEAR(DATE_SUB(NOW(),
INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,
d.city,c.english AS country,
(SELECT COUNT(*) FROM photos WHERE photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1 AND userid= a.userid) AS result_count
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
It is possible. this takes two steps:
adapt the COUNT(*) into a filtering SUM()
plug the source table into the query
.
SELECT a.userid,a.profile_username,a.profile_gender,a.photo_name,a.photo_verified,b.profile_headline,
YEAR(DATE_SUB(NOW(), INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,d.city,c.english AS country
//Here we insert the count column
,IFNULL(SUM(IF(photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1,1,0)),0) AS photocount
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
//Here we insert the source table
LEFT JOIN photos ON photos.userid=a.userid
WHERE a.userid IN ('1000000002','1000000003','1000000004')
//Group by users
GROUP BY a.userid
If you want this as an additional column, then cross join it into the results:
select const.cnt, . . .
from (SELECT COUNT(*) as cnt
FROM photos
WHERE photo_description_profanity=1 AND photo_visible=1 AND
photo_verified=1 AND userid='1000000002'
) const cross join
login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
//Here we insert the source table
LEFT JOIN photos ON photos.userid=a.userid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
The advantage of using a cross join instead of a nested select query is performance. MySQL will execute the nested select for every row in the return set. In the from clause, it will only be executed once.