I have a MySQL query like this:
SELECT *
FROM backstage
WHERE backstage_id IN (
SELECT backstage_id
FROM visitor_counter
WHERE backstage_id !=0
GROUP BY backstage_id
ORDER BY COUNT( DISTINCT ( ip_address ) ) DESC
)
LIMIT 0 , 100
I get the results I want, but I would like to order it by COUNT( DISTINCT ( ip_address ) ) DESC as the inner question does.
Any tips on how to do this?
Give this a go and see if it gives you what you're after:
select bs.*
from backstage bs
inner join
(
select backstage_id,count(distinct ip_address) as distIpCount
from visitor_counter
where backstage_id !=0
group by backstage_id
) vc on vc.backstage_id = bs.backstage_id
order by vc.distIpCount desc
limit 0,100;
Related
i have a large dataset and i need help to make a few queries faster.
So far i am using subquery to retrieve the product ids and get the different persons of this products (something like filtering)
Here is my query
SELECT assoc.*, count(assoc.product_id) as count FROM ws_products_persons_assoc as assoc
WHERE
assoc.product_id
IN
( SELECT c.id
FROM ws_products as c
WHERE c.status = '1'
AND ( ( product_name LIKE '%960%' ) OR ( ( code LIKE '%960%' OR isbn13 LIKE '%960%' OR parent_codes LIKE '%960%') ) OR ( publisher_name LIKE '%960%' ) OR ( author_name LIKE '%960%' ) )
ORDER BY c.year desc,c.product_name ASC
)
GROUP BY assoc.person_id
ORDER BY count DESC LIMIT 0,30
Query Time =1.7937450408936 seconds
The subquery search in a few fields for the given keyword
The subquery returns 183473 rows and takes 1.7 secs to run.
Any ideas for making subquery faster is appriciated
Thanks
Why not an inner join? (assuming product_id is unique)
SELECT a.*, count(a.product_id) as count
FROM ws_products_persons_assoc a INNER JOIN ws_products p
ON p.id = a.product_id
WHERE
p.status = 1 AND
( (p.product_name LIKE '%960%' ) OR
(p.code LIKE '%960%') OR
(p.isbn13 LIKE '%960%' OR
(p.parent_codes LIKE '%960%') OR
(p.publisher_name LIKE '%960%') OR
(p.author_name LIKE '%960%' )
)
GROUP BY a.person_id
ORDER BY count DESC
LIMIT 0, 30;
I would start by switching to EXISTS:
SELECT a.person_id, count(a.product_id) as count
FROM ws_products_persons_assoc a
WHERE EXISTS (SELECT 1
FROM ws_products p
WHERE p.id = a.product_id AND
p.status = 1 AND
( (p.product_name LIKE '%960%' ) OR
(p.code LIKE '%960%') OR
(p.isbn13 LIKE '%960%' OR
(p.parent_codes LIKE '%960%') OR
(p.publisher_name LIKE '%960%') OR
(p.author_name LIKE '%960%' )
)
)
GROUP BY a.person_id
ORDER BY count DESC
LIMIT 0, 30;
For this version, you want an index on ws_products(id, status).
The select columns should match the group by columns.
my demand is:from database query newest data,according to time field as a standard,query alarmtime this field ,but alarmtime < time
executive sql:
SELECT
c.entryTime AS alarmtime ,
a.time AS time
FROM (
SELECT
t.DB33,
MAX( t.Time ) AS time,
t.Stream,
t.Coil,
t.`View`
FROM (
SELECT DB33, Time, Stream, Coil, `View`
FROM running_check
ORDER BY id DESC
LIMIT 1000 ) as t
GROUP BY t.DB33 ) AS a
LEFT JOIN (
select cameraID,cameraName
from monitor_link_info) as b ON a.db33 = b.cameraID
LEFT JOIN (
SELECT entryTime, cameraID
FROM result_video_v2
ORDER BY id DESC
limit 1000 ) AS c ON a.db33 = c.cameraId
GROUP BY a.db33, b.cameraName
ORDER BY a.time DESC, alarmtime DESC
execute result is unamiable,please look at image
now time column not what i want,Because he didn't change.
SELECT
c.entryTime AS alarmtime ,
a.time AS TIME
FROM
(
SELECT DB33, MAX(TIME) TIME, Stream, Coil, `View`
FROM running_check
ORDER BY id DESC
GROUP BY t.DB33
LIMIT 1000
) AS a
LEFT JOIN
(
SELECT cameraID,cameraName
FROM monitor_link_info
GROUP BY cameraID
LIMIT 1000
) AS b ON (a.db33 = b.cameraID)
LEFT JOIN (
SELECT entryTime, cameraID
FROM result_video_v2
GROUP BY cameraID
ORDER BY id DESC
LIMIT 1000
) AS c ON (a.db33 = c.cameraID)
GROUP BY a.db33, b.cameraName
ORDER BY a.time DESC, c.entryTime DESC
I want to add data from table b in table a but unfortunately full outer join do not work in mysql . I have also tried union but it is throwing errors because my statement has group by and order by keyword
SELECT COUNT( ReviewedBy ) AS TotalReviews, OrganizationId, SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings, (
SUM( Rating ) / COUNT( Rating )
) AS AverageRating
FROM `tbl_reviews`
WHERE ReviewType = 'shopper'
AND ReviewFor = 'org'
AND OrganizationId
IN (
SELECT OrganizationId
FROM tbl_organizations
WHERE CategoryID =79
)
GROUP BY OrganizationId
ORDER BY AverageRating DESC
This is what i'm getting from the above statement
I want to get organizationId 21 data in the result but i'm not getting result because it's not present in 'tbl_review' table
click here to see the table b
How can i get Desired result ?
You don't need a FULL, but a LEFT join:
SELECT COUNT( ReviewedBy ) AS TotalReviews, o.OrganizationId,
SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings,
(SUM( Rating ) / COUNT( Rating )) AS AverageRating
FROM tbl_organizations AS o
LEFT JOIN `tbl_reviews` AS r
ON o.OrganizationId = r.OrganizationId
AND ReviewType = 'shopper' -- conditions on inner table
AND ReviewFor = 'org' -- must be moved to ON
WHERE CategoryID =79
GROUP BY o.OrganizationId
ORDER BY AverageRating DESC
Why don't you use AVG instead of SUM/COUNT?
Have you tried:
from organization
left outer join tbl_reviews
on organization.ID = tbl_reviews.organization is
for your where clause? I don't think you need a full outer join in this case... A left outer join should do
mysql group_concat function using sub-query in condition I want to try as below :
SELECT * FROM prologic WHERE ID IN (
SELECT GROUP_CONCAT( DISTINCT ID ) from (
SELECT GROUP_CONCAT( DISTINCT ID )ID
FROM `prologic`
GROUP BY Vendor_Code
HAVING COUNT( * ) >1
)c
)
Please guide me to solve it.
SELECT * FROM prologic WHERE ID IN (
SELECT DISTINCT ID FROM prologic
GROUP BY Vendor_Code
HAVING COUNT( * ) >1
)
Anyone can help me, I am a bit stuck.
I have this query which works like a charm
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
WHERE matches > 0
ORDER BY hits DESC
But I would like to change it to sort where HITS are more than 0, but it tells me it doesn't know hits... Is it because it's a calculation of 2 items?
You can't use an aliases column in a WHERE clause. You need to rewrite it:
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
WHERE matches - falsepositives > 0
ORDER BY hits DESC
Or use a subquery:
SELECT * FROM (
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
) AS S2
WHERE hits > 0
ORDER BY hits DESC