I want to generate a new column in my table that is true if a row exists with certain conditions.
name | col1 | col2 | flag
--------------------------
a 1 2 0
a 2 3 0
b 1 2 0
b 4 3 0
Lets say I want to set the flag to 1 for every name identifier if a row exists with that name and where col1=2 and col2 = 3. So this would result in:
name | col1 | col2 | flag
--------------------------
a 1 2 1
a 2 3 1
b 1 2 0
b 4 3 0
because for a a row with col1=2 and col2 = 3 exists, but for b, such a row doesn't exist.
In pseudocode I want something like this:
ALTER TABLE table_name
ADD flag TINYINT(1)
IF ##row with condition col1=value1 and col2=value2 exists#
GROUP BY name
How can I generate this column?
So you want just to get those values from db? or you want to add column? those are 2 different goals.
So if you need just to get those values you can:
http://sqlfiddle.com/#!9/65b4c2/1
SELECT t.*, t2.flag
FROM table_name t
LEFT JOIN (
SELECT name, MAX(IF(col1=2 AND col2=3,1,0)) flag
FROM table_name
GROUP BY name
) t2
ON t.name = t2.name
and if you really need to add new column then you go this way:
http://sqlfiddle.com/#!9/226fb3/1
ALTER TABLE table_name ADD COLUMN flag TINYINT;
UPDATE table_name t
LEFT JOIN (
SELECT name, MAX(IF(col1=2 AND col2=3,1,0)) flag
FROM table_name
GROUP BY name
) t2
ON t.name = t2.name
SET t.flag=t2.flag
Related
I have a table like this in MYSQL:
ID | NAME | VALUE |
----------------------------
1 | Bob | 1 |
2 | Bob | 2 |
3 | Jack | 5 |
4 | Jack | 8 |
5 | Jack | 10 |
and I'm trying to update the VALUE column to the highest value of rows with same NAME. So the result should be:
ID | NAME | VALUE |
----------------------------
1 | Bob | 2 |
2 | Bob | 2 |
3 | Jack | 10 |
4 | Jack | 10 |
5 | Jack | 10 |
I managed to get the max value like this:
SELECT MAX(Value) max FROM `table` GROUP BY Name having count(*) >1 AND MAX(Value) != MIN(Value)
But can't figure out how to put it in my update
Update table set Value = (SELECT MAX(Value) max FROM `table` GROUP BY Name having count(*) >1 AND MAX(Value) != MIN(Value))
Doesn't work. I'd appreciate any help.
This is easier than other answers are making it.
UPDATE MyTable AS t1 INNER JOIN MyTable AS t2 USING (Name)
SET Value = GREATEST(t1.Value, t2.Value);
You don't have to find the largest value. You just have to join each row to the set of rows with the same name, and set the Value to the greater Value of the two joined rows. This is a no-op on some rows, but it will apply to every row in turn.
http://sqlfiddle.com/#!9/f79a3/1
UPDATE t1
INNER JOIN (SELECT name, MAX(`value`) max_value
FROM t1 GROUP BY name) t2
ON t1.name = t2.name
SET t1.value = t2.max_value;
Create a temporary table consisting of ID NAME and MAX VALUE as follows:
CREATE TEMP TABLE TABLE1 AS
(SELECT NAME,MAX(Value) value FROM `table` GROUP BY Name having count(*) >1
AND MAX(Value) != MIN(Value)
);
Use this temporary table to do your update as follows:
UPDATE
Table_A
SET
Table_A.value = Table_B.value
FROM
`table` AS Table_A
INNER JOIN TABLE1 AS Table_B
ON Table_A.NAME = Table_B.NAME
Also this code is somewhat of an approximation as i am not familiar with mysql but i am familiar with sql.
Let me know if this doesn't help.
Simple left join would do the trick.
Try this out and let me know in case of any queries.
select a.id,a.name,b.value
from
table a
left join
(select name,max(value) as value from table group by name) b
on a.name=b.name;
You may use this query. The table is joined with a subquery (table t2) that contains the results you want to update your table with:
UPDATE `table` t1,
(SELECT Name, MAX(Value) maxv, MIN(Value) minv
FROM `table`
GROUP BY Name
HAVING COUNT(*)>1 AND maxv != minv) t2
SET t1.Value = t2.maxv
WHERE t1.Name = t2.Name;
If you want to know how will the values be updated, you can first run an equivalent SELECT query:
SELECT t1.*, t2.maxv
FROM `table` t1,
(SELECT Name, MAX(Value) maxv, MIN(Value) minv
FROM `table`
GROUP BY Name
HAVING COUNT(*)>1 AND maxv != minv) t2
WHERE t1.Name = t2.Name;
This query will display all the fields of table, followed by the new value maxv. You can check the current value and the new value, and if it looks fine, you may run the UPDATE query.
I need to count matches in a database.
Input:
id_to id_from
1 2
2 1
1 3
3 1
1 4
5 1
the 5th and 6th row has only one direction so doesn't count
Sample Output:
id_match
1
2
3
So, for 1 (implicit), 2 and 3 there is a reverse match but for 4 and 5 there aren't.
---- EDITED ----
Supposing the table name is "example" and I want to get all matches of id=1 then the SQL query will be:
SELECT count(*) FROM
(SELECT id_to FROM example WHERE id_from = 1) as t1,
(SELECT id_from FROM example WHERE id_to = 1) as t2
WHERE t1.id_to = t2.id_from
but maybe there is a better way to do it
You could try
SELECT DISTINCT id_from AS matched_id
FROM your_table AS data1
WHERE EXISTS (SELECT 1
FROM your_table AS data2
WHERE data1.id_from = data2.id_to
AND data1.id_to = data2.id_from)
I've created a demo here
I want to generate a new column in my table that is true if a row exists with certain conditions.
name | col1 | col2 | flag
--------------------------
a 1 2 0
a 2 3 0
b 1 2 0
b 4 3 0
Lets say I want to set the flag to 1 for every name identifier if a row exists with that name and where col1=2 and col2 = 3. So this would result in:
name | col1 | col2 | flag
--------------------------
a 1 2 1
a 2 3 1
b 1 2 0
b 4 3 0
because for a a row with col1=2 and col2 = 3 exists, but for b, such a row doesn't exist.
In pseudocode I want something like this:
ALTER TABLE table_name
ADD flag TINYINT(1)
IF ##row with condition col1=value1 and col2=value2 exists#
GROUP BY name
How can I generate this column?
So you want just to get those values from db? or you want to add column? those are 2 different goals.
So if you need just to get those values you can:
http://sqlfiddle.com/#!9/65b4c2/1
SELECT t.*, t2.flag
FROM table_name t
LEFT JOIN (
SELECT name, MAX(IF(col1=2 AND col2=3,1,0)) flag
FROM table_name
GROUP BY name
) t2
ON t.name = t2.name
and if you really need to add new column then you go this way:
http://sqlfiddle.com/#!9/226fb3/1
ALTER TABLE table_name ADD COLUMN flag TINYINT;
UPDATE table_name t
LEFT JOIN (
SELECT name, MAX(IF(col1=2 AND col2=3,1,0)) flag
FROM table_name
GROUP BY name
) t2
ON t.name = t2.name
SET t.flag=t2.flag
I have a table with two sets of integer values. Using MySQL I want to display all of the rows that correspond to unique entries in the second column. Basically I can have duplicate A values, but only unique B values. If there are duplicates for a value in B, remove all the results with that value. If I use DISTINCT I will still get one of those duplicates which I do not want. I also want to avoid using COUNT(). Here's an example:
|_A____B_|
| 1 2 |
| 1 3 |
| 2 2 |
| 2 4 |
| 1 4 |
| 5 5 |
Will have the following Results (1,3), (5,5). Any value in B that has a duplicate is removed.
Try this
SELECT * FROM TEMP WHERE B IN (
SELECT B FROM TEMP GROUP BY B Having COUNT(B)=1
);
I know you want to avoid using COUNT() but this is the quick solution.
working fiddle here - http://sqlfiddle.com/#!9/29d16/8
Tested and works! you need atleast count(*) to count the values
select * from test where B in (
select B from test group by B having count(*)<2
)
I don't know why you want to avoid using count(), because that's what would do the trick as follows:
Let's say your table is named "mytable"
SELECT t1.A, t1.B
FROM mytable t1
JOIN (
SELECT B, count(*) AS B_INSTANCES
FROM mytable
GROUP BY B
HAVING count(*) = 1
) t2 ON t2.B = t1.B
ORDER BY t1.A, t1.B
For example I have a table like given below .. I want to have separate columns on the basis of even/odd ids
-----------------------------------------------------
| ID | Names
-----------------------------------------------------
| 1 | Name1
-----------------------------------------------------
| 2 | Name2
-----------------------------------------------------
| 3 | Name3
-----------------------------------------------------
| 4 | Name4
-----------------------------------------------------
I want to design a query that could give me
-------------------
| Even | Odd |
-------------------
| Name2 | Name1 |
-------------------
| Name4 | Name3 |
-------------------
select
max(case id%2 when 1 then name end) as odd,
max(case id%2 when 0 then name end) as even
from your_table
group by floor((id+1)/2)
SQL Fiddle Demo
If you want to get odd or even, use next queries:
Select for odd records:
SELECT * FROM table WHERE ID % 2 = 1
Select, for even
SELECT * FROM table WHERE ID % 2 = 0
And if you want to decorate as two columns, try next solution:
SELECT
odd.name as Odd,
(SELECT name FROM table WHERE ID = odd.ID + 1 ) as Even
FROM
table as odd
WHERE
odd.ID % 2 = 1
If your Id column contain sequential number without any gap between number then :
SELECT t1.name as ODD,
t2.name as EVEN
FROM YourTable t1
left outer JOIN YourTable t2
ON t1.Id + 1 = t2.Id
where t1.Id%2 = 0
Note : if there are gaps between number then some of the ODD will be shown as NULL or it may skip that name if it has gap of more than 3.
Find the parity (property of even or odd) using modulo operator %.
...where id%2 equals 0;
This will give you even id in result.
The ones which are not equal to 0 are the odd id.
If you ID is sequential then
SELECT tb1.ODD, tb2.EVEN
FROM
(
SELECT Id, name ODD
FROM YourTable
where (`Id` % 2) = 1
) AS tb1
JOIN
(SELECT Id, name EVEN
FROM YourTable
WHERE (`Id` % 2) = 0
) AS tb2
ON (tb1.Id + 1 = tb2.Id)
WHERE tb1.ODD IS NOT NULL
ORDER BY tb1.Id
The above result set can be achieved by the following code -
SELECT Even, Odd
FROM (SELECT *, ROW_NUMBER()OVER(ORDER BY Even) AS ROW
FROM (SELECT CASE WHEN ID % 2 = 0 THEN Names ELSE NULL END AS 'Even'
FROM TableName)TAB1
WHERE Even IS NOT NULL)T1
FULL OUTER JOIN
(SELECT *, ROW_NUMBER()OVER(ORDER BY Odd) AS ROW FROM
(SELECT CASE WHEN ID % 2 = 1 THEN Names ELSE NULL END AS 'Odd'
FROM TableName) TAB2
WHERE Odd IS NOT NULL) T2
ON T1.ROW=T2.ROW