MySQL request is:
SELECT DISTINCT a.field_department_color_value, DISTINCT a.nid, DISTINCT c.nid, DISTINCT c.field_oeuvre_notice_bibliography_value, DISTINCT c.field_oeuvre_notice_author_value, DISTINCT d.field_oeuvre_cartel_dimension_value, DISTINCT d.field_oeuvre_cartel_origin_value
FROM (
SELECT DISTINCT field_department_color_value,nid
FROM content_type_department) a,
( SELECT field_oeuvre_notice_dep_value
FROM content_field_oeuvre_notice_dep) b,
( SELECT field_oeuvre_notice_bibliography_value, field_oeuvre_notice_author_value, field_oeuvre_notice_cartel_nid
FROM content_type_oeuvre_notice) c,
( SELECT field_oeuvre_cartel_dimension_value, field_oeuvre_cartel_origin_value, nid
FROM content_type_oeuvre_cartel) d,
WHERE a.nid = b.field_oeuvre_notice_dep_value
AND d.nid = c.field_oeuvre_notice_cartel_nid
AND a.field_department_color_value LIKE 'greek'
LIMIT 0 , 8
it takes distinct just for the attribute field_department_color_value! while I want to do it for all the attributes in the SELECT section... Thank you
Try
SELECT DISTINCT a.field_department_color_value,
a.nid,
c.nid,
c.field_oeuvre_notice_bibliography_value,
c.field_oeuvre_notice_author_value,
d.field_oeuvre_cartel_dimension_value,
d.field_oeuvre_cartel_origin_value
FROM (
SELECT DISTINCT field_department_color_value,nid
FROM content_type_department) a,
( SELECT field_oeuvre_notice_dep_value
FROM content_field_oeuvre_notice_dep) b,
( SELECT field_oeuvre_notice_bibliography_value, field_oeuvre_notice_author_value, field_oeuvre_notice_cartel_nid
FROM content_type_oeuvre_notice) c,
( SELECT field_oeuvre_cartel_dimension_value, field_oeuvre_cartel_origin_value, nid
FROM content_type_oeuvre_cartel) d,
WHERE a.nid = b.field_oeuvre_notice_dep_value
AND d.nid = c.field_oeuvre_notice_cartel_nid
AND a.field_department_color_value LIKE 'greek'
LIMIT 0 , 8
Related
I have two tables with many-to-many relationship. I am trying to get values from both of the table where UserId is unique (I'm joining these table on this value)
I am rying to use pre aggregated query, but I get error
Column 'clv.ProbabilityAlive' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I understand that I should add these all values to group by clause, but then I am getting duplicates because peakClv values repeat.
If i am using simple join then it takes forever because of many to many relationship.
this is my query:
SELECT
distinct(s.userid) as userId,
s.ProbabilityAlive AS ProbabilityAlive,
a.PeakClv as PeakClv
FROM (
SELECT [UserId], ([sb].[ProbabilityAlive]) AS ProbabilityAlive
FROM clv as sb
WHERE sb.[CalculationDate] = '20200311'
GROUP BY [UserId]
) s
LEFT JOIN (
SELECT [UserId], PeakClv
FROM [dbo].[AdditionalClvData] where peakClv > 1
GROUP BY [UserId]
) a ON a.[UserId] = s.[UserId]
I am a bit out of ideas could someone lend a hand?
I also tried using distinct like one answer suggested:
SELECT
distinct (s.userid) as userId,
s.ProbabilityAlive AS ProbabilityAlive,
a.PeakClv as PeakClv
FROM (
SELECT DISTINCT ([UserId]), ([sb].[ProbabilityAlive]) AS
ProbabilityAlive
FROM clv as sb
WHERE sb.[CalculationDate] = '10/09/2020 00:00:00' AND sb.
[EstimatedNumberOfTransactionsLong] >= 0 AND sb.
[EstimatedNumberOfTransactionsLong] <= 5680 AND sb.[ClientId] = '16'
AND sb.[Product] = 'Total'
ORDER BY sb.[userId] asc OFFSET (1 - 1) * 10 ROWS FETCH NEXT 10 ROWS
ONLY
) s
LEFT JOIN (
SELECT DISTINCT [UserId], PeakClv
FROM [dbo].[AdditionalClvData]
) a ON a.[UserId] = s.[UserId]
but I still get duplicates:
If you have not aggregation function like SUM(), MAX() .. you can't use GROUP BY
SELECT
distinct s.userid as userId,
s.ProbabilityAlive AS ProbabilityAlive,
a.PeakClv as PeakClv
FROM (
SELECT DISTINCT [UserId], ([sb].[ProbabilityAlive]) AS ProbabilityAlive
FROM clv as sb
WHERE sb.[CalculationDate] = '20200311'
) s
LEFT JOIN (
SELECT DISTINCT [UserId], PeakClv
FROM [dbo].[AdditionalClvData] where peakClv > 1
) a ON a.[UserId] = s.[UserId]
if you need distinct (not repeated rows) use distinct
but looking to you img seems you need an aggregation function on PeakClv eg max() and group by
SELECT
s.userid as userId,
s.ProbabilityAlive AS ProbabilityAlive,
max(a.PeakClv) as PeakClv
FROM (
SELECT DISTINCT [UserId], ([sb].[ProbabilityAlive]) AS ProbabilityAlive
FROM clv as sb
WHERE sb.[CalculationDate] = '20200311'
) s
LEFT JOIN (
SELECT DISTINCT [UserId], PeakClv
FROM [dbo].[AdditionalClvData] where peakClv > 1
) a ON a.[UserId] = s.[UserId]
GROUP BY s.userid,
s.ProbabilityAlive
I have 3 tables engagements, patient_services and patients.
This Query
SELECT
ps_user_loc AS loc, COUNT(ps_id) AS ser, Count(Distinct ps_ur) AS patient
FROM patient_services
GROUP BY loc
UNION ALL
SELECT
eng_user_loc AS loc, COUNT(eng_id) AS ser, Count(Distinct eng_ur) AS patient
FROM engagements
WHERE LENGTH( eng_ur )>0
GROUP BY loc
returns
loc ser patient
CABOOLTURE 354 255
KILCOY 15 12
RBWH 1840 476
RBWH 34 27
REDCLIFFE 3 3
TPCH 11 9
So loc has doubles and I can calculate ser in php loop
But Patients count not unique because the same id in engagements and patient_services tables.
How to make select grouped by Location with number of Services and unique Patients in two tables(not in each like it now)?
Thank you.
What you are looking for is a full outer join. That would be two steps: 1. get loc/patient pairs from the tables and join, 2. aggregate by loc. In standard SQL:
select
loc,
sum(coalesce(ps.cnt, 0) + coalesce(e.cnt, 0)),
count(distinct patient)
from
(
select
ps_user_loc as loc,
ps_ur as patient,
count(*) as cnt
from patient_services
group by ps_user_loc, ps_ur
) ps
full outer join
(
select
eng_user_loc as loc,
eng_ur as patient
count(*) as cnt,
from engagements
where length(eng_ur) > 0
group by eng_user_loc, eng_ur
) e using (loc, patient)
group by loc;
Unfortunately MySQL doesn't support full outer joins (and the using clause neither). One way is to get all locs/patients first and then left join:
select
l.loc,
sum(coalesce(ps.cnt, 0) + coalesce(e.cnt, 0)),
count(distinct l.patient)
from
(
select ps_user_loc as loc, ps_ur as patient from patient_services
union
select eng_user_loc as loc, eng_ur as patient from engagements
) l
left outer join
(
select
ps_user_loc as loc,
ps_ur as patient,
count(*) as cnt
from patient_services
group by ps_user_loc, ps_ur
) ps on ps.loc = l.loc and ps.patient = l.patient
left outer join
(
select
eng_user_loc as loc,
eng_ur as patient,
count(*) as cnt
from engagements
where length(eng_ur) > 0
group by eng_user_loc, eng_ur
) e on e.loc = l.loc and e.patient = l.patient
group by l.loc;
I try to use a field from joined table "glpi_items_tickets" into a subquery like this :
SELECT
NAME
FROM
(
SELECT
NAME
FROM glpi_computers
WHERE id = git.items_id
) AS t1
UNION
(
SELECT
NAME
FROM glpi_monitors
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_networkequipments
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_printers
WHERE id = git.items_id
)
) AS aliasIT
but i have an error of type : "#1054 - Unknown Column 'git.items_id' in where clause"
The entire request :
SELECT
gt.id,
(
SELECT
NAME
FROM
(
SELECT
NAME
FROM glpi_computers
WHERE id = git.items_id
) AS t1
UNION
(
SELECT
NAME
FROM glpi_monitors
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_networkequipments
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_printers
WHERE id = git.items_id
)
) AS aliasIT
FROM glpi_tickets gt
INNER JOIN glpi_items_tickets git
ON gt.id = git.tickets_id;
Do you have a solution for used the field "glpi_items_tickets.items_id" into my subqueries?
SELECT ...
FROM
glpi_tickets gt
INNER JOIN glpi_items_tickets git
ON git.tickets_id = gt.id;
INNER JOIN
(
SELECT NAME, id FROM glpi_computers
UNION
SELECT NAME, id FROM glpi_monitors
UNION
SELECT NAME, id FROM glpi_networkequipments
UNION
SELECT NAME, id FROM glpi_printers
) g
ON g.id = git.items_id
Use the full table name instead of the alias.
Replace every git.items_id with glpi_items_tickets.items_id.
The alias does not exist during the compilation of the subquery, since the outer query (where you set your alias) can not be compiled until the inner querys are considered valid.
Mysql union how to Group returned 3 rows into single row
(
select CONCAT(c.Email,';', c.CCEmail,';', c.AdminEmail,';', c.HREmail) as Email
from companies c
Where companyid=#companyid#
)
union
(
select ClaimAdministratorEmail
from claimadminregion
where FIND_IN_SET(#companyid#, companyid)
)
union
(
select LossPreventionPersonEmail
from losspreventionregion
where FIND_IN_SET(#companyid#, companyid)
)
it return 3 rows but i want them in single row but don't know how
Try this:
SELECT CONCAT(c.Email,';', c.CCEmail,';', c.AdminEmail,';', c.HREmail,';', A.ClaimAdministratorEmail,';', B.LossPreventionPersonEmail) AS Email
FROM companies c
LEFT JOIN (SELECT #companyid# AS companyid, GROUP_CONCAT(ClaimAdministratorEmail SEPARATOR ';') ClaimAdministratorEmail
FROM claimadminregion WHERE FIND_IN_SET(#companyid#, companyid)
) A ON c.companyid = A.companyid
LEFT JOIN (SELECT #companyid# AS companyid, GROUP_CONCAT(LossPreventionPersonEmail SEPARATOR ';') LossPreventionPersonEmail
FROM losspreventionregion WHERE FIND_IN_SET(#companyid#, companyid)
) B ON c.companyid = B.companyid
WHERE companyid=#companyid#
I have multiple table for a project (sessions , charges and payments)
To get the sessions i'm doing the following :
SELECT
sess.file_id, SUM(sess.rate * sess.length) AS total
FROM
sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
This will return the amount that a specific student should pay
I also have another table "charges"
SELECT
file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM
file_charges
GROUP BY file_charges.file_id
And finally the payment query :
SELECT
file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM
file_payments
GROUP BY file_payments.file_id
Can i combine those 3 in a way to have :
Total = Payments - (Session + Charges)
Note that it could be negative so i could have file_id that exists in session , charges but not in payments and i could have a payment without sessions or charges ...
Edit : http://sqlfiddle.com/#!2/a90d9
One issue that needs to be addressed is whether one of these queries can be the "driver", in cases where we don't have rows for a given file_id returned by one or more of the queries. (e.g. there might be rows from sess, but none from file_payments. If we want to be sure to include every possible file_id that appears in any of the queries, we can get a list of all possible file_id with a query like this:
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
(NOTE: The UNION operator will remove any duplicates)
To get the specified resultset, we can use that query, along with "left joins" of the other three original queries. The outline of the query will be:
SELECT a.file_id, p.total_payment - ( s.total + c.total_charges)
FROM a
LEFT JOIN s ON s.file_id = a.file_id
LEFT JOIN c ON c.file_id = a.file_id
LEFT JOIN p ON p.file_id = a.file_id
ORDER BY a.file_id
In that statement a is a standin for the query that gets the set of all file_id values (as shown above). The s, c and p are standins for your three original queries, on sess, file_charges and file_payments, respectively.
If any of the file_id values is "missing" from any of the queries, we are going to need to substitute a zero for the missing value. We can use the IFNULL function to handle that for us.
This query should return the specified resultset:
SELECT a.file_id
, IFNULL(p.total_payment,0) - ( IFNULL(s.total,0) + IFNULL(c.total_charges,0)) AS t
FROM ( -- all possible values of file_id
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
LEFT
JOIN ( -- the amount that a specific student should pay
SELECT sess.file_id, SUM(sess.rate * sess.length) AS total
FROM sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
) s
ON s.file_id = a.file_id
LEFT
JOIN ( -- charges
SELECT file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM file_charges
GROUP BY file_charges.file_id
) c
ON c.file_id = a.file_id
LEFT
JOIN ( -- payments
SELECT file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM file_payments
GROUP BY file_payments.file_id
) p
ON p.file_id = a.file_id
ORDER BY a.file_id
(The EXPLAIN for this query is not going to be pretty, with four derived tables. On really large sets, performance may be horrendous. But the resultset returned should meet the specification.)
Beware of queries that JOIN all three tables together... that will likely give incorrect results when there are (for example) two (or more) rows for the same file_id in the file_payment table.
There are other approaches to getting an equivalent result set, but the query above answers the question: "how can i get the results of these queries joined together into a total".
Using correlated subqueries
Here's another approach, using correlated subqueries in the SELECT list...
SELECT a.file_id
, IFNULL( ( SELECT SUM(file_payments.paymentAmount) FROM file_payments
WHERE file_payments.file_id = a.file_id )
,0)
- ( IFNULL( ( SELECT SUM(sess.rate * sess.length) FROM sess
WHERE sess.file_id = a.file_id )
,0)
+ IFNULL( ( SELECT SUM(file_charges.price) FROM file_charges
WHERE file_charges.file_id = a.file_id )
,0)
) AS tot
FROM ( -- all file_id values
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
ORDER BY a.file_id
try this
SELECT sess.file_id, SUM(file_payments.paymentAmount) - (SUM(sess.rate * sess.length)+SUM(file_charges.price)) as total_payment FROM sess , file_charges , file_payments
WHERE sess.sessionDone = 1
GROUP BY total_payment
EDIT.
SELECT a.file_id
, IFNULL(p.total_payment,0) - ( IFNULL(s.total,0) + IFNULL(c.total_charges,0)) AS tot
FROM (
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
LEFT JOIN (
SELECT sess.file_id, SUM(sess.rate * sess.length) AS total
FROM sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
) s
ON s.file_id = a.file_id
LEFT JOIN (
SELECT file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM file_charges
GROUP BY file_charges.file_id
) c
ON c.file_id = a.file_id
LEFT JOIN (
SELECT file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM file_payments
GROUP BY file_payments.file_id
) p
ON p.file_id = a.file_id
ORDER BY a.file_id
DEMO HERE