i have table like that in mysql:
from value to
1 45 2
3 20 4
2 45 1
4 20 3
I want to check values 1 to 2 and 2 to 1 has the same values .
can you give me some example not exact query?
Thanks for help.
You can do this with exists. This will return all the instances where the values are not the same:
select t.*
from table t
where not exists (select 1
from table t2
where t2.from = t.to and
t2.to = t.from and
t2.value = t.value
);
One way is to group by the value. Then you can count if the from and to columns have the right values. If the count is greater than zero for both conditions then you have met your requirement.
Hover over to see the query
select value
from your_table
group by value
having sum(from = 1 and to = 2) = 1
and sum(from = 2 and to = 1) = 1
Something like this will return a row where at least one corresponding inverse row does not have a "matching" value:
SELECT a.from, a.to, a.value, b.value
FROM mytable a
JOIN mytable b
ON b.from = a.to
AND b.to = a.from
WHERE a.from < a.to
AND NOT a.value <=> b.value
(NOTE: this query doesn't identify rows that do not have an inverse row, it only identifies rows where an inverse row exists in the table, but that inverse row has a different value.)
Related
In my database, I have a table with those values :
column_a,column_b
1,2
3,4
2,1
4,3
3,1
5,6
1,4
1,3
I'm able to know how many times there's a match between a specific value, and any other value. Take value "1" :
SELECT COUNT(*) FROM (SELECT * FROM `table` WHERE `column_a` = 1) as T1
JOIN (SELECT * FROM `table` WHERE `column_b` = 1) as T2
WHERE T1.`column_b` = T2.`column_a`
Resultat will be 2, because we have 1,2, 2,1, 1,3 and 3,1 -> 1 matches with 2 and 3.
Now, I want to know the total number of matches. Here, it will be 3 (because there's 3,4 and 4,3).
Does anyone have and idea?
Thank you
One way to solve this is to count all the cases where a matching pair is found but restricting the matches such that only the pair where column_ais greater than column_b is selected to avoid duplication:
SELECT COUNT(*)
FROM `table` t1
WHERE EXISTS (
SELECT *
FROM `table` t2
WHERE t2.column_b = t1.column_a AND t2.column_a = t1.column_b
AND t2.column_a < t1.column_a
)
Output:
3
Demo on SQLFiddle
You can also use least() & greatest() function :
SELECT COUNT(*)
FROM (SELECT COUNT(*)
FROM `table` t1
GROUP BY LEAST(column_a, column_B), GREATEST(column_a, column_B)
HAVING COUNT(*) > 1
) t;
Here is a demo.
Here is one method:
select count(distinct case when a = 1 then b else a end)
from t
where 1 in (a, b);
Here is a db<>fiddle.
I have a table and I am trying to get the sum of Col A to 2 decimal places of all rows (there is an id column ID) that satisfies the following:
1) There is another row with a matching Col B
2) It has an unique pair of the values in Col C and Col D
Try this:
SELECT ROUND(SUM(ColA), 2) AS ColA_Sum
FROM datatable t
WHERE EXISTS (
SELECT 1
FROM datatable t2
WHERE t2.ID <> t.ID -- Another row must have different id
AND t2.ColB = t.ColB -- Matching Column B
)
AND EXISTS (
SELECT 1
FROM datatable t3
WHERE t3.ColC = t.ColC -- Same Column C
AND t3.ColD = t.ColD -- Same Column D
HAVING COUNT(*) = 1 -- Only 1 row with such values
)
I think it might be as simple as:
SELECT ROUND(SUM(t.cola), 2) AS cola_sum
FROM t
WHERE cola = colb
AND NOT EXISTS
(SELECT 1
FROM t t2
WHERE t2.colc = t.colc
AND t2.cold = t.cold
GROUP BY colc, cold
HAVING COUNT(*) > 1)
Check out the test here: http://rextester.com/BSVW57900
I am trying to write a query that will take two different values in column b and then compare it with column c to determine if the two values in column b share the same value in Column C. However i also need column A in the output as well.
For example
Column A Column B Column C
Test 1 x 12345
Test 2 y 12345
Test 3` A 12344
Test 4 D 12342
Desired Output
Column A Column B Column C
Test 1 x 12345
Test 2 y 12345
Any help would be great
I'm not sure if the values in ColumnB are significant. This query finds values of ColumnC that are repeated and then returns those rows:
select * from T where ColumnC in (
select ColumnC from T
group by ColumnC
having count(*) > 1 /* or maybe count(distinct ColumnB) > 1 */
)
try this
SELECT a.* FROM table a join table b on a.c=b.c and a.b<>b.b
The query doesn't take into account rows that have same values in c and b column.
You can add DISTINCT in the select if needed.
You can perform a JOIN like below. See a demo fiddle http://sqlfiddle.com/#!9/da525/4
select t.*
from tbl1 t join tbl1 s on t.`Column C` = s.`Column C`
and t.`Column B` <> s.`Column B`;
(OR) Using WHERE EXISTS
select t.*
from tbl1 t
where exists ( select 1 from tbl1
where `Column C` = t.`Column C`
and `Column B` <> t.`Column B`);
I have a MySQL table like this
id Name count
1 ABC 1
2 CDF 3
3 FGH 4
using simply select query I get the values as
1 ABC 1
2 CDF 3
3 FGH 4
How I can get the result like this
1 ABC 1
2 CDF 3
3 FGH 4
4 NULL 0
You can see Last row. When Records are finished an extra row in this format
last_id+1, Null ,0 should be added. You can see above. Even I have no such row in my original table. There may be N rows not fixed 3,4
The answer is very simple
select (select max(id) from mytable)+1 as id, NULL as Name, 0 as count union all select id,Name,count from mytable;
This looks a little messy but it should work.
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM
(
SELECT 1 as ID
UNION
SELECT 2 as ID
UNION
SELECT 3 as ID
UNION
SELECT 4 as ID
) a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID IN (1,2,3,4)
UPDATE 1
You could simply generate a table that have 1 column preferably with name (ID) that has records maybe up 10,000 or more. Then you could simply join it with your table that has the original record. For Example, assuming that you have a table named DummyRecord with 1 column and has 10,000 rows on it
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM DummyRecord a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID >= 1 AND
a.ID <= 4
that's it. Or if you want to have from 10 to 100, then you could use this condition
...
WHERE a.ID >= 10 AND
a.ID <= 100
To clarify this is how one can append an extra row to the result set
select * from table union select 123 as id,'abc' as name
results
id | name
------------
*** | ***
*** | ***
123 | abc
Simply use mysql ROLLUP.
SELECT * FROM your_table
GROUP BY Name WITH ROLLUP;
select
x.id,
t.name,
ifnull(t.count, 0) as count
from
(SELECT 1 AS id
-- Part of the query below, you will need to generate dynamically,
-- just as you would otherwise need to generate 'in (1,2,3,4)'
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
) x
LEFT JOIN YourTable t
ON t.id = x.id
If the id does not exist in the table you're selecting from, you'll need to LEFT JOIN against a list of every id you want returned - this way, it will return the null values for ones that don't exist and the true values for those that do.
I would suggest creating a numbers table that is a single-columned table filled with numbers:
CREATE TABLE `numbers` (
id int(11) unsigned NOT NULL
);
And then inserting a large amount of numbers, starting at 1 and going up to what you think the highest id you'll ever see plus a thousand or so. Maybe go from 1 to 1000000 to be on the safe side. Regardless, you just need to make sure it's more-than-high enough to cover any possible id you'll run into.
After that, your query can look like:
SELECT n.id, a.*
FROM
`numbers` n
LEFT JOIN table t
ON t.id = n.id
WHERE n.id IN (1,2,3,4);
This solution will allow for a dynamically growing list of ids without the need for a sub-query with a list of unions; though, the other solutions provided will equally work for a small known list too (and could also be dynamically generated).
Basically I have this query:
( SELECT * FROM tbl WHERE type = 'word1' )
UNION
( SELECT * FROM tbl WHERE type = 'word2' ) // Run this query if there are no results with type = 1
Basically I would like to run the second query only if the first hasn't any results. is it possible?
The FIRST "PreCheck" query does a count of how many records ARE of type = 1. After that, if the count is greater than 1, then return 1, otherwise return 2.
Now, THAT answer can be used in the join (which is always a single row via COUNT(*)) which will either have a 1 or 2 value. THAT value will be the second value is the EQUALITY conditon. So, if there IS an entry of 1, the result will be as if
WHERE t1.Type = 1
Thus never allowing any 2 in the test. HOWEVER, if NO entries are found, it will have a value of 2 and thus create a WHERE clause of
WHERE t1.type = 2
select t1.*
from
( select if( count(*) > 0, 1, 2 ) IncludeType
from tbl t2
where t2.type = 1 ) preCheck,
tbl t1
where
t1.type = preCheck.IncludeType
If there is an index on the "type" column, the first query should be almost instantaneous.
You could write
select * from tbl
where type = 1
union
select * from tbl
where type = 2
and not exists( select * from tble where type = 1 )
but this probably won't perform as well as just doing it in your program
It does the trick:
SELECT tbl.* FROM tbl JOIN (SELECT min(type) min_type FROM tbl WHERE type between 1 and 2 ) on min_type = type
First, it selects the lesser of these two types, if any exists, and then oins this one number table to your table. It is actually a simple filter. You can use WHERE instead of JOIN, if you want.
SELECT tbl.* FROM tbl WHERE (SELECT min(type) FROM tbl WHERE type between 1 and 2 ) = type