I am having issue with my query having both SUM and GROUP_CONCAT function.
The sum values changes as GROUP_CONCAT values increases.
Below is my code:
SELECT ul.display_name,
ul.photo,
ul.user_id,
Sum(ulr.level_score) AS level_scores,
Sum(ulr.level_timer) AS level_timer,
Group_concat(ulr.level_completed) AS levels,
Group_concat(DISTINCT c.bit_id) AS bit_id
FROM user_level_responses AS ulr
INNER JOIN user_login AS ul
ON (
ul.user_id=ulr.user_id)
INNER JOIN c_member AS cm
ON (
cm.user_id=ul.user_id
AND cm.user_approval='Y'
AND cm.delete_status='0'
AND cm.status='1')
INNER JOIN ctree ct
ON (
cm.circuit_id=ct.circuit_id )
INNER JOIN cir AS c
ON (
c.circuits_id=cm.circuit_id
AND c.builtin=0
AND c.delete_status='0'
AND c.status='1')
WHERE Match(ct.circuit_path) against ('_902_')
AND ulr.institution_id=321
AND ulr.delete_status=0
AND ulr.status=1
AND ul.delete_status=0
GROUP BY ulr.user_id
ORDER BY level_scores DESC,
level_timer ASC,
ul.display_name limit 500
If the actual score is 900 and if i have 2 ids in GROUP_CONCAT then actual score is double the original.
Expected OUTPUT:
user1 2010.cs,btech 960 00:01:08 Completed
user2 btech 920 00:01:08 Completed
OUTPUT GETTING:
user1 2010.cs,btech 1920 00:01:08 Completed
user2 btech 920 00:01:08 Completed
twice the actual amount ie 960.
Your problem is that your multiple ids are doubling the rows that your result has before the grouping. You can solve this problem by joining in all of the external data in a subquery.
I have absolutely no idea the structure of your database, nor all of the functions, but this is a stab in the dark at reorganizing your query. If you need, I can write up a much simpler SQLFiddle to show you what I mean.
SELECT ul2.display_name,
ul2.photo,
ul2.user_id,
Sum(ulr.level_score) AS level_scores,
Sum(ulr.level_timer) AS level_timer,
Group_concat(ulr.level_completed) AS levels,
ul2.bit_id
FROM user_level_responses AS ulr
INNER JOIN (
SELECT
ul.display_name,
ul.photo,
ul.user_id,
GROUP_CONTACT(DISTINCT c.bit_id) as bit_id
FROM user_login AS ul
INNER JOIN c_member AS cm
ON (
cm.user_id=ul.user_id
AND cm.user_approval='Y'
AND cm.delete_status='0'
AND cm.status='1')
INNER JOIN ctree ct
ON (
cm.circuit_id=ct.circuit_id )
INNER JOIN cir AS c
ON (
c.circuits_id=cm.circuit_id
AND c.builtin=0
AND c.delete_status='0'
AND c.status='1')
WHERE Match(ct.circuit_path) against ('_902_')
AND ul.delete_status=0
GROUP BY ul.user_id
) AS ul2
ON (
ulr.user_id = ul2.user_id )
WHERE ulr.institution_id=321
AND ulr.delete_status=0
AND ulr.status=1
GROUP BY ulr.user_id
ORDER BY level_scores DESC,
level_timer ASC,
ul.display_name limit 500
Related
I have four tables, three of which are pretty static: haul_types, dumpster_type_team (the dumpster_type_team has the many-to-many relationship between dumpster_types and teams), and users. The fourth table, hauls, has transactional data.
haul_types:
id
name
dumpster_type_team:
id
dumpster_type_id
team_id
users:
id
first_name
last_name
is_driver
team_id
hauls:
haul_type_id
haul_status_id
set_dumpster_type_id
completed_driver_id
team_id
I would like a query that has a combination of dumpster_types, haul_types, and drivers (users) and a count of the hauls they were involved in. In some cases, there should be a count of zero because some drivers haven't completed hauls for every haul_type / dumpster type combination.
Here's the query I have so far that seems to be behaving as if it is an inner join because the records are getting filtered to only show where there are matches:
SELECT
c.haul_type_id,
c.dumpster_type_id,
c.driver_id,
count(h.id) AS haul_count
FROM
hauls h
RIGHT JOIN ( SELECT DISTINCT
ht.id AS haul_type_id,
dtt.dumpster_type_id AS dumpster_type_id,
dtt.team_id AS team_id,
u.id AS driver_id
FROM
haul_types ht
CROSS JOIN dumpster_type_team dtt
CROSS JOIN users u
WHERE
u.team_id = dtt.team_id
AND u.is_driver = TRUE) c ON c.haul_type_id = h.haul_type_id
AND c.dumpster_type_id = h.set_dumpster_type_id
AND c.driver_id = h.completed_driver_id
AND c.team_id = h.team_id
WHERE
h.team_id = 9
AND h.haul_status_id = 3
AND h.completed_driver_id IS NOT NULL
GROUP BY
c.haul_type_id, c.dumpster_type_id, c.driver_id
When I run the subquery in isolation:
SELECT DISTINCT
ht.id AS haul_type_id,
dtt.dumpster_type_id AS dumpster_type_id,
dtt.team_id AS team_id,
u.id AS driver_id
FROM
haul_types ht
CROSS JOIN dumpster_type_team dtt
CROSS JOIN users u
WHERE
u.team_id = dtt.team_id
AND u.is_driver = TRUE
I get the results I want: a row for each permutation of haul_type, dumpster_type, driver_id, and team_id. However, when I run the entire query, I get filtered results despite the right join.
What I would like to have is the following:
If I have 4 haul_types: delivery, swap, live, pickup
and 2 dumpster_types: 10YD, 15YD
and 2 drivers: 1, 2
I would like a haul count for the combination of haul_type, dumpster_type, and driver. If there are no hauls matching the row, show 0:
Any help is appreciated. Thank you
The description of the question and the query seem to have little to do with each other. I don't know what a "pivot table" is supposed to be.
I would like a query that has a combination of dumpster_types, haul_types, and drivers (users) and a count of the hauls they were involved in.
This sounds like a cross join to generate the rows and then a left join/group by to calculate the results:
select d.dumpster_id, ht.haul_type_id, d.driver_id, count(h.driver_id)
from dumpster_types d cross join
haul_types ht cross join
drivers d left join
hauls h
on h.dumpster_id = d.dumpster_id and
h.haul_type_id = ht.haul_type_id and
h.driver_id = d.driver_id
group by d.dumpster_id, ht.haul_type_id, d.driver_id;
Running the query #GordonLinoff provided, exposed the issue I was facing - when applying a where clause on the top level query, the results were getting filtered to only matches. I moved the where clause to individual subqueries and now I am getting all expected results.
Not sure if this is the most efficient way to write it but it yields the correct results:
SELECT
d.dumpster_type_id,
ht.id AS haul_type_id,
u.id AS driver_id,
count(h.id) AS haul_count
FROM (
SELECT
dumpster_type_id,
team_id
FROM
dumpster_type_team
WHERE
team_id = 9) d
CROSS JOIN haul_types ht
CROSS JOIN (
SELECT
users.id
FROM
users
WHERE
users.is_driver = TRUE
AND users.team_id = 9) u
LEFT JOIN (
SELECT
id, set_dumpster_type_id, haul_type_id, completed_driver_id, team_id
FROM
hauls
WHERE
haul_status_id = 3
AND team_id = 9) h ON h.set_dumpster_type_id = d.dumpster_type_id
AND h.haul_type_id = ht.id
AND h.completed_driver_id = u.id
AND h.team_id = d.team_id
GROUP BY
d.dumpster_type_id,
ht.id,
u.id
i have some code to mysql query, but it's not showing right result.
This is my code:
select a.spent
, t_rinci.harga as price
from t_pengajuan
join t_rinci
on t_rinci.id_pengajuan = t_pengajuan.id
left
JOIN
( SELECT t_realisasi.id_rinci as id
, SUM(nilai_realisasi) spent
FROM t_realisasi
GROUP
by id ) a
on a.id = t_rinci.id_rinci
where t_rinci.id_rinci in (a.id)
group
by t_rinci.id_pengajuan
expected result is
spent
price
400000
4250000
1000000
1100000
but it say
spent
price
400000
4250000
1000000
1000000
here my sqlfiddle
Here's an example of a coherent query:
select r.id_pengajuan
, SUM(a.spent) spent
, SUM(r.harga) as price
from t_pengajuan p
join t_rinci r
on r.id_pengajuan = p.id
JOIN
( SELECT t_realisasi.id_rinci as id
, SUM(nilai_realisasi) spent
FROM t_realisasi
GROUP
by id ) a
on a.id = r.id_rinci
group
by r.id_pengajuan
It might not be what you're after, but it does at least make sense.
I've got a query with avg results. In another table I have the results of that
avg result in text.
Right now this is my query:
select round(avg(breed_ratings.rating)) as result, breed_ratings.score_name, count(*) as total, breeds.name_en
from breed_ratings
inner join breeds on breeds.id = breed_ratings.breed_id
where breeds.id = 188
group by score_name, breeds.name_en
The rating_result table looks like this:
id
rating
result_text
How can I get the result_text in this query?
Please help me out.
--EDIT
I need to get the result from the image below in text.
So I have another table where this is stored I need to get the result_nl where it matches the rating:
Desired result (if rating is 5):
result: 5
score_name: ADULT_FRIENDLY
total: 117
name_en: American Staffordshire Terrier
result_nl: I am extremely dominant
I think you want to join the average to the first rating in rating_results where the average is bigger than the listed rating there. If so:
select br.*, rr.result_text
from (select round(avg(br.rating)) as result, br.score_name, count(*) as total, b.name_en
from breed_ratings br join
breeds b
on b.id = br.breed_id
where b.id = 188
group by br.score_name, b.name_en
) br left join
(select rr.*, lead(rr.rating) over (order by rr.rating) as next_rating
from rating_result rr
) rr
on br.result >= rr.rating and
(br.result < rr.next_rating or rr.next_rating is null)
My Sql query takes more time to execute from mysql database server . There are number of tables are joined with sb_tblproperty table. sb_tblproperty is main table that contain more than 1,00,000 rows . most of table contain 50,000 rows.
How to optimize my sql query to fast execution. I have also used indexing.
indexing Explain - query - structure
SELECT `t1`.`propertyId`, `t1`.`projectId`,
`t1`.`furnised`, `t1`.`ownerID`, `t1`.`subType`,
`t1`.`fors`, `t1`.`size`, `t1`.`unit`,
`t1`.`bedrooms`, `t1`.`address`, `t1`.`dateConfirm`,
`t1`.`dateAdded`, `t1`.`floor`, `t1`.`priceAmount`,
`t1`.`priceRate`, `t1`.`allInclusive`, `t1`.`booking`,
`t1`.`bookingRate`, `t1`.`paidPercetage`,
`t1`.`paidAmount`, `t1`.`is_sold`, `t1`.`remarks`,
`t1`.`status`, `t1`.`confirmedStatus`, `t1`.`source`,
`t1`.`companyName` as company, `t1`.`monthly_rent`,
`t1`.`per_sqft`, `t1`.`lease_duration`,
`t1`.`lease_commencement`, `t1`.`lock_in_period`,
`t1`.`security_deposit`, `t1`.`security_amount`,
`t1`.`total_area_leased`, `t1`.`lease_escalation_amount`,
`t1`.`lease_escalation_years`, `t2`.`propertyTypeName` as
propertyTypeName, `t3`.`propertySubTypeName` subType,
`t3`.`propertySubTypeId` subTypeId, `Owner`.`ContactName`
ownerName, `Owner`.`companyName`, `Owner`.`mobile1`,
`Owner`.`otherPhoneNo`, `Owner`.`mobile2`,
`Owner`.`email`, `Owner`.`address` as caddress,
`Owner`.`contactType`, `P`.`projectName` as project,
`P`.`developerName` as developer, `c`.`name` as city,
if(t1.projectId="", group_concat( distinct( L.locality)),
group_concat( distinct(L2.locality))) as locality, `U`.`firstname`
addedBy, `U1`.`firstname` confirmedBy
FROM `sb_tblproperty` as t1
JOIN `sb_contact` Owner ON `Owner`.`id` = `t1`.`ownerID`
JOIN `tbl_city` C ON `c`.`id` = `t1`.`city`
JOIN `sb_propertytype` t2 ON `t1`.`propertyType`= `t2`.`propertyTypeId`
JOIN `sb_propertysubtype` t3 ON `t1`.`subType` =`t3`.`propertySubTypeId`
LEFT JOIN `sb_tbluser` U ON `t1`.`addedBy` = `U`.`userId`
LEFT JOIN`sb_tbluser` U1 ON `t1`.`confirmedBy` = `U1`.`userId`
LEFT JOIN `sb_tblproject` P ON `P`.`id` = `t1`.`projectId` LEFT
JOIN `sb_tblpropertylocality` PL ON `t1`.`propertyId` = `PL`.`propertyId`
LEFT JOIN `sa_localitiez` L ON `L`.`id` = `PL`.`localityId`
LEFT JOIN `sb_tblprojectlocality` PROL ON `PROL`.`projectId` = `P`.`id`
LEFT JOIN `sa_localitiez` L2 ON `L2`.`id` = `PROL`.`localityId`
LEFT JOIN `sb_tblfloor` F
ON `F`.`floorName` =`t1`.`floor`
WHERE `t1`.`is_sold` != '1' GROUP BY `t1`.`propertyId`
ORDER BY `t1`.`dateConfirm`
DESC LIMIT 1000
Please provide the EXPLAIN.
Meanwhile, try this:
SELECT ...
FROM (
SELECT propertyId
FROM sb_tblproperty
WHERE `is_sold` = 0
ORDER BY `dateConfirm` DESC
LIMIT 1000
) AS x
JOIN `sb_tblproperty` as t1 ON t1.propertyId = x.propertyId
JOIN `sb_contact` Owner ON `Owner`.`id` = `t1`.`ownerID`
JOIN `tbl_city` C ON `c`.`id` = `t1`.`city`
...
LEFT JOIN `sb_tblfloor` F ON `F`.`floorName` =`t1`.`floor`
ORDER BY `t1`.`dateConfirm` DESC -- yes, again
Together with
INDEX(is_sold, dateConfirm)
How can t1.projectId="" ? Isn't projectId the PRIMARY KEY? (This is one of many reasons for needing the SHOW CREATE TABLE.)
If my suggestion leads to "duplicate" rows (that is, multiple rows with the same propertyId), don't simply add back the GROUP BY propertyId. Instead figure out why, and avoid the need for the GROUP BY. (That is probably the performance issue.)
A likely case is the GROUP_CONCAT. A common workaround is to change from
GROUP_CONCAT( distinct( L.locality)) AS Localities,
...
LEFT JOIN `sa_localitiez` L ON `L`.`id` = `PL`.`localityId`
to
( SELECT GROUP_CONCAT(distinct locality)
FROM sa_localitiez
WHERE id = PL.localityId ) AS Localities
...
# and remove the JOIN
I am getting from the below query
SELECT co.mobility_theme, COUNT(DISTINCT ca.user_id) AS n
FROM courses_apply AS ca LEFT JOIN dy41s_courses AS co ON ca.course_id = co.id
WHERE ca.submission IS NULL AND ca.`call` LIKE '1b'
GROUP BY co.mobility_theme
ORDER BY co.mobility_theme ASC
The below result total (133)
mobility_theme n
1 =>70
4 =>18
5 =>45
What I want to do is: for each mobility theme (1,2 and 5), I have repeated users, so the total unique user_id should be (130), I cannot manage to get unique user_id group by (mobility theme), any help?
One approach is to arbitrarily choose one of the mobility themes. This method chooses the one with the minimum value:
select mobility_theme, COUNT(*) as Numusers
from (select ca.user_id, MIN(co.mobility_theme) as mobility_theme
from courses_apply ca LEFT JOIN
dy41s_courses co
ON ca.course_id = co.id
WHERE ca.submission IS NULL AND ca.`call` LIKE '1b'
group by ca.user_id
) caco
group by mobility_theme