SQL counting different column values - mysql

I have a table called spider_status which has a status_code and a locationid. I am retrieving all cities from region_select_city which I joined in the code below. Now I am trying to count all the unique values in status_code in the table spider_status grouping by cities.
SELECT region_select_city.name as stad , COUNT(spider_status.id) as spider_aantal,
CASE WHEN spider_status.status_code = 1 THEN COUNT(spider_status.status_code) ELSE 0 END as LIVE
FROM
spider_status
JOIN
location
ON spider_status.location_id = location.id
JOIN
location_select_addressid
ON location.id = location_select_addressid.locationid
JOIN
location_address
ON location_select_addressid.addressid = location_address.id
JOIN
region_select_city
ON location_address.city_id = region_select_city.id
JOIN
spider_status_code
ON spider_status.status_code = spider_status_code.id
WHERE spider_status.current = 1
GROUP BY region_select_city.name

Hope the following code help you to solve the issue
SELECT count(DISTINCT s.status_code)
FROM spider_status AS s
JOIN location AS l
ON l.locationid = s.locationid
JOIN location_address AS loc_add
ON loca_add.locationid = loc_add.locationid
GROUP BY loc_add.city_id

At the end of the 2nd last line, should the AND be there?

Related

MySQL query returning only one row because of SUM function in it

I am trying to create an advertisement query where I want to fetch data of all the impressions per advertisement. One user can have multiple advertisements and impressions will be counted in a table on per day basis. So for each day I will have one different row. Here is how my query currently looks like.
SELECT
eac.id,
eac.gender,
eac.start_date,
eac.end_date,
eac.ad_image_path,
eac.ad_link,
eac.requestfrom,
eac.traffic,
eac.registertype,
eacr.region_id,
eac.active,
eac.impression,
eac.center_image_path,
eac.bottom_image_path,
eac.approved_by,
er.name as country_name,
eac.budget,
sum(budget/ (DATEDIFF(end_date,start_date)) *1000) as daily_imp,
eaa.impression_count,
eac.customer_id,
eaa.created_at
FROM
`enrich_advert_customer` eac
JOIN `enrich_advert_customer_regions` eacr ON eac.id = eacr.advert_customer_id
JOIN `enrich_regions` er ON er.id = eacr.region_id
LEFT JOIN `enrich_advert_abstract` eaa on eac.id = eaa.advert_customer_id
WHERE
eac.requestfrom ='web' AND
eac.registertype = 'paid' AND
eac.active = 1 AND
eac.approved_by = 1 AND
eac.gender ='male' AND
er.name = 'india' AND
eac.start_date <= '2018-11-5' AND
eac.end_date >= '2018-11-10'
But the problem here is if I am using
sum(budget/ (DATEDIFF(end_date,start_date)) *1000) as daily_imp
this then its returning only one row at a time.
If you can suggest where I am making a mistake that will be helpful.
Thank you!
You need to add group by clause and others column in there as you applyied aggregation
SELECT eac.id,eac.gender,eac.start_date,eac.end_date,eac.ad_image_path,eac.ad_link,eac.requestfrom,eac.traffic,eac.registertype,eacr.region_id,eac.active,eac.impression,eac.center_image_path,eac.bottom_image_path,eac.approved_by,er.name as country_name,eac.budget,sum(budget/ (DATEDIFF(end_date,start_date)) *1000) as daily_imp ,eaa.impression_count,eac.customer_id,eaa.created_at
FROM
`enrich_advert_customer` eac
JOIN
`enrich_advert_customer_regions` eacr
ON eac.id = eacr.advert_customer_id
JOIN
`enrich_regions` er
ON er.id = eacr.region_id
LEFT JOIN
`enrich_advert_abstract` eaa
on eac.id = eaa.advert_customer_id
WHERE eac.requestfrom ='web' AND
eac.registertype = 'paid' AND
eac.active = 1 AND
eac.approved_by = 1 AND
eac.gender ='male' AND
er.name = 'india' AND
eac.start_date <= '2018-11-5' AND
eac.end_date >= '2018-11-10'
group by eac.id,eac.gender,eac.start_date,eac.end_date,eac.ad_image_path,eac.ad_link,eac.requestfrom,eac.traffic,eac.registertype,eacr.region_id,eac.active,eac.impression,eac.center_image_path,eac.bottom_image_path,eac.approved_by,er.name,eac.budget, eaa.impression_count,eac.customer_id,eaa.created_at

SQL Query based on multiple where conditions

