I have 3 different table named job_party, job_party_details and job_party_delv. In which job_party is the main table and others are detailed tables. I am trying to gather data date by date from all these tables. I wrote the following query and getting perfect data but the problem is data of job_party_details comes first and job_party_delv comes latter. I want all data at once as per the date.
SELECT job_party.on_date
, SUM(job_party_details.qty) as detail_qty
, NULL as delv
FROM job_party_details d
JOIN job_party p
on d.jp_id = p.id
where p.party_id = 9
and d.i_id = 1
GROUP
BY p.on_date
UNION
SELECT p.on_date
, NULL as detail_qty
, SUM(d.d_qty) as delv
FROM job_party_delv d
JOIN job_party p
on d.jp_id = p.id
where p.party_id = 9
and d.i_id = 1
GROUP
BY p.on_date
Replace NULL with 0 then make the query as a sub-query and perform another SUM on the outer query GROUP BY on_date like this:
SELECT on_date,SUM(detail_qty) as detail_qty, SUM(delv) as delv
FROM
(SELECT job_party.on_date
, SUM(job_party_details.qty) as detail_qty
, 0 as delv
FROM job_party_details d
JOIN job_party p
on d.jp_id = p.id
where p.party_id = 9
and d.i_id = 1
GROUP
BY p.on_date
UNION
SELECT p.on_date
, 0 as detail_qty
, SUM(d.d_qty) as delv
FROM job_party_delv d
JOIN job_party p
on d.jp_id = p.id
where p.party_id = 9
and d.i_id = 1
GROUP
BY p.on_date) A GROUP BY on_date;
I am trying to retrieve everything from client and bond table where the client.id is not equal to bond.client and bond client.bond is not equal to bond.id. My query did not work and returns the whole list instead. How can i solve this problem? My query wants to output 4 , 5 from client table and 5, 5 from bond table as the result
Client table
Id Bond
1 2
2 3
4 5
Bond table
Id Client
2 1
3 2
5 5
.
SELECT * FROM `client_table`
INNER JOIN `bond_table`
where client_table.id != bond_table.client and client_table.bond != bond_table.id
Please try this:
SELECT c.ClientID, c.BondID from client_table c
left join bond_table b
on c.clientID = b.clientID
where b.clientID is null
UNION
SELECT b.ClientID, b.BondID from bond_table b
left join client_table c
on c.clientID = b.clientID
where c.clientID is null
could be using not in clause
SELECT * FROM `client_table`
INNER JOIN `bond_table` on client_table.id
not in ( select bond_table.client from bond)
AND client_table.bond not in ( select bond_table.id from bond)
but based on the resukt you show in the comment you should use OR (and not AND)
SELECT * FROM `client_table`
INNER JOIN `bond_table` on client_table.id
not in ( select bond_table.client from bond)
OR client_table.bond not in ( select bond_table.id from bond)
I have query:
SELECT p.`obj_id` ,
p.`alt_name` ,
o.`name`,
p.`id`,
oc.`text_val`,
oc.`float_val`
FROM `cms3_hierarchy` p
LEFT JOIN `cms3_objects` o
ON p.`obj_id` = o.`id`
LEFT JOIN `cms3_object_content` oc
ON p.`obj_id` = oc.`obj_id`
WHERE (oc.`field_id` = 221 OR oc.`field_id` = 248 )
AND (p.`rel`=903687) LIMIT 0,50
But answer like this:
obj_id name id 221 248
1 first 2 null
1 first null 3
Well, i have one obj_id with different values.
But for me this is look like this:
obj_id name id 221 248
1 first 2 3
How to do this?
Conditions on the right table of a LEFT JOIN should be specified only inside the ON clause, when they are in the WHERE clause, the join automatically turns into an INNER JOIN because of NULL comparison.
Also, use IN() to compare the same column to multiple values instead of OR . I also used MAX() to group the rows into one row, so :
SELECT p.obj_id , p.alt_name , o.name,p.id,
MAX(CASE WHEN oc.field_id = 221 THEN oc.text_val END) as col_221,
MAX(CASE WHEN oc.field_id = 1123 THEN oc.text_val END) as col_1123,
MAX(oc.float_val)
FROM cms3_hierarchy p
LEFT JOIN cms3_objects o
ON p.obj_id = o.id
LEFT JOIN cms3_object_content oc
ON p.obj_id = oc.obj_id and oc.field_id in(221,248,1123)
WHERE p.rel=903687
LIMIT 0,50
GROUP BY p.obj_id , p.alt_name , o.name,p.id
I have two tables in MySQL that I'm comparing with the following attributes:
tbl_fac : facility_id, chemical_id, criteria
10 , 25 , 50
10 , 26 , 60
10 , 27 , 60
11 , 25 , 30
11 , 27 , 31
etc...
tbl_samp: sample_id, chemical_id, result
5 , 25 , 51
5 , 26 , 61
6 , 25 , 51
6 , 26 , 61
6 , 27 , 500
etc....
These tables are joined by chemical_id (many-to-many---- ugh), and there are several thousand facility_id's, and several hundred chemical_id's for each facility_id. There are also several thousand sample_id's, each with several hundred chemical_id's for each sample_id. All-in-all, there are around 500,000 records in tbl_fac, and 1,000,000+ records in tbl_samp.
I'm trying to extract three groups of sample_id's from this dataset:
Group 1: any sample_id where tbl_samp.result > tbl_fac.criteria (i.e., result exceeds criteria)
Group 2: any sample_id where tbl_samp.result < tbl_fac.criteria, AND all tbl_fac.chemical_id's are present for that sample_id (i.e., result is less than criteria, and everything is there)
Group 3: any sample_id where tbl_samp.result < tbl_fac.criteria, BUT one or more tbl_fac.chemical_id's are missing in the sample_id (i.e., result is less than criteria, but something is missing)
Here's the Question: How do I get all three Groups efficiently in one query?
I've tried:
select *
from tbl_fac
left join tbl_samp
on tbl_fac.chemical_id = tbl_samp.chemical_id
But this only yields values that are missing for the entire dataset (not the individual samples). I have a hackish query working that uses a third table to join tbl_fac and tbl_samp, but it is so ugly I'm actually embarrassed to post it....
As always, many thanks in advance for your thoughts on this one!
Cheers,
Josh
EDIT: Ideally, I would like the sample_id and Group returned -- with just one Group per sample ID (my knowledge of the data indicates that they will always fall into one of the three categories above).
This answer makes the assumption that there is a unique constraint on facility_id and chemical_id in tbl_fac and a unique constraint on sample_id and chemical_id in tbl_samp. What I did was build up the query one step at a time. Whether this is efficient remains to be seen.
Group 1: any sample_id where tbl_samp.result > tbl_fac.criteria (i.e., result exceeds criteria)
SELECT tbl_samp.sample_id,
'ResultsGreaterThanCriteria' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result > tbl_fac.criteria
GROUP BY tbl_samp.sample_id
Group 2: any sample_id where tbl_samp.result < tbl_fac.criteria, AND all tbl_fac.chemical_id's are present for that sample_id (i.e., result is less than criteria, and everything is there)
SELECT tbl_samp.sample_id,
'ResultLessThanCriteriaAndAllChems' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result < tbl_fac.criteria
AND NOT EXISTS (SELECT *
FROM tbl_fac tf
LEFT JOIN tbl_samp ts
ON tf.chemical_id = ts.chemical_id
WHERE ts.chemical_id IS NULL
AND tbl_samp.sample_id = ts.sample_id)
GROUP BY tbl_samp.sample_id
Group 3: any sample_id where tbl_samp.result < tbl_fac.criteria, BUT one or more tbl_fac.chemical_id's are missing in the sample_id (i.e., result is less than criteria, but something is missing)
SELECT tbl_samp.sample_id,
'ResultsLessThanCriteriaWithMissingChems' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result < tbl_fac.criteria
AND EXISTS (SELECT *
FROM tbl_fac tf
LEFT JOIN tbl_samp ts
ON tf.chemical_id = ts.chemical_id
WHERE ts.chemical_id IS NULL
AND tbl_samp.sample_id = ts.sample_id)
GROUP BY tbl_samp.sample_id
And finally, you union all three queries together and get:
SELECT tbl_samp.sample_id,
'ResultsGreaterThanCriteria' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result > tbl_fac.criteria
GROUP BY tbl_samp.sample_id
UNION ALL
SELECT tbl_samp.sample_id,
'ResultLessThanCriteriaAndAllChems' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result < tbl_fac.criteria
AND NOT EXISTS (SELECT *
FROM tbl_fac tf
LEFT JOIN tbl_samp ts
ON tf.chemical_id = ts.chemical_id
WHERE ts.chemical_id IS NULL
AND tbl_samp.sample_id = ts.sample_id)
GROUP BY tbl_samp.sample_id
UNION ALL
SELECT tbl_samp.sample_id,
'ResultsLessThanCriteriaWithMissingChems' AS samplegroup
FROM tbl_fac
INNER JOIN tbl_samp
ON tbl_fac.chemical_id = tbl_samp.chemical_id
WHERE tbl_samp.result < tbl_fac.criteria
AND EXISTS (SELECT *
FROM tbl_fac tf
LEFT JOIN tbl_samp ts
ON tf.chemical_id = ts.chemical_id
WHERE ts.chemical_id IS NULL
AND tbl_samp.sample_id = ts.sample_id)
GROUP BY tbl_samp.sample_id
SELECT
sample_id,
IF(result = criteria, -1, /* unspecified behavior */
IF(result > criteria, 1,
IF(nb_chemicals = total_nb_chemicals, 2, 3))) AS grp
FROM (
SELECT s.result, s.sample_id, f.criteria, f.chemical_id,
COUNT(DISTINCT f.chemical_id) AS nb_chemicals
FROM tbl_fac f JOIN tbl_samp s
ON f.chemical_id = s.chemical_id
GROUP BY s.sample_id
) t
CROSS JOIN (
SELECT COUNT(DISTINCT chemical_id) AS total_nb_chemicals
FROM tbl_fac
) u
New solution:
SELECT
s.sample_id,
IF(s.result = f.criteria, -1, /* unspecified behavior */
IF(s.result > f.criteria, 1,
IF(sample_nb_chemicals = total_nb_chemicals, 2, 3))) AS grp
FROM
tbl_fac f JOIN tbl_samp s
ON f.chemical_id = s.chemical_id
JOIN (
SELECT s.sample_id,
COUNT(DISTINCT f.chemical_id) AS sample_nb_chemicals
FROM tbl_fac f JOIN tbl_samp s
ON f.chemical_id = s.chemical_id
GROUP BY s.sample_id
) u
ON s.sample_id = u.sample_id
CROSS JOIN (
SELECT COUNT(DISTINCT chemical_id) AS total_nb_chemicals
FROM tbl_fac
) v
GROUP BY sample_id, grp
I am having a bit of a brain block with this problem and I am finding it hard to search for a solution because I cant phrase the question correctly to bring up the relevant information.
I am trying to get back "fProduct" record from the table below where it has a "fAttribute"
of 2 and 20.
id fAttribute fProduct
19 2 2967
48 2 2923
50 2 3008
51 20 3008
52 2 2295
53 20 2295
My statment below produces 0 results when I would expect to return fProduct's 2295 and 3008.
SELECT fProduct
FROM tableName
WHERE fAttribute = 2 AND fAttribute = 20
GROUP BY fProduct
Can anyone help please?
You can either use INNER JOINS or use EXISTS conditions:
INNER JOIN:
SELECT DISTINCT a.fProduct
FROM MyTable a
INNER JOIN MyTable b ON a.fProduct = b.fProduct AND b.fAttribute = 2
INNER JOIN MyTable c ON a.fProduct = c.fProduct AND c.fAttribute = 20
EXISTS:
SELECT afproduct
FROM MyTable a
WHERE EXISTS (SELECT b.id FROM MyTable b WHERE a.fProduct = b.fProduct AND b.fAttribute = 2)
AND EXISTS (SELECT c.id FROM MyTable c WHERE a.fProduct = c.fProduct AND c.fAttribute = 20)
A join should help:
SELECT distinct a.fProduct
FROM tableName as a
join tableName as b on b.product = a.product
WHERE a.fAttribute = 2 and b.fAttribute = 20
Since your are already doing a GROUP BY just change your WHERE clause to an OR or an IN and add the HAVING COUNT(fattribute) = 2 which makes sure it has both.
SELECT fproduct
FROM tablename
WHERE fattribute IN (2 , 20)
GROUP BY fproduct
HAVING COUNT(fattribute) = 2