Some sort of join statement? - mysql

How do I put these two queries into a single query?
select count(id) as cnt from {$site_id}.proofingv2_packages where active='1'
select count(id) as cnt from {$site_id}.proofingv2_package_options where active='1' and parent={$row["id"]} order by sort
$row['id'] is the id field from the first query. I am trying to determine if there are any valid packages. A valid package must be active and have at least 1 active option. Running 2 queries for this doesn't seem right.
Can anyone help?

select count(id) as cnt from
{$site_id}.proofingv2_packages pp
INNER JOIN
{$site_id}.proofingv2_package_options
pt ON pp.active = pt.Active AND
pp.Active = 1
if the id is the PK or FK on the same on both tables use this query
select count(id) as cnt from
{$site_id}.proofingv2_packages pp
INNER JOIN {$site_id}.proofingv2_package_options pt ON pp.id= pt.id
AND pp.Active = 1

SELECT IF(count(*) > 0, 1, 0) AS isValid
FROM {$site_id}.proofingv2_packages pp
INNER JOIN {$site_id}.proofingv2_package_options ppo ON ppo.parent = pp.id
WHERE pp.active = '1'
AND ppo.active = '1'
This should return 1 if there are valid packages or 0 if not

Related

I want to apply an INNER JOIN and use WHERE condition using 3 tables

SELECT
*
FROM
retailer
WHERE
states = 1
AND newsletter.status = 1
AND (
company_id IN (
SELECT
id
FROM
retailer
WHERE
muli_ret_id = 0
)
)
ORDER BY
email
I'm not sure that your exact current query can be expressee using an inner join instead of the where clause. You might try:
SELECT DISTINCT r1.*
FROM retailer r1
INNER JOIN retailer r2
ON r1.company_id = r2.id
WHERE
r1.states = 1 AND
r1.newsletter.status = 1 AND
r2.muli_ret_id = 0
ORDER BY
r1.email;
I use select distinct to remove possible duplicates which could arise from the self join. But honestly, you current approach is fine, though I might use exists here:
SELECT r1.*
FROM retailer r1
WHERE
r1.states = 1 AND
r1.newsletter.status = 1 AND
EXISTS (SELECT 1 FROM retailer r2
WHERE r2.id = r1.company_id AND r2.muli_ret_id = 0)
ORDER BY
r1.email;

Return MYSQL results based on a sub query count?

Is there a way to adjust the following MYSQL query so that it only shows results where the video count is greater than 0? I have tried the following but it doesn't recognise
video_count
SELECT channels.*,
(SELECT COUNT(*) FROM videos WHERE videos.video_publisher_id = channels.channel_id) as `video_count`
FROM channels
WHERE channel_active = 1
AND video_count > 0
AND channel_thumbnail IS NOT NULL
ORDER BY channel_subscribers DESC
Move your subquery from the SELECT clause to the FROM clause. An inner join guarantees matches.
SELECT c.*, v.video_count
FROM channels c
JOIN
(
SELECT video_publisher_id, COUNT(*) AS video_count
FROM videos
GROUP BY video_publisher_id
) v ON v.video_publisher_id = c.channel_id
WHERE c.channel_active = 1
AND c.channel_thumbnail IS NOT NULL
ORDER BY c.channel_subscribers DESC;
Maybe this will help you.
SELECT channels.*,video_count.count
FROM channels
left join (SELECT channel_id,COUNT(*) count FROM videos) as `video_count` on video_count.video_publisher_id = channels.channel_id
WHERE channel_active = 1
AND video_count.count > 0
AND channel_thumbnail IS NOT NULL
ORDER BY channel_subscribers DESC
For filter by subquery result or aggregation function value you can use HAVING. You have error in WHERE clause because MySQL don't know about this column in WHERE
SELECT channels.*,
(SELECT COUNT(*) FROM videos WHERE videos.video_publisher_id = channels.channel_id) as `video_count`
FROM channels
WHERE channel_active = 1
AND channel_thumbnail IS NOT NULL
HAVING video_count > 0
ORDER BY channel_subscribers DESC
Or:
SELECT channels.*, COUNT(*) AS video_count
FROM channels
INNER JOIN videos
ON videos.video_publisher_id = channels.channel_id
WHERE channel_active = 1
AND channel_thumbnail IS NOT NULL
GROUP BY channels.channel_id
ORDER BY channel_subscribers DESC