I've got a script where checked in employee's can see the stock inventory from each other, linked with their personal stock location, so each checked in employee can see which items are in stock at different locations. However, I want the main stock (id of 1, which is not attached to an employee) to be showed always, but I can't get the query right because one of the where statements is clearly not correct:
`stock_locations`.`location_id` = 1 AND
`workschedule`.`checkedIn` = 1 AND
Rememeber, the main stock is not linked to an employee, so it doesn't show up at the workschedule table. If I remove the first statement, It clearly shows up all the checked in employee's with their location, but that doesn't give me the main stock. If I remove the second statement, it only shows me the main stock.
How can I solve this issue within SQL? This is btw the full statement:
SELECT
`item_quantities`.`item_id`,
`stock_locations`.`location_name`,
`item_quantities`.`quantity`,
`people`.`first_name`
FROM
`item_quantities`
JOIN `stock_locations` ON `item_quantities`.`location_id` = `stock_locations`.`location_id`
JOIN `items` ON `item_quantities`.`item_id` = `items`.`item_id`
LEFT JOIN `workschedule` ON `workschedule`.`linked_storage` = `stock_locations`.`location_id`
LEFT JOIN `people` ON `workschedule`.`employee_id` = `people`.`person_id`
WHERE
`stock_locations`.`location_id` = 1 AND
`workschedule`.`checkedIn` = 0 AND
`items`.`unit_price` != 0 AND
`items`.`deleted` = 0 AND
`stock_locations`.`deleted` = 0 NULL
Thanks in advance!
Make it an OR statement inside of parens.
(`stock_locations`.`location_id` = 1 OR `workschedule`.`checkedIn` = 1) AND
This will return all records that match either the main stock or the employee.
You need to use the OR operator. Clearly both things can't happen at the same time, so you need to specify each set of acceptable conditions.
SELECT
`item_quantities`.`item_id`,
`stock_locations`.`location_name`,
`item_quantities`.`quantity`,
`people`.`first_name`
FROM
`item_quantities`
JOIN `stock_locations`
ON `item_quantities`.`location_id` = `stock_locations`.`location_id`
JOIN `items`
ON `item_quantities`.`item_id` = `items`.`item_id`
LEFT JOIN `workschedule`
ON `workschedule`.`linked_storage` = `stock_locations`.`location_id`
LEFT JOIN `people`
ON `workschedule`.`employee_id` = `people`.`person_id`
WHERE
`stock_locations`.`location_id` = 1
OR (
AND `workschedule`.`checkedIn` = 1
AND `items`.`unit_price` != 0
AND `items`.`deleted` = 0
AND `stock_locations`.`deleted` = 0
NULL
)
You have LEFT JOIN, but your WHERE clause turns them into inner joins. Fixing that will probably fix your problem:
SELECT . . .
FROM item_quantities iq JOIN
stock_locations sl
ON iq.`location_id` = sl.`location_id` JOIN
items i
ON iq.`item_id` = i.`item_id` LEFT JOIN
workschedule ws
ON ws.`linked_storage` = sl.`location_id` AND
ws.`checkedIn` = 0 LEFT JOIN
--------^
people p
ON ws.`employee_id` = p.`person_id`
WHERE sl.`location_id` = 1 AND
i.`unit_price` != 0 AND
i.`deleted` = 0 AND
sl.`deleted` = 0

SQL query to select from 3-4 tables

Please find below a link to the table-structure I have set up and to the query I am running.
Link to tables and query.
The present result is that only the firstnames, lastnames and "education_finished" are showing. But all the option_id's and their related lang_values still show "NULL".
The desired result:
Any suggestions how to solve?
Below is the query that you are using:
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_data d
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_name
LEFT JOIN phpbb_profile_fields_lang fl
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
The reason why you are getting null value is because of this condition:
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_name
You are trying to join on pf_education_finished (int) field of one table and field_name (int) field of another table. Also, there are no matching values (e.g. pf_education_finished contains numbers whereas field_nameis 'education finished').
If you want the query to return something then you need to join on field_id and phpbb_profile_fields needs to have some records with matching field id, e.g.:
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_data d
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_id
LEFT JOIN phpbb_profile_fields_lang fl
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
Here's the updated SQL Fiddle.
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_lang fl
inner JOIN phpbb_profile_fields f
ON f.field_id = fl.field_id
inner JOIN phpbb_profile_fields_data d
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
This is the optional query if you want to display data from 3-4 tables but in this query names are repeats as per the count of field_id present in phpbb_profile_fields_lang.
The exact solution you are looking is, when you have the same primary key in all the tables from which you are retrieving the data.
Thank you.

