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
Related
Is there a way to select frist 3 rows and after that next 3 ( offset 3 ) and get the result as two arrays in a single query ? Something like:
(SELECT * FROM product WHERE 1 LIMIT 3) as first_array
(SELECT * FROM product WHERE 1 OFFSET 3 LIMIT 3) as second_array
Hope you understand me. Sorry about the explanation just dont't know how to explain in other way.
Lets say I only want the ids - output example:
id_1 id_2
1 4
2 5
3 6
What I have tried from the answers below the post is :
SELECT id as id_1 FROM `ct_product` WHERE 1 LIMIT 3
UNION ALL
SELECT id as id_2 FROM `ct_product` WHERE 1 LIMIT 3 OFFSET 3
The result is strange for me. It seems it returns only the second query results and they are not the 4th 5th and 6th row but the 5th 6th and 3th (in this order).
My table rows are:
id
1
2
3
4
5
6
7
You could do it with this query:
SELECT a1.id, a2.id
FROM (SELECT *, #rownum1:=#rownum1+1 AS rownum
FROM (SELECT id
FROM `ct_product`
LIMIT 3
) art
JOIN (SELECT #rownum1 := 0) r
) a1
JOIN (SELECT *, #rownum2:=#rownum2+1 AS rownum
FROM (SELECT id
FROM `ct_product`
LIMIT 3, 3
) art
JOIN (SELECT #rownum2 := 0) r
) a2
ON a1.rownum = a2.rownum
Output:
id id
1 4
2 5
3 6
This query works by creating two new tables with artificially generated row numbers (#rownum1 and #rownum2) from the first 3 and the second 3 rows in the original table. They are then JOINed on matching row numbers to get the desired result.
I have a table with 100 000 record, I want to select only the none repeated.
In another word, if the row are duplicated did not show it at all
ID Name Reslut
1 Adam 10
2 Mark 10
3 Mark 10
result
ID Name Reslut
1 Adam 10
any ideas ?
You could join a query on the table with a query that groups by the name only returns the unique names:
SELECT *
FROM mytable t
JOIN (SELECT name
FROM mytable
GROUP BY name
HAVING COUNT(*) = 1) s ON t.name = s.name
Using the same set :
ID Name Result
1 Adam 10
2 Mark 10
3 Mark 10
4 Mark 20
I'm guessing the final solution would be:
ID Name Result
1 Adam 10
4 Mark 20
Using the above query previously suggested I modified it to take the result into consideration:
SELECT t1.*
FROM myTable t1
JOIN
(
SELECT name, result
FROM myTable
GROUP BY name, result
HAVING COUNT(*) = 1
) t2
WHERE
t1.name=t2.name and
t1.result = t2.result;
i have data below for example
id product_id date
------ ---------- ----
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 2
7 3 1
result data query that i want "the last record of last date on each product_id"
to get it that result i use the query like below
SELECT a.* FROM test AS a
JOIN (SELECT MAX(id) AS id, product_id, MAX(DATE) AS DATE FROM test GROUP BY product_id) AS b
ON a.id = b.id AND a.product_id = b.product_id AND a.date = b.date
this time i got what i want as the result
id product_id date
------ ---------- --------
3 1 3
6 2 2
7 3 1
my problem when i add another data like below
id product_id date
------ ---------- --------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 2
7 3 1
8 1 3
9 1 2
and use the same query the result become like this
id product_id date
------ ---------- --------
6 2 2
7 3 1
where the the value '1' for product_id?
Try this
SELECT id, product_id, DATE FROM test sitem WHERE product_id IN (1,2,3) AND DATE = (SELECT DATE FROM test WHERE product_id =
sitem.product_id ORDER BY DATE DESC LIMIT 1) AND id =
(SELECT id FROM test WHERE product_id = sitem.product_id ORDER BY DATE DESC,
id DESC LIMIT 1) GROUP BY product_id
This is your subquery:
SELECT MAX(id) AS id, product_id, MAX(DATE) AS DATE
FROM test
GROUP BY product_id
It is independently calculating the maximum of id and date. But, there is no guarantee that these two values are in the same record. There are ways to fix the subquery, but they are rather complicated.
Instead, I would suggest using an alternative method to get the last record:
SELECT t.*
FROM test t
WHERE NOT EXISTS (SELECT 1
FROM test t2
WHERE t2.product_id = t.product_id AND
(t2.date > t.date OR
t2.date = t.date AND t2.id > t.id
);
This identifies the last record for each product as the one where no other record has a larger date. And, if two records have the same date, no other record has a larger id.
I have a table like this:
**lead_id** **form_id** **field_number** **value**
1 2 1 Richard
1 2 2 Garriot
2 2 1 Hellen
2 2 2 Garriot
3 2 1 Richard
3 2 2 Douglas
4 2 1 Tomas
4 2 2 Anderson
Where field_number = 1 is the name and field_number = 2 is the surname.
I would like to find entries that are equal by name OR surname and group them by lead_id, so the output could be like this:
1
2
3
Any thoughts on how this can be done?
This should work and be reasonably efficient (depending upon indexes):
select distinct lead_id
from tablename as t1
where exists (
select 1
from tablename as t2
where t1.field_number = t2.field_number
and t1.value = t2.value
and t1.lead_id <> t2.lead_id
)
Select leadid from (
Select DISTINCT leadid,value from tablename
Where fieldnumber=1
Group by leadid,value
Having count(value) >1
Union all
Select DISTINCT leadid,value from tablename
Where fieldnumber=2
Group by leadid,value
Having count(value) >1
) as temp
Surely there is a faster option
I am writing a query to grab the items that a specific user_id was the first to use. Here is some sample data -
item_id used_user_id date_used
1 1 2012-08-25
1 2 2012-08-26
1 3 2012-08-27
2 2 2012-08-27
3 1 2012-08-27
4 1 2012-08-21
4 3 2012-08-24
5 3 2012-08-23
query
select item_id as inner_item_id, ( select used_user_id
from test
where test.item_id = inner_item_id
order by date_used asc
limit 1 ) as first_to_use_it
from test
where used_user_id = 1
group by item_id
It returns the correct values
inner_item_id first_to_use_it
1 1
3 1
4 1
but the query is VERY slow on a giant table. Is there a certain index that I can use or a better query that I can write?
i can't get exactly what you mean because in your inner query you have sorted it by their used_user_id and and on your outer query you have filtered it also by their userid. Why not do this directly?
SELECT DISTINCT item_id AS inner_item_id,
used_user_id AS first_to_use_it
FROM test
WHERE used_user_id = 1
UPDATE 1
SELECT b.item_id,
b.used_user_id AS first_to_use_it
FROM
(
SELECT item_ID, MIN(date_used) minDate
FROM tableName
GROUP BY item_ID
) a
INNER JOIN tableName b
ON a.item_ID = b.item_ID AND
a.minDate = b.date_used
WHERE b.used_user_id = 1