Sql trouble with coalesce() not working propely

i have a query and i'm having trouble to change the name of the last row of columb name to 'TOTAL'. The result gives me the same name of the row above the last row.
Here's my query:
SELECT COALESCE(ticket_types.name,'TOTAL') AS name,
COUNT(1) AS quantity
FROM tr_logs
LEFT JOIN tickets ON tr_logs.value = tickets.id
LEFT JOIN ticket_types ON tickets.ticket_type_id = ticket_types.id
LEFT JOIN transactions ON tr_logs.transaction_id = transactions.id
LEFT JOIN tr_fields_data AS tfd_shipping ON tfd_shipping.transaction_id = transactions.id
WHERE type = 'ADDITEM'
AND transactions.event_id = '46'
AND DATE(tr_logs.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd_shipping.data IN ('0','570','571','771')
AND name IS NOT NULL
GROUP BY ticket_types.id WITH ROLLUP
The result looks like this:
name quantity
premium 56
outlaw 6
outlaw 62
Last row name from rollup is not null.... I need it to be TOTAL and not outlaw
Thanks
You haven't changed the name to TOTAL at all: you've changed the name of the column to name, and you've told it to replace any null values with TOTAL.
If you want to change the name of ticket_types.name to total, you just want
SELECT ticket_types.name AS total ...
(But it would be weird to rename something called name to total, so perhaps you need to clarify your requirements a little.)
This may or not be related to your observed problem, but the WHERE and GROUP BY clauses turn all the outer joins into inner joins. You should simplify the query to:
SELECT COALESCE(tt.name, 'TOTAL') AS name, COUNT(1) AS quantity
FROM tr_logs l JOIN
tickets
ON l.value = t.id JOIN
ticket_types tt
ON t.ticket_type_id = tt.id JOIN
transactions tr
ON l.transaction_id = tr.id JOIN
tr_fields_data fd
ON fd.transaction_id = tr.id
WHERE type = 'ADDITEM' AND
tr.event_id = '46' AND
DATE(l.created_date) BETWEEN '2017-03-26' AND '2017-05-24' AND
fd.data IN ('0', '570', '571', '771') AND
tt.name IS NOT NULL
GROUP BY tt.id WITH ROLLUP
Thanks to Gordon Linoff I have figure out my problem.
The name of the last row was never null beacause i GROUP BY with a different attribute.
Here's the solution.
SELECT COALESCE(tckn,'TOTAL') AS name, quantity FROM
(SELECT tt.name AS tckn, COUNT(1) AS quantity
FROM tr_logs AS l
LEFT JOIN tickets AS t ON l.value = t.id
LEFT JOIN ticket_types AS tt ON t.ticket_type_id = tt.id
LEFT JOIN transactions AS tr ON l.transaction_id = tr.id
LEFT JOIN tr_fields_data AS tfd ON tfd.transaction_id = tr.id
WHERE type = 'ADDITEM'
AND tr.event_id = '46'
AND DATE(l.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd.data IN ('0','570','571','771')
GROUP BY tckn WITH ROLLUP) as sum;

How to combine two sql counts from same joined table

another annoying student here!
Today I spend hours trying to combine (select) 2 already joined SQL outputs + the ID of the original table in a single table output. which ultimately resulted in this query:
SELECT * FROM(
SELECT fd1.User_idUser,avg(fd1.caloryIntake)
AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A,
(SELECT avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER
JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B;
Which translates into…
Now this is a false result, the second column gives an almost constant value for all user entries. I think this must be solved with some kind of EXTRA join but I literally ran out of ideas. Thanks in advance..!
Your JOIN is missing an ON clause to relate dUser_idUser.
But, the simplest way to write the query uses conditional aggregation:
SELECT fd1.User_idUser,
avg(case when dd1.weekend_ind = 'N' then fd1.caloryIntake end) as weekday_avg,
avg(case when dd1.weekend_ind = 'Y' then fd1.caloryIntake end) as weekend_avg
FROM fact_dailysnapshot fd1 INNER JOIN
dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser;
This is one query instead of two.
If I understand correctly, this is what you are looking for:
SELECT A.User_idUser, A.workdays, B.weekend
FROM (
SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A
JOIN
(SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B
ON A.User_idUser = B.User_idUser
Each query gives you all users by ID and their workdays or weekends. You need to JOIN the results of the two query on the user ID.

(My)SQL JOIN - get teams with exactly specified members

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