Server won't byte on this query, it takes too long to execute:
select prodavac.id, count(artikl.id) as brojartikala, count(poruceno.id) as brojporudzbina from prod_prodavac prodavac
inner join prod_artikl artikl
on prodavac.id=artikl.prodavacid
inner join prod_poruceno poruceno
on prodavac.id=poruceno.prodavacid
group by prodavac.id
On the other hand, both semi-queries run mega fast:
select prodavac.id, count(artikl.id) as brojartikala from prod_prodavac prodavac
inner join prod_artikl artikl
on prodavac.id=artikl.prodavacid
group by prodavac.id
Also the other one:
select prodavac.id, count(poruceno.id) as brojporudzbina from prod_prodavac prodavac
inner join prod_poruceno poruceno
on prodavac.id=poruceno.prodavacid
group by prodavac.id
order by prodavac.id asc
I would really like to do it in one query, so how to merge them correct way? All IDs are indexed integers.
Explain select shows this:
Depending on the relations between the tables and the data, your combined query might not even return the desired result. For a simple count of relations you can use correlated subqueries in the SELECT clause:
select prodavac.id, (
select count(*)
from prod_artikl artikl
where artikl.prodavacid = prodavac.id
) as brojartikala, (
select count(*)
from prod_poruceno poruceno
where poruceno.prodavacid = prodavac.id
) as brojporudzbina
from prod_prodavac prodavac
order by prodavac.id asc
Related
I have an SQL join function ready to implement however, if I run the snippet below only rows from wp_tours_tours are returned which also have rows in wp_tours_tours_bookings.
SELECT
wp_tours_tours.*,
SUM(wp_tours_tours_bookings.qty) AS "TotalBookings"
FROM wp_tours_tours
left join wp_tours_tours_bookings ON wp_tours_tours.tour_id=wp_tours_tours_bookings.tour_id
WHERE wp_tours_tours.post_id=12
If I use the below script without the SUM() function in the select statement it returns multiple rows (even those without any rows in wp_tours_tours_bookings)
SELECT
wp_tours_tours.*
FROM wp_tours_tours
left join wp_tours_tours_bookings ON wp_tours_tours.tour_id=wp_tours_tours_bookings.tour_id
WHERE wp_tours_tours.post_id=12
I need to get the first snippet working so that it just returns 0 for "TotalBookings" if it has no rows and to pull through all data from tours_tours even if tours_tours_bookings has no rows.
I would use a correlated subquery here:
select
t.*,
(
select coalesce(sum(tb.qty), 0)
from wp_tours_tours_bookings tb
where tb.tour_id = t.tour_id
) as totalbookings
from wp_tours_tours t
where t.post_id=12
Your query is malformed, because you have an aggregation function (SUM()) and columns that are not aggregated -- but no GROUP BY.
You need a GROUP BY:
SELECT tt.*, COALESCE(SUM(ttb.qty), 0) AS TotalBookings
FROM wp_tours_tours tt LEFT JOIN
wp_tours_tours_bookings ttb
ON tt.tour_id = ttb.tour_id
WHERE tt.post_id = 12
GROUP BY tt.tour_id; -- or whatever the primary key is
You can also use a correlated subquery (which probably has better performance):
SELECT tt.*,
(SELECT COALESCE(SUM(ttb.qty), 0)
FROM wp_tours_tours_bookings ttb
WHERE tt.tour_id = ttb.tour_id
) AS TotalBookings
FROM wp_tours_tours tt
WHERE tt.post_id = 12
I have the following two separate queries:
SELECT qry_tbl_G_ov_uni_atp.ID, Max(qry_tbl_G_ov_uni_atp.nElo_Ov) AS MaxOfnElo_Ov
FROM qry_tbl_G_ov_uni_atp
GROUP BY qry_tbl_G_ov_uni_atp.ID;
And:
SELECT qry_tbl_G_ov_uni_atp.ID, Max(qry_tbl_G_ov_uni_atp.nElo_Sur) AS MaxOfnElo_Sur1
FROM qry_tbl_G_ov_uni_atp
WHERE qry_tbl_G_ov_uni_atp.ID_C = 1
GROUP BY qry_tbl_G_ov_uni_atp.ID;
Both run fine and within a second or two. I want to combine them into one query so I have ID, MaxOfnElo_Ov and MaxOfnElo_Sur1 in the same output.
I know I need to use a sub query but my attempts take absolutely ages to display anything and then are barely useable as any attempt at scrolling locks Access up for an age again. I'm clearly not doing something right. Here's my sub query code:
SELECT qry_tbl_G_ov_uni_atp.ID, Max(qry_tbl_G_ov_uni_atp.nElo_Ov) AS MaxOfnElo_Ov, (SELECT Max(tt.nElo_Sur)
FROM qry_tbl_G_ov_uni_atp as tt
WHERE tt.ID_C = 1
AND tt.ID = qry_tbl_G_ov_uni_atp.ID) AS MaxOfnElo_Sur1
FROM qry_tbl_G_ov_uni_atp
GROUP BY qry_tbl_G_ov_uni_atp.ID;
You can use a subquery to achieve this as you have indicated. By using a sub-query in the JOIN as well you will get all results from a (your first query) and matching results from b (your second query):
SELECT a.ID,
a.MaxOfnElo_Ov,
b.MaxOfnElo_Sur1
FROM (
SELECT qry_tbl_G_ov_uni_atp.ID,
Max(qry_tbl_G_ov_uni_atp.nElo_Ov) AS MaxOfnElo_Ov
FROM qry_tbl_G_ov_uni_atp
GROUP BY qry_tbl_G_ov_uni_atp.ID
) a
LEFT JOIN (
SELECT qry_tbl_G_ov_uni_atp.ID,
Max(qry_tbl_G_ov_uni_atp.nElo_Sur) AS MaxOfnElo_Sur1
FROM qry_tbl_G_ov_uni_atp
WHERE qry_tbl_G_ov_uni_atp.ID_C = 1
GROUP BY qry_tbl_G_ov_uni_atp.ID
) b ON b.ID = a.ID
Note that this is untested, and assumes the ID is the same in both a and b (which I believe it is).
I have such a query:
SELECT
*,
(
SELECT COUNT(DISTINCT client_id)
FROM 1097_course_students_tbl
WHERE course_cycl_id=id
AND stts_id <> 8
AND client_id IN(SELECT id FROM 1097_clients_tbl WHERE is_removed=0)
) AS cnt
FROM 1097_course_cycle_tbl
WHERE (course_id IN (SELECT id FROM 1097_courses_tbl WHERE is_removed=2))
ORDER BY start_date DESC
I need to make it more efficient because it takes too long
any suggestions ?
thanks
Try the following
SELECT cc.*,IFNULL(q.cnt,0) cnt
FROM 1097_course_cycle_tbl cс
JOIN 1097_courses_tbl с ON c.id=cc.course_id AND c.is_removed=2
LEFT JOIN
(
SELECT cs.course_cycl_id,COUNT(DISTINCT cs.client_id) cnt
FROM 1097_course_students_tbl cs
JOIN 1097_clients_tbl c ON cs.client_id=c.id AND c.is_removed=0
WHERE cs.stts_id<>8
GROUP BY cs.course_cycl_id
) q
ON q.course_cycl_id=cс.id
ORDER BY cc.start_date DESC
I think id in 1097_courses_tbl and 1097_clients_tbl is primary key.
Therefore I replaced IN into JOIN.
And I converted the subquery from SELECT block wich executed for each rows into the subquery with GROUP BY which using in LEFT JOIN. Here it'll execute only one time and return all the necessary information.
I am trying to retrieve the max(date_entered) for a group of computer_ids.
The first query won't return accurate results. The second query gives me accurate results but essentially hangs unless I filter by a specific computer_id.
I'd rather use this first query
SELECT *, max(reports.date_entered)
FROM reports, hardware_reports
WHERE reports.report_id=hardware_reports.report_id
GROUP BY computer_id;
than this second query
SELECT *
FROM reports a
JOIN hardware_reports
ON a.report_id=hardware_reports.report_id
AND a.date_entered = (
SELECT MAX(date_entered)
FROM reports AS b
WHERE a.computer_id = b.computer_id)
and computer_id = 1648;
I need to either optimize second or get max to work in first.
You can alternative join it on a subquery that gets the latest record for every computer_ID.
SELECT a.*, c.*
FROM reports a
INNER JOIN
(
SELECT computer_ID, MAX(date_entered) date_entered
FROM reports
GROUP BY computer_ID
) b ON a.computer_ID = b.computer_ID
AND a.date_entered = b.date_entered
INNER JOIN hardware_reports c
ON a.report_id = c.report_id
To make it more efficient, provide an index on columns:
ALTER TABLE reports INDEX idx_report_compDate (computer_ID, date_entered)
How could I count rows from a SELECT query as a value?
Such as
SELECT FUCNTIONIMLOOKINGFOR(SELECT * FROM anothertable) AS count FROM table;
So that count is an integer of how many rows the subquery SELECT * FROM anothertable returns.
EDIT
SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
(
SELECT COUNT(f.FlagTime)
FROM Flags as f
JOIN Posts as p
ON p.PostPID = f.FlagPID
) as PostFlags
FROM Posts AS p
JOIN Users AS u
ON p.PostUID = u.UserUID
ORDER BY PostTime DESC
LIMIT 0, 30
SELECT ( SELECT COUNT(id) FROM aTable ) as count FROM table
I assume your example is a truncated version of your actual query, so perhaps you should post what you are after to get a, possibly, more optimal query.
EDIT
Working directly from my brain, something like this should be more optimal.
SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep, COUNT(v.FlagTime) as postFlags
FROM Flags as f
JOIN Posts as p ON p.PostPID = f.FlagPID
JOIN Users AS u ON p.PostUID = u.UserUID
LIMIT 0, 30
GROUP BY p.PostPID
ORDER BY PostTime DESC
You can say
SELECT COUNT(*) FROM anothertable
which will return a numeric value, which you can use in another query, such as in the select list of another query, or as a condition in another query.
SELECT someVariable FROM table
WHERE (SELECT COUNT(*) FROM anotherTable) > 5
OR
SELECT someVariable, (SELECT COUNT(*) FROM anotherTable) as count FROM table