i wonder if someone could help me out with this problem.
I'd like to update the column "result" in TABLE1 SET "1" when all to the ID(TABLE1) belonging tab1ID-values have in column result the value 1.
The ID in table1 are in relationship with tab1ID in table2. Hope this will make it clear:
Table1:
id | result |
1 | null |
2 | null |
3 | null |
Table2:
id | tab1ID | result |
1 | 1 | 1
2 | 1 | 0
3 | 1 | 1
4 | 2 | 1
5 | 2 | 1
6 | 2 | 1
7 | 3 | 0
8 | 3 | 1
9 | 3 | 1
The UPDATE-Satement should now UPDATE TABLE1 like this:
Table1:
id | result |
1 | 0 |
2 | 1 |
3 | 0 |
result at ID2 is 1 now, because all the belonging tab1ID (2) rows in table2 have the result-value 1
How can i do this with one update-statement?
This query assumes that the values for Table2.Result are only 1 and 0.
UPDATE table1 a
INNER JOIN
(
SELECT tab1ID, COUNT(*) = SUM(result) result
FROM table2
GROUP BY tab1ID
) b ON a.ID = b.tab1ID
SET a.result = b.result
SQLFiddle Demo
Related
I need to count shutouts for goalies. I have two tables ("players" and "gamestats"). I have a problem getting the values when goalie has no "0" / zero values in "goalsagainst" column when the goalie is "dressed" (has games).
So, I need to count all the zero values from column "goalsagainst" when "dressed" column has a value 1 as a "shutout" column. And if values from column "goalsagains" are more than 0 "shutout" colmn values should be 0;
I have tried the other solutions from similar topics, but I always have the same outcome where only the zero values are counted and other values are not shown.
My structure:
players
|p_id|pos|
--------
| 1 | G |
--------
| 2 | D |
--------
| 3 | O |
--------
| 4 | G |
stats
|g_id|p_id|goalsagainst|dressed|
--------------------------------
| 1 | 1 | 2 | 1 |
--------------------------------
| 1 | 4 | 0 | 0 |
--------------------------------
| 1 | 3 | NULL | 1 |
--------------------------------
| 1 | 2 | NULL | 1 |
--------------------------------
| 2 | 1 | 0 | 0 |
--------------------------------
| 2 | 4 | 0 | 1 |
--------------------------------
| 2 | 3 | NULL | 1 |
--------------------------------
| 2 | 2 | NULL | 1 |
SELECT
stats.id,
COUNT(stats.goalsagainst) AS shutouts
FROM `stats`
RIGHT JOIN players
ON stats.id = players.id
WHERE goalsagainst = 0
AND players.pos = 'G'
AND stats.dressed = 1
GROUP BY stats.id;
my result is:
p_id|shutouts
-------------
4 | 1
when it should be:
p_id|shutouts
-------------
1 | 0
-------------
4 | 1
Your problem is that your conditions on the stats table in your WHERE clause effectively turn the RIGHT JOIN into an INNER JOIN. To work around this, move the conditions to the ON clause. Secondly, you need to use players.p_id in the SELECT and GROUP BY as stats.p_id may be NULL:
SELECT players.p_id,
COUNT(stats.goalsagainst) AS shutouts
FROM `stats`
RIGHT JOIN players ON stats.p_id = players.p_id AND stats.dressed = 1 AND stats.goalsagainst = 0
WHERE players.pos = 'G'
GROUP BY players.p_id;
Output:
p_id shutouts
1 0
4 1
Demo on dbfiddle
On table1
+-------+-------+
| unid1 | unid2 |
+-------+-------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+-------+-------+
On table 2
+---------+-------+-------+------+
| tableid | unid1 | unid2 | type |
+---------+-------+-------+------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 1 |
| 3 | 3 | 3 | 1 |
| 4 | 3 | 0 | 2 |
| 5 | 3 | 0 | 2 |
| 6 | 4 | 4 | 3 |
| 7 | 5 | 5 | 3 |
+---------+-------+-------+------+
Expected result.
+-------+-------+------+
| unid1 | unid2 | type |
+-------+-------+------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 3 | 0 | 2 |
| 3 | 0 | 2 |
+-------+-------+------+
My SQL code
select t1.*, t2.* from table1 t1
left join table2 t2 on t1.unid1 = t2.unid1 and t1.unid2 = t2.unid2 and
t2.type in (1 , 2);
My SQL query does not give the result that i wanted, how can i get the result that i want.
Your expected output implies that you want to retain all rows in table2 whose unid1 values can be found in table1. If so, then we can just inner join these two tables on the unid1 column. This assumes that unid1 is unique in table1.
SELECT t2.unid1, t2.unid2, t2.type
FROM table2 t2
INNER JOIN table1 t1
ON t2.unid1 = t1.unid1;
If I understand you correctly, you want to output values wherein the rows from Table1 matches on Table2 in both columns unid1 and unid2 and that the type must be contained with your desired values.
SELECT b.unid1, b.unid2, b.type
FROM table1 a
INNER JOIN table2 b
ON a.unid1 = b.unid1
WHERE EXISTS
(
SELECT 1
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.unid1 = t2.unid1
AND t1.unid2 = t2.unid2
WHERE t2.type in (1,2)
AND a.unid1 = t1.unid1
)
Here's a DEMO.
I have the followin problem:
I want to update all rows where COUNT criteria is greater 1, when not I want to update all except 1. It also should update per other_ID.
Dummytable:
+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
| 1 | 1 | 1 | 0 |
| 2 | 1 | 1 | 0 |
| 3 | 1 | 1234 | 0 |
| 4 | 2 | 2 | 0 |
| 5 | 2 | 1 | 0 |
| 6 | 2 | 1 | 0 |
| 7 | 4 | 20 | 0 |
| 8 | 4 | 1 | 0 |
| 9 | 4 | 60 | 0 |
| 10 | 5 | 1 | 0 |
| 11 | 5 | 1 | 0 |
| 12 | 6 | 5 | 0 |
+----+----------+----------+-------------+
excpected result:
+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 1 | 1234 | 0 |
| 4 | 2 | 2 | 0 |
| 5 | 2 | 1 | 1 |
| 6 | 2 | 1 | 1 |
| 7 | 4 | 20 | 0 |
| 8 | 4 | 1 | 1 |
| 9 | 4 | 60 | 0 |
| 10 | 5 | 1 | 0 |
| 11 | 5 | 1 | 1 |
| 12 | 6 | 5 | 0 |
+----+----------+----------+-------------+
my idea:
UPDATE pics AS tu SET updatefield=1 WHERE criteria=1 AND (select count(*) as cnt2 from pics where criteria>1 group by other_id)>1;
Error: Table 'tu' is specified twice, both as a target for 'UPDATE' and as a separate source for data
Also I have problems to geht the right count:
SELECT other_id, count() as cnt FROM pics AS ts WHERE criteria=1 and (select count() as cnt2 from pics where criteria>1)>0 GROUP BY other_id;
i want to get cnt = 1 for other_id=5, but i get cnt=2
with
SELECT other_id, COUNT(*) AS cnt2
FROM pics
WHERE criteria>1
GROUP BY other_id;
I get all other_ids where i want to update the updatefield. But how can I connect it with the update? And how to get all except one for other_id=5
You can alias the sub query into another query, e.g.:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND other_id IN (
SELECT a.id FROM (
SELECT other_id AS id
FROM test
WHERE criteria > 1
GROUP BY other_id
HAVING COUNT(*) > 1
) a
);
Here's the SQL Fiddle.
Update
This will update the ids for records with criteria 0 and >1. Now, to update the records where there is more than one record with 1 criteria, you need to do something like this:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id IN (
SELECT a.id FROM (
SELECT MIN(id) AS id
FROM test
WHERE criteria = 1
GROUP BY other_id
HAVING COUNT(*) > 1
) a
);
Thanks to #Darshan Mehtas answer and help I finally found the solution to solve it as I want.
Here's the complete solution:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id not IN (
SELECT a.id FROM (
SELECT id
FROM test
WHERE criteria>1
) a
)
AND id not IN (
SELECT b.id FROM (
SELECT id
FROM test
GROUP BY other_id
HAVING COUNT(*) = 1
) b
)
AND id NOT IN (
SELECT c.id FROM (
SELECT id
FROM test
WHERE criteria=1 AND other_id NOT IN (
SELECT other_id FROM test WHERE Criteria>1
)
GROUP BY other_id, criteria
HAVING COUNT(criteria)>1
) c
);
Short description:
First Subquery (a) filters IDs where a criteria is greater 1
Second Subquery (b) filters IDs which have only on result
Third Subquery (c) filters IDs Where criteria is 1an don't have any higher criteria and keeps, thansk grouping, the first result.
Only bad thing could be to keep in the last subquery (c) the first (mostly oldest) result instead of newest.
€dit:
to keep the last result use this for subquery c instead:
AND id NOT IN (
SELECT c.id FROM (
SELECT id
FROM test t1
JOIN (SELECT other_id, max(id) maxid
FROM test
GROUP BY other_id) t2
ON t1.otheR_id=t2.other_id AND t1.id=t2.maxid
WHERE criteria=1 AND t1.other_id NOT IN (
SELECT other_id FROM test WHERE Criteria>1
)
GROUP BY t1.other_id, criteria
) c
);
I need help with query
let say i have 2 tables
tableA
------------------------------------------
id | name
1 | ABC
2 | DEF
3 | GHI
tableB
------------------------------------------
id | anotherID | Amount
1 | 1 | 1000
2 | 1 | 2000
3 | 1 | 3000
1 | 2 | 4000
2 | 2 | 5000
1 | 3 | 6000
i need this list
jointable
------------------------------------------
id | anotherID | Amount
1 | 1 | 1000
2 | 1 | 2000
3 | 1 | 3000
1 | 2 | 4000
2 | 2 | 5000
3 | 2 | 0
1 | 3 | 6000
2 | 3 | 0
3 | 3 | 0
i need every single id have value even its 0 for every single anotherID value..
example :
tableA have 3 id & distinct anotherID tableB have 3 records so i will need 3 * 3 = 9 records..
how to do this with query?? i can do with left join and union but i want to know if there some more effective way to do it.
SQLFiddle demo
select T1.ID,T2.AnotherId,
COALESCE(T3.Amount,0) as Amount
FROM TableA as T1
CROSS JOIN (Select distinct anotherID FROM TableB) as T2
LEFT JOIN TableB as T3 on (T1.id=T3.id)
AND
(T2.anotherID=T3.anotherID)
Order by T2.anotherId,T1.Id
I have the following table structure:
item_id | value |
==================
1 | 1 |
1 | 3 |
1 | 4 |
2 | 2 |
2 | 3 |
2 | 4 |
2 | 5 |
3 | 1 |
3 | 5 |
3 | 6 |
4 | 1 |
4 | 3 |
4 | 4 |
4 | 5 |
I have a query that returns those item_id whose value matches with 1, 3 and 4.
So here, the item_ids that should be returned are 1 and 4.
My query:
select item_id from table t
where exists (select item_id from table t1 where value = 1 and t1.item_id = t.item_id)
and exists (select item_id from table t1 where value = 2 and t1.item_id = t.item_id) group by item_id
This query is working fine. Here i am matching only 3 values. What if i want to match 50 such values from the table? (all the 50 values are stored in a php array) The query will be huge and also i want to do the same thing from two different tables in the same query. So, this will double the size of an already huge query. Please suggest me some other way around.
Edited::
table 2
--------
item_id | user_id |
==================
1 | 1 |
1 | 5 |
1 | 7 |
2 | 2 |
2 | 3 |
2 | 4 |
2 | 5 |
3 | 1 |
3 | 5 |
3 | 6 |
4 | 1 |
4 | 3 |
4 | 4 |
4 | 5 |
Now, i want item_id where values from table1 are 1,3,4 and user_id from table2 are 1,5,7
This problem is called Relational Division.
SELECT item_ID
FROM tableName
WHERE value IN (1,3,4)
GROUP BY item_ID
HAVING COUNT(*) = 3
if uniqueness was not enforce on column value for every item_id, DISTINCT is required to count only unique values,
SELECT item_ID
FROM tableName
WHERE value IN (1,3,4)
GROUP BY item_ID
HAVING COUNT(DISTINCT value) = 3
SQLFiddle Demo (both query included)
SQL of Relational Division