Distinct value in two column - mysql

I have a query in mysql
select f1,f2,f3 from tableName;
I want to remove duplicate value in field f1 and f2 only,
I have tired as follows
select f1,f2,f3 from tableName
group by f1,f2;
But it will remove duplicates in f1 only.Any body can suggest me that how to remove duplicates in f1 and f2.
topic_id topic_name question_type
2237 Understanding Diversity Comprehensive
2237 Understanding Diversity Easy
2237 Understanding Diversity Application
44315 Bhasha, boli, lipi, or Vayakaran Intermediate
above is sample output having distinct value in question_type column only
here i want to remove duplicates from question_type and topic_id
expected output: having both topic_id and question_type distinct values
44315 Bhasha, boli, lipi, or Vayakaran Intermediate
2237 Understanding Diversity Comprehensive

You were almost there - you need to group the last column also. I can just guess the usage, so I added a sorted summary of covered question_types that might be handy for search or output:
SELECT
topic_id,
topic_name,
GROUP_CONCAT(DISTINCT question_type ORDER BY question_type) AS question_types
FROM tableName
GROUP BY topic_id, topic_name;
Output is:
'2237', 'Understanding Diversity', 'Application,Comprehensive,Easy'
'44315', 'Bhasha, boli, lipi, or Vayakaran', 'Itermediate'

My SQL really isn't that great, but I think you need to do what is called a nested SELECT statement.
Here is the manual reference.
http://dev.mysql.com/doc/refman/5.0/en/subqueries.html
That would make the SQL look something like this.
SELECT f1,f2,f3 FROM (SELECT f1,f2,f3 FROM tableName AS table1 GROUP BY f1) AS table2 GROUP BY f2;
Note, that I had to use the AS to create an alias, else "tableName" would conflict with the parent SQL select.

Related

MySQL - inner join on select query error 1052

Im trying to do a select query on a table along with an inner join afterwards to link data from the owner to the cats
the ownercat is using a foreign key on the id linking to the ownerinfo id
USE CATTERY;
SELECT
OWNERINFO.ID, OWNERINFO.First_Name, OWNERINFO.Last_Name, OWNERINFO.Phone, OWNERINFO.AddrL1, OWNERINFO.AddrL2, OWNERINFO.AddrL3, OWNERINFO.PostCode,
GROUP_CONCAT(DISTINCT OWNERCAT.Chip_ID)
FROM OWNERINFO
INNER JOIN OWNERCAT ON OWNERINFO.ID = OWNERCAT.ID
WHERE ID = 1;
I get returned the following error:
Error Code: 1052. Column 'ID' in where clause is ambiguous 0.0014 sec
removing the concat distinct statement still produces the same error, im not sure how to get around this issue
You need to define from which table the ID on WHERE-clause come from (you can use aliases). Secondly, as you are using GROUP_CONCAT, you should have GROUP BY in the query:
SELECT
oi.ID,
oi.First_Name,
oi.Last_Name,
oi.Phone,
oi.AddrL1,
oi.AddrL2,
oi.AddrL3,
oi.PostCode,
GROUP_CONCAT(DISTINCT oc.Chip_ID)
FROM OWNERINFO oi
INNER JOIN OWNERCAT oc ON oc.ID=oi.ID
WHERE oi.ID = 1
GROUP BY oi.ID
The problem is in the WHERE clause: ID is ambiguous, because that column is available in both tables.
You may think that, since you are joining the tables on ID, the database is able to tell that it has the same value, but that's not actually the case.
So just qualify the column in the WHERE clause, ie change this:
WHERE ID = 1
To either:
WHERE OWNERINFO.ID = 1
Or the equivalent:
WHERE OWNERCAT.ID = 1
Also please note that your query uses GROUP_CONCAT(), which is an aggregate function. This implies that you need a GROUP BY clause, that should list all non-aggregated column (ie all columns other than the one that is within GROUP_CONCAT()).

SQL - Nested query optimization

How can I optimize this query SQL?
CREATE TABLE table1 AS
SELECT * FROM temp
WHERE Birth_Place IN
(SELECT c.DES_COM
FROM tableCom AS c
WHERE c.COD_PROV IS NULL)
ORDER BY Cod, Birth_Date
I think that the problem is the IN clause
First of all it's not quite valid SQL, since you are selecting and sorting by columns that are not part of the group. What you want to do is called "select top N in group", check out Select first row in each GROUP BY group?
Your query doesn't make sense, because you have SELECT * with GROUP BY. Ignoring that, I would recommend writing the query as:
SELECT t.*
FROM temp t
WHERE EXISTS (SELECT 1
FROM tableCom c
WHERE t.Birth_Place = c.DES_COM AND
c.COD_PROV IS NULL
)
ORDER BY Cod, Birth_Date;
For this, I recommend an index on tableCom(desc_com, cod_prov). Your database might also be able to use an an index on temp(cod, birth_date, birthplace).

