Where clause on count column - mysql

I have two tables pdc and class
select roll_no as roll,sum(pdc.amount) as amount,count(amount) as given,
stu_profile.name,f_name,scholarship,class_id,batch_id,statuss
from stu_profile left join
pdc
on pdc.roll=stu_profile.roll_no
where 1 and class_id!='' and given=0
group by roll
I want a condition on count (amount) column

Use having clause instead
. . .
having count(amount) = 0;

Then answer to your question is the having clause. But, your query is malformed and would not work in most databases, including the more recent versions of MySQL.
The solution is simple: In an aggregation query, the only columns in the SELECT should be the GROUP BY keys or arguments to aggregation functions.
Let me assume that you want:
select p.roll_no as roll, sum(pdc.amount) as amount,
count(pdc.amount) as given,
p.name, p.f_name, p.scholarship, p.class_id, p.batch_id, p.statuss
from stu_profile p left join
pdc
on pdc.roll = p.roll_no
where 1 and class_id <> ''
group by roll, p.name, p.f_name, p.scholarship, p.class_id, p.batch_id, p.statuss
You can then just add something like:
having given = 0

Related

Fetching data from many to many relationship

I am having 3 tables namely
category
case
cost
office_id
category_id
linked to >
category_id
case_number
linked to >
case_number
total_cost
Problem:
I need to fetch the total number of case and their respective cost for every office id which is there in category table
Query I have written:
select cm_c_d.case_number,cm_c.office_id,count(*) as case_count from categories as cm_c
join case as cm_c_d on cm_c.category_id = cm_c_d.category_id
join cost on cm_c_d.case_number = cost.case_number group by office_id;
but I don't think this will provide the desired result as joining all the three tables will increase the row count.
Updated SQL query:
select cm_c.office_id
, count(DISTINCT cm_costs.case_number) as case_count
, SUM(total_charge) AS overall_cost
from cm_categories as cm_c
JOIN cm_case_details as cm_c_d
on cm_c.category_id = cm_c_d.category_id
join cm_costs
on cm_c_d.case_number = cm_costs.case_number
group by cm_c.office_id
;
If you want distinct case count (adjusted with the new table names):
SELECT cm_c.office_id
, COUNT(DISTINCT cm_costs.case_number) AS case_count
, SUM(total_charge) AS overall_cost
FROM cm_categories AS cm_c
JOIN cm_case_details AS cm_c_d ON cm_c.category_id = cm_c_d.category_id
JOIN cm_costs ON cm_c_d.case_number = cm_costs.case_number
GROUP BY cm_c.office_id
;
COUNT(DISTINCT x) means count the distinct number of x values for each group.
Also notice we needed to quote the case table name. As mentioned in prior comments, that's a reserved word. I suggest avoiding use of reserved words as identifiers (table, column, etc names).
I've removed case_number from your SELECT list because it's not functionally dependent on the GROUP BY terms. That means the design/query does not guarantee that there is at most one case_number for each office_id.
If you want a case_number in the select list, you would need to use a form of aggregation (like COUNT), as follows:
SELECT cm_c.office_id
, COUNT(DISTINCT cm_costs.case_number) AS case_count
, SUM(total_charge) AS overall_cost
, MIN(cost.case_number) AS some_case_number
, GROUP_CONCAT(cost.case_number) AS all_cases
FROM cm_categories AS cm_c
JOIN cm_case_details AS cm_c_d ON cm_c.category_id = cm_c_d.category_id
JOIN cm_costs ON cm_c_d.case_number = cm_costs.case_number
GROUP BY cm_c.office_id
;
Be careful of GROUP_CONCAT for very large sets, since that result column width could get rather wide.
Here's the test case, with necessary adjustments:
Test case
For more detail on GROUP BY and functional dependence, see the following links:
group-by-handling
group-by-functional-dependence

How to show last data (max data) of each group by on mysql

