I have a responses table which has a dataset like this...
id|resp_id|value|is_cleaned
1 1 Yes 0
2 1 No 1
3 2 No 0
I would like to get all the responses where is_cleaned = 1, if it doesnt exist i would like to get the uncleaned result. What i have tried so far is, grouping by resp_id and using CASE statement. Not sure what exactly to put in the CASE statement though.
What i have so far is
SELECT * FROM cleanedresponse GROUP BY case when is_cleaned = 1 then resp_id else resp_id end
I would like the following results
resp_id|value|is_cleaned
1 No 1
2 No 0
You can do that by getting the max(is_cleaned) for each resp_id first
select resp_id, max(is_cleaned)
from cleanedresponse
group by resp_id
and then using it as a filter in the original table
select t1.resp_id, t1.value, t1.is_cleaned
from cleanedresponse t1
join (
select resp_id, max(is_cleaned) as max_cleaned
from cleanedresponse
group by resp_id
) t2
on t1.resp_id = t2.resp_id and
t1.is_cleaned = t2.max_cleaned
Related
Let's say we have 2 tables:
t1: with columns t1.doc_id, ...
looks like this:
t1.doc_id
1
2
3
4
t2: with columns t2.from_doc_id, t2.to_doc_id, t2.flag, ...
looks like this
from_doc_id
to_doc_id
flag
1
100
null
1
101
null
2
100
null
3
8
set
I wanted to get a query result like this:
t1.doc_id
refs
1
100, 101
2
100
3
Basically, wherever flag is null, i want to collect all to_doc_id and concatenate them in a string if flag is not null. Like the first two results in the example above.
If flag is not null (like third row in t2 example), I still want to get the 3 in the query result, but the refs field should not contain 8.
with a query:
SELECT t1.doc_id, group_concat(t2.to_doc_id) AS refs
FROM t1
LEFT OUTER JOIN t2 ON t2.from_doc_id = t1.id
WHERE t2.flag is null
... i miss the last line entirely, I only get the first two lines from the expected result.
So I guess, what I want, is to use WHERE t2.flag is null in group_concat, but to ignore the t2.flag when I get the t1.doc_id values.
You can use CASE inside GROUP_CONCAT
SELECT from_doc_id
,group_concat(CASE WHEN flag IS NULL THEN to_doc_id ELSE '' END) AS refs
FROM yourtable t1
JOIN yourtable2 t2 ON t1.doc_id = t2.from_doc_id
GROUP BY from_doc_id
Demo on db<>fiddle
I have a database as follows:
drinks_id ingredients_master_id
1 2
1 3
1 4
2 2
2 4
3 5
And I'm looking for a query where I can give it a list of ingredients_master_id such as 2,4 and it returns all of the drinks_id's that have exactly 2,4.
So in this case if I gave it ingredients_master_id 2,4,5 it would return drinks_id 2 and 3. And if I gave it 5 it would return drinks_id 3.
This is what I have so far but it's currently not displaying the correct info.
SELECT DISTINCT drinks.id
FROM drinks
WHERE drinks.id NOT IN
(
SELECT drinks.id
FROM ingredients
JOIN drinks ON ingredients.drinks_id = drinks.id
WHERE ingredients.ingredients_master_id NOT IN
(
2,3,4,5,6
)
);
You probably achieve the desired result using not exists as follows:
Select t.*
From your_table t
Where t.ingredients_master_id in (2,4,5)
And not exists
(Select 1 from your_table tt
Where tt.drinks_id = t.drinks_id
And tt.ingredients_master_id not in (2,4,5))
And I'm looking for a query where I can give it a list of ingredients_master_id such as 2,4 and it returns all of the drinks_id's that have exactly 2,4.
You can use group by and having:
select drinks_id
from t
group by drinks_id
having sum( ingredients_master_id in (2, 4) ) = 2;
The "= 2" is the size of the list, so you need to adjust that for different lists.
You can use as below:
select drink_id
from (
select drink_id,listagg(ingredients_master_id,',') within group( order by ingredients_master_id) val from <Table> group by drink_id)
where case
when instr('**2,4,5**',val)> 0
Then 'Y'
else 'N'
end = 'Y';
So I have this bit of mysql that I'm trying to work out. My goal is to insert the count of a grouping into the primary records to tell me how many of each status is within the related table for the record, so the result might look like this:
| id | name | count1 | count2 |
------------------------------------
| 1 | primary 1 | 5 | 3 |
| 1 | primary 2 | 2 | 7 |
select * from primaryTable
left join (
select
case
when relationTable.relation_status_id = 1
then count(*)
END as count1,
case
when relationTable.relation_status_id = 2
then count(*)
END as count2
) relationTable
on relationTable.primary_id = primaryTable.id
I tried using a subquery to do it, which worked, but requires a select per count, which I'm trying to avoid.
Adding a group by to the subquery resulted in an error that more than one row was being returned.
In the subquery, rather than aggregate COUNT()s inside CASE, you may more easily use SUM() to add up the result of a boolean comparison (0 or 1) to return a result resembling a count.
SELECT
primaryTable.*,
count1,
count2
FROM
primaryTable
JOIN (
SELECT
primary_id,
-- Sum the results of a boolean comparison
SUM(relation_status_id = 1) AS count1,
SUM(relation_status_id = 2) AS count2
FROM relationTable
-- Group in the subquery
GROUP BY primary_id
-- Join the subquery to the main table by primary_id
) counts ON primaryTable.primary_id = counts.primary_id
Note that because MySQL treats the booleans the same as 0 or 1, the comparison relation_status_id = 1 returns 1 or 0. The syntax above isn't supported in every RDBMS. To be more portable, you would need to use a CASE inside SUM() to explicitly return an integer 1 or 0.
SUM(CASE WHEN relation_status_id = 1 THEN 1 ELSE 0 END) AS count1,
SUM(CASE WHEN relation_status_id = 2 THEN 1 ELSE 0 END) AS count2
Your original attempt has some syntax problems. Chiefly, it has no FROM clause, which is causing MySQL to think it should be treated as a scalar value and then complain that it returns more than one row.
Sorry but I am not sure how to phrase this question or if it is possible but basically I am using a select statement in which I would like to display a column showing a count of when a criteria is met. For example
SELECT pageID, isHome, if(ishome = 1, 'count?', 0) AS Passed
FROM pages
I would like the passed column to show a running count kind of like this
PageID | ishome | passed
10031 | 0 | 0
10032 | 1 | 1
10033 | 1 | 2
10034 | 1 | 3
Thank you for any help
Try something like the following (untested)
select a.pageid, a.ishome, sum(b.ishome) passed
from
pages a join pages b
on a.pageid>= b.pageid
group by a.pageid, a.ishome
order by a.pageid
Not sure but I think this is want you want.
SELECT pageID, isHome,
case when(ishome = 1)
then count(*)
else 0
end Passed FROM Table1
group by pageID;
sqlfiddle
OR if you want the number of passed pages
SELECT isHome,
case when(ishome = 1)
then count(*)
else 0
end Passed FROM Table1
group by isHome;
sqlfiddle
SELECT pageID, isHome, count(*) AS Passed
FROM pages
where ishome = 1
GROUP BY PageID
DEMO
if you want show all result then use this
SELECT pageID, isHome, if(ishome = 1, count(*), 0) AS Passed
FROM pages
group by pageID,ishome ;
DEMO
Try something like this
SELECT pageID, isHome,
CASE isHome
WHEN 1 THEN SELECT COUNT(*) FROM pages p
WHERE p.isHome = 1 AND p.pageID <= pageID
ELSE 0
END as passed
FROM pages
ORDER BY pageID ASC
I have a table like so
+-------------------------------------+
| Description | ID | Show(1 or 0) |
+-------------------------------------+
I have a bunch of entries with the same description but one has an ID of null. I have to set show on all the rows without the null to 0 but only if they have more than rows 2 of the same description. I am new to SQL and I have around 50K rows so I would rather not do it manually.
USA 987655 1 - changed to 0
USA 987658 1 - changed to 0
USA 987617 1 - changed to 0
USA 989876 null - unchanged
CAN 767655 1 - not changed
CAN 957655 1 - not changed
have tried:
UPDATE test1 t1,
(
SELECT id, description, show AS mid
FROM test1 ti
GROUP BY
description
) tm
SET show = 0
WHERE t1.description= tm.description
AND id is not null;
Thank you in advance
You'll need a correlated sub-query. I haven't tested this, so use with caution. But something like this might be what you're after.
UPDATE
some_table st1
JOIN (
SELECT st2.description, count(*) c
FROM some_table st2
WHERE
st1.description = st1.description AND
st1.id IS NOT NULL AND
st2.id IS NOT NULL
GROUP by st2.description
HAVING c > 1
) AS tmp ON tmp.description = st1.description
SET st1.show = 0
This is not the final answer but could help you a lot ( i guess)
execute this query to see which ones should be updated from 0 to 1
SELECT description, COUNT(*) as "Same Description" FROM table
WHERE id <> null
GROUP BY description
HAVING COUNT(*) > 2