I'm trying to divide the numeric results from 2 pretty different queries.
The end result should be Query 1 DIVIDED BY Query 2
Query 1 =
SELECT COUNT(DISTINCT(table1.ID)) AS count_1
FROM table1
INNER JOIN op
INNER JOIN Org
ON table1.EID = op.id
AND Op.OrgID = Org.ID
WHERE table1.TitleID = 123
AND op.BrandID = 1
AND op.Start <= NOW() AND op.End >= NOW();
Query 2 =
SELECT COUNT(DISTINCT user.id) AS count_2
FROM table1 INNER JOIN user INNER JOIN ur
ON table1.EID = user.id AND ur.userID = user.id
WHERE
user.BrandID = 1
AND table1.TitleID = 123
AND ur.role = 0
AND user.Inactive = 0;
Sure! You can use subselects to achieve this, though it will be pretty verbose!
SELECT
(
SELECT COUNT(DISTINCT(table1.ID)) AS count_1
FROM table1
INNER JOIN op
INNER JOIN Org
ON table1.EID = op.id
AND Op.OrgID = Org.ID
WHERE table1.TitleID = 123
AND op.BrandID = 1
AND op.Start <= NOW() AND op.End >= NOW()
) / (
SELECT COUNT(DISTINCT user.id) AS count_2
FROM table1 INNER JOIN user INNER JOIN ur
ON table1.EID = user.id AND ur.userID = user.id
WHERE
user.BrandID = 1
AND table1.TitleID = 123
AND ur.role = 0
AND user.Inactive = 0
);
Format however it feels the least ugly to you.
Use sub queries like this:
SELECT Q1.count_1 / Q2.Count_2
FROM
( ... Query1 ...) AS Q1
JOIN
( ... Query2 ...) AS Q2
ON 1=1
Replace Query1 and Query2 as your code.
Like this:
SELECT count_1 / count_2
FROM (SELECT COUNT(*) count_1 FROM foo) f
JOIN (SELECT COUNT(*) count_2 FROM bar) b ON 1=1;
http://sqlfiddle.com/#!2/c215e/1
Related
I have a query that is giving me different results when i enclosed it in Parentheses, however when I run it without Parentheses its giving me different results. I want to apply Union in between so I have to use Parentheses as without union doesn't work.
The query is as follows:
SELECT Distinct
recurring_billing.id,
recurring_billing.kid_id,
recurring_billing.class_id,
recurring_billing.app_id,
recurring_billing.Region_ID,
CC.month_name,
CC.billing_year,
CASE
WHEN
CC.month_name = recurring_billing.billing_month
AND CC.billing_year = recurring_billing.billing_year
THEN
recurring_billing.billing_status
ELSE
'Pending'
END
AS billing_status, tblkids.kid_name, tblkids.kid_Lastname, tblkids.kid_EMail, tbl_app.app_CCExp AS cc_exp, tbl_app.app_CCName AS cc_name, tbl_app.app_CCNumber AS cc_number, tbl_app.app_CCType AS cc_type, tblclasses.cla_EndDate, tblclassdays.classday_day, CC.remainingclasses, tbl_app.cost_per_class, CC.remainingclasses * tbl_app.cost_per_class AS cost_amount,
CASE
WHEN
OP.override_amt IS NOT NULL
THEN
OP.override_amt
ELSE
CC.remainingclasses * tbl_app.cost_per_class
END
AS pmt_amount,
CASE
WHEN
OP.process_payment = False
THEN
OP.process_payment
ELSE
True
END
AS process_payment
FROM
recurring_billing
LEFT JOIN
tblkidsxclass
ON recurring_billing.kid_id = tblkidsxclass.kxc_kidid
AND recurring_billing.app_id = tblkidsxclass.kxc_appid
LEFT JOIN
tbl_app
ON recurring_billing.app_ID = tbl_app.app_ID
LEFT JOIN
tblkids
ON recurring_billing.kid_id = tblkids.kid_ID
LEFT JOIN
tblclasses
ON recurring_billing.class_id = tblclasses.cla_ID
LEFT JOIN
tblclassdays
ON tblclasses.cla_ID = tblclassdays.classday_classID
INNER JOIN
(
SELECT
MONTHNAME(classday_day) AS month_name,
YEAR(classday_day) AS billing_year,
cla_ID,
COUNT(classday_classid) AS remainingclasses,
c.cost_per_class AS cost_per_class,
COUNT(classday_classid) * cost_per_class AS TotalClassCost
FROM
tblclassdays
JOIN
(
SELECT
tblclasses.cla_ID,
tblclasses.cost_per_class,
tblclasses.cla_nextclass AS next1,
tblclasses_1.cla_nextclass AS next2
FROM
tblclasses
LEFT JOIN
tblclasses AS tblclasses_1
ON tblclasses.cla_nextclass = tblclasses_1.cla_ID
WHERE
tblclasses.cla_ID IN
(
SELECT DISTINCT
recurring_billing.class_id
FROM
recurring_billing
LEFT JOIN
tblkidsxclass
ON recurring_billing.kid_id = tblkidsxclass.kxc_kidid
AND recurring_billing.app_id = tblkidsxclass.kxc_appid -- LEFT JOIN tblkids ON recurring_billing.kid_id = tblkids.kid_ID
LEFT JOIN
tblclasses
ON recurring_billing.class_id = tblclasses.cla_ID -- LEFT JOIN tblclassdays ON tblclasses.cla_ID = tblclassdays.classday_classID
WHERE
ISNULL(tblkidsxclass.kxc_dropoutdate)
AND tblkidsxclass.pmt_option = 'Recurring'
AND tblclasses.cla_active = TRUE -- AND tblclasses.cla_EndDate >= NOW()
GROUP BY
recurring_billing.id
)
)
c
ON tblclassdays.classday_classid IN
(
c.cla_ID,
c.next1,
c.next2
)
WHERE
tblclassdays.classday_noclass = FALSE
AND MONTH(classday_day) = 11
AND YEAR(classday_day) = 2020
AND
(
CONCAT(CAST(classday_day AS DATE), ' ', CAST(classday_endtime AS TIME)) > CAST(CURDATE() AS DATETIME)
)
GROUP BY
cla_ID
)
CC
ON CC.cla_ID = tblclassdays.classday_classID
LEFT JOIN
override_payments OP
ON recurring_billing.app_id = OP.app_id
AND recurring_billing.kid_id = OP.kid_id
AND CC.month_name = OP.billing_month
AND CC.billing_year = OP.billing_year
WHERE
ISNULL(tblkidsxclass.kxc_dropoutdate)
AND tblkidsxclass.pmt_option = 'Recurring'
AND tblclasses.cla_active = TRUE
AND recurring_billing.kid_id NOT IN
(
SELECT
kid_id
from
recurring_billing
where
billing_month = 'November'
and billing_year = '2020'
)
-- AND tblclasses.cla_EndDate >= NOW()
GROUP BY
recurring_billing.id
ORDER BY
recurring_billing.id ASC
Same query if enclosed in Parentheses will give me different results.
Parentheses are not required for a UNION statement. The following 2 union statements both work and yield the same results.
SELECT 1 UNION SELECT 2;
(SELECT 1) UNION (SELECT 2);
When I execute this query, it works fine:
SELECT
pr.pr_nombre , cl.cl_nomcorto,
mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951 as Interes,
mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951*.049 as WH,
(select pr_id from dbo.nonplusultra(cr.pr_id) where pr_renew_ref is null) as Agrupador
FROM movcuentas mc
inner join corridas cr on mc.cr_id = cr.cr_id
inner join clientes cl on cr.cl_id = cl.cl_id
inner join prestamos pr on cr.pr_id = pr.pr_id
WHERE (mc_concepto = 'Amort Int') AND (tm_id = 3) AND MONTH(mc_fecha) = 2 AND YEAR(mc_fecha) = 2017
ORDER BY pr.pr_nombre
I get this:
Query results
Now I need to show it adding columns "Interes" and "WH" on records with same "Agrupador", something like this:
SELECT
pr.pr_nombre , cl.cl_nomcorto,
sum(mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951) as Interes,
sum(mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951*.049) as WH,
(select pr_id from dbo.nonplusultra(cr.pr_id) where pr_renew_ref is null) as Agrupador
FROM movcuentas mc
inner join corridas cr on mc.cr_id = cr.cr_id
inner join clientes cl on cr.cl_id = cl.cl_id
inner join prestamos pr on cr.pr_id = pr.pr_id
WHERE (mc_concepto = 'Amort Int') AND (tm_id = 3) AND MONTH(mc_fecha) = 2 AND YEAR(mc_fecha) = 2017
GROUP BY pr.pr_nombre , cl.cl_nomcorto, (select pr_id from dbo.nonplusultra(cr.pr_id) where pr_renew_ref is null)
ORDER BY pr.pr_nombre
And I get this error message:
Msg 144, Level 15, State 1, Line 12
Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
Any help will be welcome.
Can you make use of CTE here?
;WITH CTE as
(
SELECT
pr.pr_nombre , cl.cl_nomcorto,
mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951 as Interes,
mc_cant * dbo.tipo_cambio(cr.mo_id,3,mc_fecha)/0.951*.049 as WH,
(select pr_id from dbo.nonplusultra(cr.pr_id) where pr_renew_ref is null) as Agrupador
FROM movcuentas mc
inner join corridas cr on mc.cr_id = cr.cr_id
inner join clientes cl on cr.cl_id = cl.cl_id
inner join prestamos pr on cr.pr_id = pr.pr_id
WHERE (mc_concepto = 'Amort Int') AND (tm_id = 3) AND MONTH(mc_fecha) = 2 AND YEAR(mc_fecha) = 2017
ORDER BY pr.pr_nombre
)
select pr_nombre,cl_nomcorto,sum(Interes),sum(WH),Agrupador
from CTE
group by pr_nombre,cl_nomcorto,Agrupador
order by pr_nombre
I'm trying get last result from a table using the data_coleta (DATE) and servico_id as base. The query is working but is very slow. How can I optimize?
select t1.* from
amostra_ensaio_full t1
where
t1.cliente_id = 6 and t1.tipo_id <> 1
and t1.data_coleta = (SELECT max(s1.data_coleta) from amostra_ensaio_full s1 where t1.cliente_id = s1.cliente_id and s1.tipo_id <> 1 and s1.tipo_id = t1.tipo_id)
and t1.servico_id = (SELECT max(s2.servico_id) from amostra_ensaio_full s2 where t1.cliente_id = s2.cliente_id and s2.tipo_id <> 1 and s2.tipo_id = t1.tipo_id)
GROUP by t1.cliente_id , t1.tipo_id
You can probably speed up this query using indexes.
The query is:
select t1.*
from amostra_ensaio_full t1
where t1.cliente_id = 6 and t1.tipo_id <> 1 and
t1.data_coleta = (SELECT max(s1.data_coleta)
from amostra_ensaio_full s1
where t1.cliente_id = s1.cliente_id and
s1.tipo_id <> 1 and
s1.tipo_id = t1.tipo_id
) and
t1.servico_id = (SELECT max(s2.servico_id)
from amostra_ensaio_full s2
where t1.cliente_id = s2.cliente_id and
s2.tipo_id <> 1 and
s2.tipo_id = t1.tipo_id
)
GROUP by t1.cliente_id , t1.tipo_id;
You want the following index for the query: amostra_ensaio_full(cliente_id, tipo_id, servico_id).
The condition tipo_id <> 1 is unnecessary in the subquery, but it causes no harm.
Tks Gordon but the query still slow. Maybe I found the answer searching more.
SELECT a.*
FROM amostra_ensaio_full a
INNER JOIN
(
SELECT MAX(data_coleta) maxDate , tipo_id, cliente_id
FROM amostra_ensaio_full
GROUP BY cliente_id, tipo_id
) b ON a.cliente_id = b.cliente_id and a.tipo_id = b.tipo_id and b.maxDate = a.data_coleta
GROUP by a.cliente_id ,a.tipo_id
Assume tables
team: id, title
team_user: id_team, id_user
I'd like to select teams with just and only specified members. In this example I want team(s) where the only users are those with id 1 and 5, noone else. I came up with this SQL, but it seems to be a little overkill for such simple task.
SELECT team.*, COUNT(`team_user`.id_user) AS cnt
FROM `team`
JOIN `team_user` user0 ON `user0`.id_team = `team`.id AND `user0`.id_user = 1
JOIN `team_user` user1 ON `user1`.id_team = `team`.id AND `user1`.id_user = 5
JOIN `team_user` ON `team_user`.id_team = `team`.id
GROUP BY `team`.id
HAVING cnt = 2
EDIT: Thank you all for your help. If you want to actually try your ideas, you can use example database structure and data found here: http://down.lipe.cz/team_members.sql
How about
SELECT *
FROM team t
JOIN team_user tu ON (tu.id_team = t.id)
GROUP BY t.id
HAVING (SUM(tu.id_user IN (1,5)) = 2) AND (SUM(tu.id_user NOT IN (1,5)) = 0)
I'm assuming a unique index on team_user(id_team, id_user).
You can use
SELECT
DISTINCT id,
COUNT(tu.id_user) as cnt
FROM
team t
JOIN team_user tu ON ( tu.id_team = t.id )
GROUP BY
t.id
HAVING
count(tu.user_id) = count( CASE WHEN tu.user_id = 1 or tu.user_id = 5 THEN 1 ELSE 0 END )
AND cnt = 2
Not sure why you'd need the cnt = 2 condition, the query would get only those teams where all of users having the ID of either 1 or 5
Try This
SELECT team.*, COUNT(`team_user`.id_user) AS cnt FROM `team`
JOIN `team_user` ON `team_user`.id_team = `team`.id
where `team_user`.id_user IN (1,5)
GROUP BY `team`.id
HAVING cnt = 2
How do I link across and get the variables of three tables, I want to get the linked facilities for each room but currently my record seems to be returning nothing.
I would like to return a new column header for facilities as well: http://sqlfiddle.com/#!2/8d6ca/25
The fiddle can be found here
SELECT *
FROM ts_room rm
WHERE
NOT EXISTS (
SELECT 1
FROM ts_roompref rp
JOIN ts_request rq ON rp.request_id = rq.id AND day_id = 1 AND period_id = 1
WHERE rm.id = rp.room_id)
AND NOT EXISTS (
SELECT 1
FROM ts_roompref rp
JOIN ts_allocation a ON rp.request_id = a.request_id AND a.status = "Allocated"
WHERE rm.id = rp.room_id)
AND EXISTS (
SELECT 1
FROM ts_roomfacilities f
JOIN ts_room b ON f.room_id = b.id
WHERE rm.id = f.room_id AND
f.facilities_id=2);
AND EXISTS (
SELECT 1
FROM ts_facilities f1
JOIN ts_roomfacilities c ON f2.id = c.id
WHERE rm.id = f.room_id);
There's a ; in the middle of your query which you should remove