I have query like below:
SELECT kd.id_karir, kd.nama, kd.kelamin,
(YEAR(NOW())-YEAR(tanggal)) usia, MAX(pf.jenis), pf.jenis,
pf.nama AS pendidikan, pf.jurusan, kd.alamat, kd.telepon,
kd.handphone, kd.email, kd.tempat AS tempat_lahir,
kd.tanggal AS tanggal_lahir
FROM keadaan_diri AS kd
LEFT OUTER JOIN pendidikan_formal AS pf ON (kd.id_karir = pf.id_karir)
WHERE kd.id_karir = 'P1409047'
GROUP BY kd.id_karir
ORDER BY kd.nama ASC, pf.jenis DESC
I mean to returning the last data on the table pendidikan_formal using max and group but the query doesn't work.
First of all, you can / should (depending on the MySQL configuration) only select and order by columns that are part of your group by clause. For all other columns, you have to specify an aggregation function. For example, let's say you have two records of humans, both have the same name and a different age. When you group by name, you have to choose one of the two age values (max, min, average, ...). If you don't care which, you could turn off sql mode only full group by. I wouldn't suggest that however.
In order to get the one record with some maximum value however, group by is not the right approach. Take a look at these examples:
Subselect:
SELECT name, age, ...
FROM humans
WHERE age=(SELECT MAX(age) FROM humans);
Order by and limit:
SELECT name, age, ...
FROM humans
ORDER BY age DESC
LIMIT 1;
Left join:
SELECT name, age, ...
FROM humans h1
LEFT JOIN humans h2 ON h1.age < h2.age
WHERE h2.age IS NULL;
Now if you want all maximum rows per group, check one of these answers with tag greatest-n-per-group.
You can use a correlated subquery. Your question is a bit vague; I assume that id_karir is the group and tanggal is the date.
If I understand correctly, this would apply to your query as:
SELECT kd.id_karir, kd.nama, kd.kelamin,
(YEAR(NOW())-YEAR(tanggal)) usia, pf.jenis, pf.jenis,
pf.nama AS pendidikan, pf.jurusan, kd.alamat, kd.telepon,
kd.handphone, kd.email, kd.tempat AS tempat_lahir,
kd.tanggal AS tanggal_lahir
FROM keadaan_diri kd LEFT OUTER JOIN
pendidikan_formal pf
ON kd.id_karir = pf.id_karir AND
pf.tanggal = (SELECT MAX(pf2.tanggal) FROM pendidikan_formal pf2 WHERE pf2.id_karir = pf.id_karir)
This is not an aggregation query. This is a filtering query.

Why INNER JOIN dont not work correct?

I have one SQL query with INNER JOINS. I need to get all offers from table offers.
Table offers is empty now. But the following query returns one row with NULL field.
Why is it returned? How to fix that? I need to return 0 rows if table is empty.
Query:
select *, SUM(offers.price * announcement_product.amount) AS total, announcements.user_id AS creator_ann, announcements.id AS ann_id,
announcements.delivery AS deliveryAnn, announcements.payment AS
paymentAnn, SUM(announcement_product.amount) AS amount,
announcement_product.name as name_product
from `offers`
inner join `announcements` on `announcements`.`id` = `offers`.`announcement_id`
inner join `announcement_product` on `offers`.`announcement_product_id` = `announcement_product`.`id`
inner join `countries` on `countries`.`id` = `announcements`.`country`
where `offers`.`user_id` = 1 and `offers`.`status` = 1 and `offers`.`deleted_at` is null
You're using the aggregate function SUM(), but you don't have any GROUP BY clause.
When you do that you are instructing MySQL to add up all the row values in the column you mention in SUM(). It will do that even if there are no rows to add up.
For best results you should study up on the GROUP BY function and how to use it with SUM(). It's hard to guess what you want from your query.
I'm not sure, but I don't think
select *, ..
when there's multiple tables in the query is valid.
Try
select offers.*,..
This how Your select structure should be :
Select
Id,
Sku,
Sum(Onhand),
Sum(price)
From mytable
Where mytable Onhand > 0
Group by
Id,Sku
If you are going to use aggregate function such as Max,Sum,Min,....
you need to use group by for other table fields that your using in the select part.