Referencing (Using an alias) the value from nested MySQL query in an outer conditional statement

I'm using a nested query to get the value I need from a table that I then need to use in a conditional statement, however, every time I try this I keep on getting an error saying unknown column (format) in the field list
SELECT
(SELECT format FROM competition_stages WHERE comp_id = "5" AND rid = "24") AS format,
a.tie_id, b.name AS team_a, b.team_id AS team_a_id, c.name AS team_b, c.team_id AS team_b_id, SUM(e.bonus) AS team_a_bonus, SUM(f.bonus) AS team_b_bonus,
SUM(CASE
WHEN (a.team_a = e.team_id AND format = "0") THEN e.score
END) as team_a_agg,
SUM(CASE
WHEN (a.team_b = f.team_id AND format = "0") THEN f.score
END) as team_b_agg
FROM competition_tie a
INNER JOIN teams b ON (a.team_a = b.team_id)
INNER JOIN teams c ON (a.team_b = c.team_id)
LEFT JOIN fixtures d ON (a.tie_id = d.tie_id)
LEFT JOIN fixture_scores e ON (d.fx_id = e.fx_id AND a.team_a = e.team_id)
LEFT JOIN fixture_scores f ON (d.fx_id = f.fx_id AND a.team_b = f.team_id)
WHERE a.comp_id = "5" AND a.rid = "24" AND a.season_id = "5"
GROUP BY a.tie_id
ORDER BY a.tie_id ASC
I can get the value of the format column in my results when I go through them but it just seems I can't use it within my query to use in.
Thanks for your help!
Instead of using a subquery, simply join the competition_stages table to your query so that you can reference the format column directly. Assuming there is no appearant relation between the competition_stages table and the other tables in the query (at least not from the information on hand), you can just join the table using the two conditions you specified if these conditions would only yield 1 result in the competition_stages table. Something like this:
SELECT cs.format, a.tie_id, ....
FROM competition_tie a ...
INNER JOIN competition_stages cs ON cs.comp_id = "5" AND cs.rid = "24"

Issues with a MySQL JOIN statement

i have 5 tables called personal,dailypay,bonuses,iou and loans am trying to write a query that will generate payroll from this table's...my code is
select personal.name as NAME,
(sum(dailypay.pay) + bonuses) - (iou.amount + loans.monthly_due)) as SALARY
from personal
join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid
left join iou on personal.eid = iou.eid
left join where dailypay.date = 'specified_date'
and bonuses.date_approved = 'specified_date'
and iou.date_approved = 'specified_date'
and loans.date = month(now()
It returns the name and null salary values for staffs that does have records for either bonuses,iou and loans. But i want to sum their dailypay, deduct/add deductions or additions return the values, in the event of no record it should proceed with the summation without any deduction or subtraction.
You missed something when pasting the code, as there is no join for the loans table. Also, you are using the table bonuses as a value, you need a field name also. I added some code for the join and for the field, but used ??? for names that are unknown to me.
When you add or subtract a null value to something else, the result is null, that's why you get null as result when any of the values from the left-joined tables are missing. You can use ifnull(..., 0) to turn a null value into zero.
You need a group by clause, otherwise it would sum up the salary for all persons.
If I get you right, you have several records in the dailypay table for each user, but only one record per user in the other tables? In that case you have the problem that you will be joining the other tables against each row in the dailypay, so if you have 20 payment records for a user, it will count the bonus 20 times. You can use an aggregate like max to get the value only once.
You have put conditions for the left.joined tables in the where clause, but this will turn the joins into inner joins. You should have those conditions in each join clause.
select
personal.name as NAME,
(sum(dailypay.pay) + ifnull(max(bonuses.???), 0)) - (ifnull(max(iou.amount), 0) + ifnull(max(loans.monthly_due), 0)) as SALARY
from
personal
inner join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid and bonuses.date_approved = 'specified_date'
left join iou on personal.eid = iou.eid and iou.date_approved = 'specified_date'
left join loans on personal.??? = loans.??? and loans.date = month(now())
where
dailypay.date = 'specified_date'
group by
personal.name
There seems to be an extranous left join before the where and a missing closing bracket ) in month(now()
so it should look like:
select personal.name as NAME,
(sum(dailypay.pay) + bonuses) - (iou.amount + loans.monthly_due)) as SALARY
from personal
join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid
left join iou on personal.eid = iou.eid
where dailypay.date = 'specified_date'
and bonuses.date_approved = 'specified_date'
and iou.date_approved = 'specified_date'
and loans.date = month(now())