mySQL SELECT values from a TABLE where the TABLE name is based on a field value

Here's are very simplified versions of my tables.
[stock_adjust]
id
batch_table_name
batch_id
adjustment_reason
qty
[ingredient_batch]
id
batch_name
...lots of other columns
[product_batch]
id
batch_name
...lots of other columns
[packaging_batch
id
batch_name
...lots of other columns
stock_adjust contains the name of the correct batch table in the column batch_table_name which will either be "ingredient_batch", "product_batch" or "packaging_batch". I need to get the values from the correct batch table for each entry. The pseudo code for this would look something like the following:
SELECT sa.id, sa.adjustment_reason, sa.qty, batch.batch_name
FROM stock_adjust AS sa, [sa.batch_table_name] AS batch
WHERE sa.batch_id=batch.id
I have tried to simplify the description and tables as much as possible, hopefully I haven't simplified it too much and the above makes sense?
I have found several questions regarding similar issues to the following, but they either do not work correctly in this situation or I am not understanding the question correctly.
While I would recommend updating your database schema, here's an approach that could work for you given your scenario:
select sa.id, b.batch_name
from stock_adjust sa join (
select id, batch_name, 'ingredient_batch' table_name from ingredient_batch
union all
select id, batch_name, 'product_branch' table_name from product_branch
union all
select id, batch_name, 'packaging_batch' table_name from packaging_batch
) b on sa.batch_table_id = b.id and b.table_name = sa.batch_table_name
SQL Fiddle Demo
Maybee a dynamic query could be the solution. Check this answer SELECT * FROM #variable

Get a list of ids not present in a table

I have a list of ids, and I want to query a mysql table for ids not present in the table.
e.g.
list_of_ids = [1,2,4]
mysql table
id
1
3
5
6
..
Query should return [2,4] because those are the ids not in the table
since we cant view ur code i can only work on asumption
Try this anyway
SELECT id FROM list_of_ids
WHERE id NOT IN (SELECT id
FROM table)
I hope this helps
There is a horrible text-based hack:
SELECT
substr(result,2,length(result)-2) AS notmatched
FROM (
SELECT
#set:=replace(#set,concat(',',id,','),',') AS result
FROM (
select #set:=concat(',',
'1,2,4' -- your list here
,',')
) AS setinit,
tablename --Your tablename here
) AS innerview
ORDER BY LENGTH(result)
LIMIT 1;
If you represent your ids as a derived table, then you can do this directly in SQL:
select list.val
from (select 1 as val union all
select 2 union all
select 4
) list left outer join
t
on t.id = list.val
where t.id is null;
SQL doesn't really have a "list" type, so your question is ambiguous. If you mean a comma separated string, then a text hack might work. If you mean a table, then something like this might work. If you are constructing the SQL statement, I would advise you to go down this route, because it should be more efficient.

Why is this SQL query with subquery very slow?

I have this query:
select *
from transaction_batch
where id IN
(
select MAX(id) as id
from transaction_batch
where status_id IN (1,2)
group by status_id
);
The inner query runs very fast (less than 0.1 seconds) to get two ID's, one for status 1, one for status 2, then it selects based on primary key so it is indexed. The explain query says that it's searching 135k rows using where only, and I cannot for the life of me figure out why this is so slow.
The inner query is run seperatly for every row of your table over and over again.
As there is no reference to the outer query in the inner query, I suggest you split those two queries and just insert the results of the inner query in the WHERE clause.
select b.*
from transaction_batch b
inner join (
select max(id) as id
from transaction_batch
where status_id in (1, 2)
group by status_id
) bm on b.id = bm.id
my first post here.. sorry about the lack of formatting
I had a performance problem shown below:
90sec: WHERE [Column] LIKE (Select [Value] From [Table]) //Dynamic, slow
1sec: WHERE [Column] LIKE ('A','B','C') //Hardcoded, fast
1sec: WHERE #CSV like CONCAT('%',[Column],'%') //Solution, below
I had tried joining rather than subquerying.
I had also tried a hardcoded CTE.
I had lastly tried a temp table.
None of these standard options worked, and I was not willing to dosp_execute option.
The only solution that worked as:
DECLARE #CSV nvarchar(max) = Select STRING_AGG([Value],',') From [Table];
// This yields #CSV = 'A,B,C'
...
WHERE #CSV LIKE CONCAT('%',[Column],'%')