Concatenate Sql column

SELECT DISTINCT a.assessement_group_id,
b.title as dataa
FROM assessment_group a
JOIN assessment_category b
WHERE a.assessement_group_id = b.group_id
I am using the join to display the data.the result are shown below
100 Partner Business Profile
99 Partner Activation
99 ajay test
100 ajaytest123
But i want this type of answer
100 Partner Business Profile,ajaytest123
99 Partner Activation,ajay test
You can use GROUP_CONCAT(DISTINCT ...) along with GROUP BY to get the output you want:
SELECT a.assessement_group_id,
GROUP_CONCAT(DISTINCT b.title)
FROM assessment_group a
INNER JOIN assessment_category b
ON a.assessement_group_id = b.group_id
GROUP BY a.assessement_group_id
SQLFiddle
By the way, I replaced your old-style implicit join syntax with an explicit INNER JOIN. It is generally considered bad practice now to put join conditions into the WHERE clause.
Try something as follows, hope this helps
select id, group_concat(`dataa` separator ',') as `dataa`
from
(
SELECT distinct a.assessement_group_id id, b.title as dataa
from assessment_group a JOIN assessment_category b
WHERE a.assessement_group_id=b.group_id
) tbl
group by id;
See the MySql GROUP_CONCAT() as part of a grouped query.
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html
You would add a GROUP_BY assessement_group_id to the end of the query, for example.
In mySql you can use the GROUP_CONCAT function, see here more details: http://dev.mysql.com/doc/refman/5.6/en/group-by-functions.html#function_group-concat.
In your initial query you need to add GROUP_CONCAT(b.title) in select clause and also a group by after assessement_group_id.
This one will help you
SELECT A.ASSESSEMENT_GROUP_ID, GROUP_CONCAT(B.TITLE SEPARATOR ' , ') AS DATAA FROM ASSESSMENT_GROUP A, ASSESSMENT_CATEGORY B WHERE A.ASSESSEMENT_GROUP_ID=B.GROUP_ID GROUP BY A.ASSESSEMENT_GROUP_ID;

MySQL query - unknown column in where clause- column value might not yet be determined when the WHERE clause is executed

SELECT area_id,
area_name,
(select count(*) from applications
where claims_status=1 and
center_name=c.area_id) as cont
FROM apparea c where cont<>0
I am trying to get fields and relevant count from anothere table, but the above query is not working. The query is involved two different tables(apparea, applications). The above query has error and I am looking for the alternate way to achieve this.
The alias for your column cont is not available in the WHERE clause. You will want to use something similar to this:
SELECT area_id,
area_name,
cont
FROM
(
SELECT area_id,
area_name,
(select count(*)
from applications
where claims_status=1
and center_name=c.area_id) as cont
FROM apparea c
) c
where cont<>0
This can also be written using a LEFT JOIN:
select c.area_id,
c.area_name,
a.cont
from apparea c
left join
(
select count(*) cont,
center_name
from applications
where claims_status=1
group by center_name
) a
on c.area_id = a.center_name
Try this query
SELECT
c.area_id,
c.area_name,
cnt
FROM
apparea c,
(select
center_name,
count(*) AS cnt
from
applications
where
claims_status=1
GROUP BY
center_name
HAVING
count(*) > 0) cont
where
c.area_id = cont.center_name;
Got the count for each center_name and then joined table to get count for each area
Use HAVING rather than where.
As it is problem with aliases.
It is not permissible to refer to a column alias in a WHERE clause, because the column
value might not yet be determined when the WHERE clause is executed.
See Section C.5.5.4, “Problems with Column Aliases”.
http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html
From: http://dev.mysql.com/doc/refman/5.0/en/select.html